-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchess_state.py
91 lines (75 loc) · 2.58 KB
/
chess_state.py
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
88
89
90
91
import chess
import sys
class ChessState(chess.Board):
"""
Chessboard subclass implementing the interface needed for minimax
"""
def __init__(self, evaluate=(lambda _: 0), memoize=False, fen=None):
# evaluate is an heuristic function taking a board state
# and returning an approximate value.
self.evaluate = evaluate
self.memoize = memoize
if memoize:
self.values = dict()
super().__init__()
def __str__(self):
# Board representation
result = [' ABCDEFGH']
for i in range(8):
line = [str(i+1), ' ']
for j in range(8):
piece = self.piece_at(8*i+j)
if piece:
line.append(piece.symbol())
else:
line.append('#')
result.append(''.join(line))
return '\n'.join(reversed(result))
def winner(self):
if (self.is_stalemate() or
self.is_insufficient_material() or
self.can_claim_draw()):
return None
if not self.is_game_over():
return False
return chess.WHITE if self.turn == chess.BLACK else chess.BLACK
def hashable(self):
return (self.occupied_co[chess.WHITE],
self.occupied_co[chess.BLACK],
self.pawns,
self.knights,
self.bishops,
self.rooks,
self.queens,
self.kings)
def value(self):
"""Get ground value of state, if exists, or evaluate(state) if not."""
h = self.hashable()
if self.memoize and h in self.values:
return self.values[h]
result = None
winner = self.winner()
if winner == False:
# Game's not over
result = self.evaluate(self)
elif winner is None:
# Draws are neutral
result = 0
else:
# Good for winner, bad for loser
result = float("inf" if winner == chess.BLACK else "-inf")
if self.memoize:
self.values[h] = result
return result
def moves(self):
for move in self.generate_legal_moves():
self.push(move)
yield (move, self)
self.pop()
def do(self, move):
"""Return a new board resulting from the current player taking move"""
result = ChessState(evaluate=self.evaluate, fen=self.fen(), memoize=self.memoize)
result.push(move)
return result
def is_terminal(self):
return self.is_game_over()