-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpvtable.go
87 lines (79 loc) · 1.93 KB
/
pvtable.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package main
import (
"errors"
"fmt"
"unsafe"
)
type PvEntry struct {
PosKey uint64
Move int
}
type PvTable struct {
PTable []*PvEntry
NumEntries int
}
func (pvt *PvTable) Clear() {
for i := 0; i < pvt.NumEntries; i++ {
pvEntry := new(PvEntry)
pvEntry.PosKey = 0
pvEntry.Move = NoMove
pvt.PTable = append(pvt.PTable, pvEntry)
}
}
func (pvt *PvTable) Init() {
var pvEntry PvEntry
pvt.NumEntries = PvSize/int(unsafe.Sizeof(pvEntry)) - 2
pvt.PTable = nil
pvt.Clear()
}
func GetPvLine(depth int, pos *Board) (int, error) {
if depth >= MaxDepth {
return 0, errors.New(fmt.Sprintf("Depth can't be more than %d", MaxDepth))
}
move, err := ProbePvTable(pos)
if err != nil {
return 0, err
}
count := 0
for move != NoMove && count < depth {
if count >= MaxDepth {
return 0, errors.New(fmt.Sprintf("Depth can't be more than %d", MaxDepth))
}
if MoveExists(pos, move) {
MakeMove(move, pos)
pos.PvArray[count] = move
count++
} else {
break
}
move, err = ProbePvTable(pos)
if err != nil {
return 0, err
}
}
for pos.Ply > 0 {
TakeMove(pos)
}
return count, nil
}
// StorePvMove stores the move in the PV table of the board
func StorePvMove(pos *Board, move int) error {
index := pos.PosKey % uint64(pos.PvTable.NumEntries)
if index < 0 || index > uint64(pos.PvTable.NumEntries-1) {
return errors.New("Index where PV move is to be stored is invalid")
}
pos.PvTable.PTable[index].PosKey = pos.PosKey
pos.PvTable.PTable[index].Move = move
return nil
}
// ProbePvTable searches for the most significant move on the board based on its pv
func ProbePvTable(pos *Board) (int, error) {
index := pos.PosKey % uint64(pos.PvTable.NumEntries)
if index < 0 || index > uint64(pos.PvTable.NumEntries-1) {
return NoMove, errors.New("Index where PV move is to be probed from is invalid")
}
if pos.PvTable.PTable[index].PosKey == pos.PosKey {
return pos.PvTable.PTable[index].Move, nil
}
return NoMove, nil
}