Skip to content

Commit 9f114a4

Browse files
committed
23 Transposition table implemented
1 parent 0f7b16b commit 9f114a4

File tree

11 files changed

+776
-286
lines changed

11 files changed

+776
-286
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ temp.go
1111
diverse/*.*
1212
gobit.bat
1313
temp_test.go
14+
temp.goo

.vscode/settings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"design.png": true,
55
"**/*.exe": true,
66
"**/*.png": true,
7-
"README.md": true,
87
"LICENSE": true,
98
"uci_example.txt": true,
109
"**/*.jpg": true,
@@ -13,7 +12,8 @@
1312
"pm.txt": true,
1413
"GoBit.exe~": true,
1514
"london.txt": true,
16-
"temp_test.go": true
15+
"engine-interface.txt": true,
16+
"README.md": true
1717
},
1818
"cSpell.words": [
1919
"Pval",

engine.go

Lines changed: 76 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type searchLimits struct {
2525
moveTime int // in milliseconds
2626
infinite bool
2727
startTime time.Time
28-
nextTime time.Time
28+
lastTime time.Time
2929

3030
//////////////// current //////////
3131
stop bool
@@ -89,62 +89,72 @@ func (pv *pvList) String() string {
8989
func engine() (toEngine chan bool, frEngine chan string) {
9090
frEngine = make(chan string)
9191
toEngine = make(chan bool)
92-
go rootx(toEngine, frEngine)
92+
go root(toEngine, frEngine)
9393

9494
return
9595
}
9696

9797
//TODO root: Aspiration search
9898
func root(toEngine chan bool, frEngine chan string) {
99-
var depth int
99+
var depth, alpha, beta int
100100
var pv pvList
101101
var childPV pvList
102+
var ml moveList
102103
childPV.new()
103104
pv.new()
105+
ml.new(60)
104106
b := &board
105-
ml := make(moveList, 0, 60)
106107
for _ = range toEngine {
107-
limits.startTime, limits.nextTime = time.Now(), time.Now()
108-
alpha, beta := minEval, maxEval
109-
108+
limits.startTime, limits.lastTime = time.Now(), time.Now()
110109
cntNodes = 0
110+
111111
killers.clear()
112112
ml.clear()
113113
pv.clear()
114-
genAndSort(b, &ml)
114+
115+
genAndSort(0, b, &ml)
115116
bm := ml[0]
116117
bs := noScore
117118
depth = limits.depth
118-
for depth = 1; depth <= limits.depth; depth++ {
119-
bs = noScore
120-
for ix := range ml {
121-
mv := &ml[ix]
119+
for depth = 1; depth <= limits.depth && !limits.stop; depth++ {
120+
ml.sort()
121+
bs = noScore // bm keeps the best from prev iteration in case of immediate stop before first is done in this iterastion
122+
alpha, beta = minEval, maxEval
123+
for ix, mv := range ml {
122124
childPV.clear()
123125

124-
b.move(*mv)
126+
b.move(mv)
125127
tell("info depth ", strconv.Itoa(depth), " currmove ", mv.String(), " currmovenumber ", strconv.Itoa(ix+1))
128+
126129
score := -search(-beta, -alpha, depth-1, 1, &childPV, b)
127-
b.unmove(*mv)
130+
b.unmove(mv)
128131
if limits.stop {
129132
break
130133
}
131-
mv.packEval(score)
134+
ml[ix].packEval(score)
132135
if score > bs {
133136
bs = score
134-
pv.catenate(*mv, &childPV)
137+
pv.catenate(mv, &childPV)
135138

136-
bm = *mv
139+
bm = ml[ix]
137140
alpha = score
138141

139142
t1 := time.Since(limits.startTime)
140143
tell(fmt.Sprintf("info score cp %v depth %v nodes %v time %v pv ", bm.eval(), depth, cntNodes, int(t1.Seconds()*1000)), pv.String())
141144
}
145+
142146
}
143147
ml.sort()
144148
}
145-
149+
//
150+
// time, nps, ebf
146151
t1 := time.Since(limits.startTime)
147-
tell(fmt.Sprintf("info score cp %v depth %v nodes %v time %v pv ", bm.eval(), depth-1, cntNodes, int(t1.Seconds()*1000)), pv.String())
152+
nps := float64(0)
153+
if t1.Seconds() != 0 {
154+
nps = float64(cntNodes) / t1.Seconds()
155+
}
156+
157+
tell(fmt.Sprintf("info score cp %v depth %v nodes %v time %v nps %v pv %v", bm.eval(), depth-1, cntNodes, int(t1.Seconds()*1000), uint(nps), pv.String()))
148158
frEngine <- fmt.Sprintf("bestmove %v%v", sq2Fen[bm.fr()], sq2Fen[bm.to()])
149159
}
150160
}
@@ -163,15 +173,22 @@ func root(toEngine chan bool, frEngine chan string) {
163173
func search(alpha, beta, depth, ply int, pv *pvList, b *boardStruct) int {
164174
cntNodes++
165175
if depth <= 0 {
166-
return signEval(b.stm, evaluate(b))
176+
//return signEval(b.stm, evaluate(b))
177+
return qs(beta, b)
167178
}
168179
pv.clear()
169-
ml := make(moveList, 0, 60)
180+
181+
// trans retrieve here
182+
183+
var ml moveList
184+
ml.new(60)
185+
170186
//genAndSort(b, &ml)
171187
genInOrder(b, &ml, ply)
172188

173-
bm, bs := noMove, noScore
174-
childPV := make(pvList, 0, maxPly)
189+
bs := noScore
190+
var childPV pvList
191+
childPV.new() // TODO? make it smaller for each depth maxDepth-ply
175192
for _, mv := range ml {
176193
if !b.move(mv) {
177194
continue
@@ -186,6 +203,10 @@ func search(alpha, beta, depth, ply int, pv *pvList, b *boardStruct) int {
186203
if score > bs {
187204
bs = score
188205
pv.catenate(mv, &childPV)
206+
if score > alpha {
207+
alpha = score
208+
// trans.store here
209+
}
189210

190211
if score >= beta { // beta cutoff
191212
// add killer and update history
@@ -194,17 +215,11 @@ func search(alpha, beta, depth, ply int, pv *pvList, b *boardStruct) int {
194215
}
195216
return score
196217
}
197-
if score > alpha {
198-
bm = mv
199-
_ = bm
200-
alpha = score
201-
}
202-
203218
}
204-
if time.Since(limits.nextTime) >= time.Duration(time.Second) {
219+
if time.Since(limits.lastTime) >= time.Duration(time.Second) {
205220
t1 := time.Since(limits.startTime)
206221
tell(fmt.Sprintf("info time %v nodes %v nps %v", int(t1.Seconds()*1000), cntNodes, cntNodes/uint64(t1.Seconds())))
207-
limits.nextTime = time.Now()
222+
limits.lastTime = time.Now()
208223
}
209224

210225
if limits.stop {
@@ -243,14 +258,15 @@ func qs(beta int, b *boardStruct) int {
243258

244259
see := see(fr, to, b)
245260

246-
if see < 0 {
247-
continue // equal captures not interesting
248-
}
249261
if see == 0 && mv.cp() == empty {
250262
// must be a promotion that didn't captureand was not captured
251263
see = pieceVal[wQ] - pieceVal[wP]
252264
}
253265

266+
if see <= 0 {
267+
continue // equal captures not interesting
268+
}
269+
254270
sc := ev + see
255271
if sc > bs {
256272
bs = sc
@@ -356,7 +372,7 @@ func see(fr, to int, b *boardStruct) int {
356372
return captureList[0]
357373
}
358374

359-
func genAndSort(b *boardStruct, ml *moveList) {
375+
/* func genAndSort(b *boardStruct, ml *moveList) {
360376
ml.clear()
361377
b.genAllLegals(ml)
362378
for ix, mv := range *ml {
@@ -368,6 +384,31 @@ func genAndSort(b *boardStruct, ml *moveList) {
368384
(*ml)[ix].packEval(v)
369385
}
370386
387+
ml.sort()
388+
} */
389+
func genAndSort(ply int, b *boardStruct, ml *moveList) {
390+
if ply > maxPly {
391+
panic("wtf maxply")
392+
}
393+
394+
ml.clear()
395+
b.genAllLegals(ml)
396+
397+
for ix, mv := range *ml {
398+
b.move(mv)
399+
v := evaluate(b)
400+
b.unmove(mv)
401+
if killers[ply].k1.cmp(mv) {
402+
v += 1000
403+
} else if killers[ply].k2.cmp(mv) {
404+
v += 900
405+
}
406+
407+
v = signEval(b.stm, v)
408+
409+
(*ml)[ix].packEval(v)
410+
}
411+
371412
ml.sort()
372413
}
373414

engine_test.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func Benchmark_root(b *testing.B) {
2323
fakeRoot()
2424
}
2525
}
26+
2627
// times
2728
/* only a/b nothing else
2829
Benchmark_root-4: 192.911s 1 192848735500 ns/op 13250269384 B/op 28233303 allocs/op
@@ -40,14 +41,14 @@ func fakeRoot() {
4041
childPV.new()
4142
b := &board
4243
ml := make(moveList, 0, 60)
43-
limits.startTime, limits.nextTime = time.Now(), time.Now()
44+
limits.startTime, limits.lastTime = time.Now(), time.Now()
4445
alpha, beta := minEval, maxEval
4546
bm, bs := noMove, noScore
4647
depth := limits.depth
4748
cntNodes = 0
4849
killers.clear()
4950
ml.clear()
50-
genAndSort(b, &ml)
51+
genAndSort(0, b, &ml)
5152

5253
for ix := range ml {
5354
mv := &ml[ix]
@@ -73,7 +74,6 @@ func fakeRoot() {
7374
fmt.Printf("bestmove %v%v", sq2Fen[ml[0].fr()], sq2Fen[ml[0].to()])
7475
}
7576

76-
7777
//////////////////////////////////// TESTS ////////////////////////////////////////////////////////
7878
func Test_genAndSort(t *testing.T) {
7979
tests := []struct {
@@ -88,7 +88,7 @@ func Test_genAndSort(t *testing.T) {
8888
for _, tt := range tests {
8989
t.Run(tt.name, func(t *testing.T) {
9090
var ml moveList
91-
genAndSort(&board, &ml)
91+
genAndSort(0, &board, &ml)
9292
if tt.want1Mv != trim(ml[0].String()) {
9393
t.Errorf("%v: %#v should be best move. Got %#v", tt.name, tt.want1Mv, trim(ml[0].String()))
9494
}
@@ -167,8 +167,8 @@ func Test_initQs(t *testing.T) {
167167
}{
168168
{"startpos", "position startpos", []args{}},
169169
{"dxe5", "position startpos moves d2d4 e7e5", []args{{D4, E5}}},
170-
{"QxQ delayed", "position fen r1b1kbnr/ppp2ppp/2n5/3pp1q1/3P2Q1/4PN2/PPP2PPP/RNB1KB1R w KQkq - 4 5", []args{{D4, E5}, {F3, E5}, {F3, G5}} },
171-
{"ungarded pawn", "position fen rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR w KQkq - 0 2", []args{{C4, B5}, } },
170+
{"QxQ delayed", "position fen r1b1kbnr/ppp2ppp/2n5/3pp1q1/3P2Q1/4PN2/PPP2PPP/RNB1KB1R w KQkq - 4 5", []args{{D4, E5}, {F3, E5}, {F3, G5}}},
171+
{"ungarded pawn", "position fen rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR w KQkq - 0 2", []args{{C4, B5}}},
172172
}
173173
for _, tt := range tests {
174174
t.Run(tt.name, func(t *testing.T) {
@@ -231,7 +231,7 @@ func Test_QS(t *testing.T) {
231231
{"", "Pawn captures unguarded knight. Now under with queen and pawn", "position fen rnb1kbnr/ppp1pppp/8/3n4/2P5/8/PP1PPPPP/RNBQKBNR w KQkq - 0 1", pieceVal[wP] + pieceVal[wQ], 20},
232232
{"", "White is Q-P down", "position fen rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNB1KBNR w KQkq - 0 2", -pieceVal[wQ] + pieceVal[wP], 20},
233233
{"", "Black is Q-P down", "position fen rnb1kbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR b KQkq - 0 2", -pieceVal[wQ] + pieceVal[wP], 20},
234-
234+
235235
// Promotions
236236
{"", "Pawn promotes and no captures", "position fen 8/1k2P3/8/q7/8/8/6K1/8 w - - 0 1", 30, 30},
237237
{"", "Pawn promotes with capture. B under. This special case is not working prperly", "position fen 3b1n2/1k2P3/8/q7/8/8/6K1/8 w - - 0 1", pieceVal[wP] - pieceVal[wB] - pieceVal[wN], 30},
@@ -270,4 +270,3 @@ func Test_QS(t *testing.T) {
270270
})
271271
}
272272
}
273-

london.txt

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

moves.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ func (m move) onlyMv() move {
122122
}
123123

124124
type moveList []move
125+
func (ml *moveList) new(size int) {
126+
*ml = make(moveList, 0, size)
127+
}
125128

126129
func (ml *moveList) clear() {
127130
*ml = (*ml)[:0]

0 commit comments

Comments
 (0)