-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheuristic.py
156 lines (140 loc) · 4.39 KB
/
heuristic.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import chess
import chess.svg
import chess.polyglot
from evaluation import *
from app import get_board
from redis_auth import r
board = None
def evaluate_board():
if board.is_checkmate():
if board.turn:
return -9999
else:
return 9999
if board.is_stalemate():
return 0
if board.is_insufficient_material():
return 0
wp = len(board.pieces(chess.PAWN, chess.WHITE))
bp = len(board.pieces(chess.PAWN, chess.BLACK))
wn = len(board.pieces(chess.KNIGHT, chess.WHITE))
bn = len(board.pieces(chess.KNIGHT, chess.BLACK))
wb = len(board.pieces(chess.BISHOP, chess.WHITE))
bb = len(board.pieces(chess.BISHOP, chess.BLACK))
wr = len(board.pieces(chess.ROOK, chess.WHITE))
br = len(board.pieces(chess.ROOK, chess.BLACK))
wq = len(board.pieces(chess.QUEEN, chess.WHITE))
bq = len(board.pieces(chess.QUEEN, chess.BLACK))
material = (
100 * (wp - bp)
+ 320 * (wn - bn)
+ 330 * (wb - bb)
+ 500 * (wr - br)
+ 900 * (wq - bq)
)
pawnsq = sum([pawntable[i] for i in board.pieces(chess.PAWN, chess.WHITE)])
pawnsq = pawnsq + sum(
[
-pawntable[chess.square_mirror(i)]
for i in board.pieces(chess.PAWN, chess.BLACK)
]
)
knightsq = sum([knightstable[i] for i in board.pieces(chess.KNIGHT, chess.WHITE)])
knightsq = knightsq + sum(
[
-knightstable[chess.square_mirror(i)]
for i in board.pieces(chess.KNIGHT, chess.BLACK)
]
)
bishopsq = sum([bishopstable[i] for i in board.pieces(chess.BISHOP, chess.WHITE)])
bishopsq = bishopsq + sum(
[
-bishopstable[chess.square_mirror(i)]
for i in board.pieces(chess.BISHOP, chess.BLACK)
]
)
rooksq = sum([rookstable[i] for i in board.pieces(chess.ROOK, chess.WHITE)])
rooksq = rooksq + sum(
[
-rookstable[chess.square_mirror(i)]
for i in board.pieces(chess.ROOK, chess.BLACK)
]
)
queensq = sum([queenstable[i] for i in board.pieces(chess.QUEEN, chess.WHITE)])
queensq = queensq + sum(
[
-queenstable[chess.square_mirror(i)]
for i in board.pieces(chess.QUEEN, chess.BLACK)
]
)
kingsq = sum([kingstable[i] for i in board.pieces(chess.KING, chess.WHITE)])
kingsq = kingsq + sum(
[
-kingstable[chess.square_mirror(i)]
for i in board.pieces(chess.KING, chess.BLACK)
]
)
eval = material + pawnsq + knightsq + bishopsq + rooksq + queensq + kingsq
if board.turn:
return eval
else:
return -eval
# Searching the best move using minimax and alphabeta algorithm with negamax implementation
def alphabeta(alpha, beta, depthleft):
bestscore = -9999
if depthleft == 0:
return quiesce(alpha, beta)
for move in board.legal_moves:
board.push(move)
score = -alphabeta(-beta, -alpha, depthleft - 1)
board.pop()
if score >= beta:
return score
if score > bestscore:
bestscore = score
if score > alpha:
alpha = score
return bestscore
def quiesce(alpha, beta):
stand_pat = evaluate_board()
if stand_pat >= beta:
return beta
if alpha < stand_pat:
alpha = stand_pat
for move in board.legal_moves:
if board.is_capture(move):
board.push(move)
score = -quiesce(-beta, -alpha)
board.pop()
if score >= beta:
return beta
if score > alpha:
alpha = score
return alpha
def selectmove(depth):
try:
move = (
chess.polyglot.MemoryMappedReader("human.bin").weighted_choice(board).move
)
return move
except:
bestMove = chess.Move.null()
bestValue = -99999
alpha = -100000
beta = 100000
for move in board.legal_moves:
board.push(move)
boardValue = -alphabeta(-beta, -alpha, depth - 1)
if boardValue > bestValue:
bestValue = boardValue
bestMove = move
if boardValue > alpha:
alpha = boardValue
board.pop()
return bestMove
def algomove(game_id):
global board
board = get_board(game_id)
move = selectmove(3)
board.push(move)
r.set(game_id, board.fen())