-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplayer.go
72 lines (59 loc) · 1.58 KB
/
player.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
package reversi
// Player TODO
type Player interface {
Think(b Board) Pos
}
// ComputerPlayer TODO
type ComputerPlayer struct {
stone int
}
// Evaluate Abstract Method
type Evaluate func(b *Board, stone int) int
// NewComputerPlayer Constructor of ComputerPlayer struct
func NewComputerPlayer(stone int) *ComputerPlayer {
if stone != STONE_BLACK && stone != STONE_WHITE {
panic("Stone must be STONE_BLACK or STONE_WHITE!")
}
p := new(ComputerPlayer)
p.stone = stone
return p
}
func (p *ComputerPlayer) Think(b Board, e Evaluate, depth int) Pos {
movables := b.CalcMovable(p.stone)
if len(movables) == 0 {
return Pos{Index: INDEX_SKIP, Stone: p.stone}
} else if len(movables) == 1 {
return Pos{Index: movables[0], Stone: p.stone}
}
score, index := p.alphabeta(&b, e, p.stone, -10000, 10000, depth)
return Pos{Index: index, Stone: p.stone, Score: score}
}
func (p *ComputerPlayer) alphabeta(b *Board, eval Evaluate, stone, alpha, beta, depth int) (int, int) {
if depth <= 0 || b.CheckGameover() {
//return p.evaluate(b, stone), INDEX_SKIP
return eval(b, stone), INDEX_SKIP
}
movables := b.CalcMovable(stone)
if len(movables) == 0 {
b.Skip(stone)
score, _ := p.alphabeta(b, eval, -stone, -beta, -alpha, depth-1)
b.Undo()
score = -score
return score, INDEX_SKIP
}
bestindex := INDEX_SKIP
for _, index := range movables {
b.Move(index, stone)
score, _ := p.alphabeta(b, eval, -stone, -beta, -alpha, depth-1)
b.Undo()
score = -score
if score > alpha {
alpha = score
bestindex = index
}
if alpha >= beta {
break
}
}
return alpha, bestindex
}