Skip to content

Commit 6d9f0f1

Browse files
committed
20 AlphaBeta first step implemented
1 parent 12d40dc commit 6d9f0f1

File tree

14 files changed

+597
-103
lines changed

14 files changed

+597
-103
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
See_c/*.*
1010
temp.go
1111
diverse/*.*
12+
gobit.bat

.vscode/launch.json

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,11 @@
55
"version": "0.2.0",
66
"configurations": [
77
{
8-
"name": "Launch",
8+
"name": "Launch Package",
99
"type": "go",
1010
"request": "launch",
1111
"mode": "debug",
12-
"remotePath": "",
13-
"port": 2345,
14-
"host": "127.0.0.1",
15-
"program": "${fileDirname}",
16-
"env": {},
17-
"args": [],
18-
"showLog": true
12+
"program": "${workspaceRoot}"
1913
}
2014
]
2115
}

.vscode/settings.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
"diverese": true,
1414
"pm.txt": true,
1515
"GoBit.exe~": true,
16-
".gitignore": true,
17-
"engine-interface.txt": true,
18-
"temp.go": true
16+
".gitignore": true
1917
},
2018
"cSpell.words": [
2119
"Pval",

_config.yml

Lines changed: 0 additions & 1 deletion
This file was deleted.

engine.go

Lines changed: 124 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,30 @@ package main
33
import (
44
"fmt"
55
"math"
6+
"time"
67
)
78

9+
const (
10+
maxDepth = 100
11+
maxPly = 100
12+
)
13+
14+
var cntNodes uint64
815

916
//TODO search limits: start clock and testing for movetime
1017
//TODO search limits: counting nodes and testing for limit.nodes
11-
//TODO search limits: depth and other limits
18+
//TODO search limits: limit.depth
19+
1220
//TODO search limits: time per game w/wo increments
1321
//TODO search limits: time per x moves and after x moves w/wo increments
1422
type searchLimits struct {
15-
depth int
16-
nodes uint64
17-
moveTime int // in milliseconds
18-
infinite bool
23+
depth int
24+
nodes uint64
25+
moveTime int // in milliseconds
26+
infinite bool
27+
startTime time.Time
28+
nextTime time.Time
29+
1930
//////////////// current //////////
2031
stop bool
2132
}
@@ -27,6 +38,7 @@ func (s *searchLimits) init() {
2738
s.nodes = math.MaxUint64
2839
s.moveTime = 99999999999
2940
s.infinite = false
41+
s.stop = false
3042
}
3143

3244
func (s *searchLimits) setStop(st bool) {
@@ -42,6 +54,38 @@ func (s *searchLimits) setInfinite(b bool) {
4254
s.infinite = b
4355
}
4456

57+
type pvList []move
58+
59+
func (pv *pvList) new() {
60+
*pv = make(pvList, 0, maxPly)
61+
}
62+
63+
func (pv *pvList) add(mv move) {
64+
*pv = append(*pv, mv)
65+
}
66+
67+
func (pv *pvList) clear() {
68+
*pv = (*pv)[:0]
69+
}
70+
71+
func (pv *pvList) addPV(pv2 *pvList) {
72+
*pv = append(*pv, *pv2...)
73+
}
74+
75+
func (pv *pvList) catenate(mv move, pv2 *pvList) {
76+
pv.clear()
77+
pv.add(mv)
78+
pv.addPV(pv2)
79+
}
80+
81+
func (pv *pvList) String() string {
82+
s := ""
83+
for _, mv := range *pv {
84+
s += mv.String() + " "
85+
}
86+
return s
87+
}
88+
4589
func engine() (toEngine chan bool, frEngine chan string) {
4690
fmt.Println("info string Hello from engine")
4791
frEngine = make(chan string)
@@ -52,32 +96,53 @@ func engine() (toEngine chan bool, frEngine chan string) {
5296
}
5397

5498
//TODO root: Iterative Depening
99+
55100
//TODO root: Aspiration search
56101
func root(toEngine chan bool, frEngine chan string) {
102+
var pv pvList
103+
var childPV pvList
104+
childPV.new()
57105
b := &board
58-
ml := moveList{}
106+
ml := make(moveList, 0, 60)
59107
for _ = range toEngine {
60-
tell("info string engine got go! X")
61-
ml = moveList{}
108+
limits.startTime, limits.nextTime = time.Now(), time.Now()
109+
alpha, beta := -minEval, maxEval
110+
bm, bs := noMove, noScore
111+
depth := limits.depth
112+
cntNodes = 0
113+
ml.clear()
62114
genAndSort(b, &ml)
63115

64-
for _, mv := range ml {
65-
b.move(mv)
66-
score := -search(b)
67-
b.unmove(mv)
68-
69-
mv.packEval(adjEval(b, score))
116+
for ix := range ml {
117+
mv := &ml[ix]
118+
childPV.clear()
119+
120+
b.move(*mv)
121+
tell("info currmove ", mv.String())
122+
score := -search(-beta, -alpha, depth-1, 1, &childPV, b)
123+
b.unmove(*mv)
124+
mv.packEval(signEval(b.stm, score))
125+
if score > bs {
126+
bs = score
127+
pv.clear()
128+
pv.catenate(*mv, &childPV)
129+
130+
bm = *mv
131+
alpha = score
132+
tell(fmt.Sprintf("info score cp %v depth %v nodes %v pv ", bs, depth, cntNodes), pv.String())
133+
}
70134
}
71135
ml.sort()
72-
tell("info score cp ", fmt.Sprintf("%v", ml[0].eval()), " depth 1 pv ", ml[0].String())
136+
tell(fmt.Sprintf("info score cp %v depth %v nodes %v pv ", bm.eval(), depth, cntNodes), pv.String())
73137
frEngine <- fmt.Sprintf("bestmove %v%v", sq2Fen[ml[0].fr()], sq2Fen[ml[0].to()])
74138
}
75139
}
76140

77141
//TODO search: the 'stop' command
78142
//TODO search: time handling basic movetime
79-
//TODO search: generate all moves and put captures first (temporary)
80143
//TODO search: alpha Beta
144+
145+
//TODO search: generate all moves and put captures first (temporary)
81146
//TODO search: qs
82147
//TODO search: killer moves
83148
//TODO search: hash table
@@ -90,27 +155,65 @@ func root(toEngine chan bool, frEngine chan string) {
90155
//TODO search: more complicated time handling schemes
91156
//TODO search: other reductions and extensions
92157

93-
func search(b *boardStruct) int {
158+
func search(alpha, beta, depth, ply int, pv *pvList, b *boardStruct) int {
159+
cntNodes++
160+
if depth <= 0 {
161+
return signEval(b.stm,evaluate(b))
162+
}
163+
pv.clear()
164+
ml := make(moveList, 0, 60)
165+
genAndSort(b, &ml)
166+
167+
bm, bs := noMove, noScore
168+
var childPV pvList
169+
for _, mv := range ml {
170+
childPV.clear()
171+
b.move(mv)
172+
score := -search(-beta, -alpha, depth-1, ply+1, &childPV, b)
173+
b.unmove(mv)
174+
if score > bs {
175+
bs = score
176+
pv.catenate(mv, &childPV)
177+
178+
if score >= beta { // beta cutoff
179+
return score
180+
}
181+
if score > alpha {
182+
bm = mv
183+
_ = bm
184+
alpha = score
185+
}
186+
}
187+
if time.Since(limits.nextTime) >= time.Duration(time.Second) {
188+
t1 := time.Since(limits.startTime)
189+
tell(fmt.Sprintf("info time %v nodes %v nps %v", int(t1.Seconds()*1000), cntNodes, cntNodes/uint64(t1.Seconds())))
190+
limits.nextTime = time.Now()
191+
}
94192

95-
return evaluate(b)
193+
if limits.stop {
194+
return alpha
195+
}
196+
}
197+
return bs
96198
}
97199

98200
func genAndSort(b *boardStruct, ml *moveList) {
201+
99202
b.genAllMoves(ml)
100203

101204
for ix, mv := range *ml {
102205
b.move(mv)
103206
v := evaluate(b)
104207
b.unmove(mv)
105-
v = adjEval(b, v)
208+
v = signEval(b.stm, v)
106209
(*ml)[ix].packEval(v)
107210
}
108211

109212
ml.sort()
110213
}
111214

112-
func adjEval(b *boardStruct, ev int) int {
113-
if b.stm == BLACK {
215+
func signEval(stm color, ev int) int {
216+
if stm == BLACK {
114217
return -ev
115218
}
116219
return ev

evaluate.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package main
2-
3-
var pieceVal = [12]int{100, -100, 325, -325, 350, -350, 500, -500, 950, -950, 10000, -10000}
2+
const (
3+
maxEval = +10000
4+
minEval = -maxEval
5+
mateEval= maxEval+1
6+
noScore = minEval-1
7+
)
8+
9+
var pieceVal = [16]int{100, -100, 325, -325, 350, -350, 500, -500, 950, -950, 10000, -10000,0,0,0,0}
410

511
var knightFile = [8]int{-4, -3, -2, +2, +2, 0, -2, -4}
612
var knightRank = [8]int{-15, 0, +5, +6, +7, +8, +2, -4}

magic.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ var mBishopTab [64]sMagic
1313
var mRookTab [64]sMagic
1414

1515
// all attacks from current square
16-
func (m *sMagic) atks(b *boardStruct) bitBoard {
17-
return m.toSqBB[int(((b.allBB()&m.innerBB)*bitBoard(m.magic))>>m.shift)]
16+
func (m *sMagic) atks(allBB bitBoard) bitBoard {
17+
return m.toSqBB[int(((allBB&m.innerBB)*bitBoard(m.magic))>>m.shift)]
1818
}
1919

2020
func initMagic() {

magic_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func Test_sMagic_atks(t *testing.T) {
2222
for _, tt := range tests {
2323
t.Run(tt.name, func(t *testing.T) {
2424
handlePosition("position " + tt.position)
25-
if got := tt.m.atks(&board); got != tt.want {
25+
if got := tt.m.atks(board.allBB()); got != tt.want {
2626
t.Errorf("sMagic.atks() = \n%v\nwant \n%v", got.Stringln(), tt.want.Stringln())
2727
}
2828
})

moves.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const (
2828
epShift = 24 //6+6+4+4+4
2929
castlShift = 30 //6+6+4+4+4+6
3030
evalShift = 64 - 16
31+
noMove = move(0)
3132
)
3233

3334
var pieceRules [nP][]int // not pawns
@@ -45,7 +46,7 @@ func (m move) StringFull() string {
4546
p := int2Fen(int(m.p12()))
4647
cp := int2Fen(int(m.cp())) + " "
4748
pr := int2Fen(int(m.pr()))
48-
return fmt.Sprintf("%v%v-%v%v%v", p, fr, cp[:1], to, pr)
49+
return trim(fmt.Sprintf("%v%v-%v%v%v", p, fr, cp[:1], to, pr))
4950
}
5051

5152
func (m *move) packMove(fr, to, p12, cp, pr, epSq int, castl castlings) {
@@ -54,6 +55,7 @@ func (m *move) packMove(fr, to, p12, cp, pr, epSq int, castl castlings) {
5455
(cp << cpShift) | (pr << prShift) | (epSq << epShift) | int(castl << castlShift) )
5556
}
5657
func (m *move) packEval(score int) {
58+
(*m) &= move(^evalMask) //clear eval
5759
(*m) |= move(score + 30000) << evalShift
5860
}
5961

@@ -85,6 +87,10 @@ func (m move) castl() castlings {
8587

8688
type moveList []move
8789

90+
func (ml *moveList) clear() {
91+
*ml = (*ml)[:0]
92+
}
93+
8894
func (ml *moveList) add(mv move) {
8995
*ml = append(*ml, mv)
9096
}

0 commit comments

Comments
 (0)