-
Notifications
You must be signed in to change notification settings - Fork 2
/
ChessAi.py
156 lines (138 loc) · 4.64 KB
/
ChessAi.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 random
pieceScore = {"K": 0, "Q": 10, "R": 5, "B": 3, "N": 3, "P": 1}
CHECKMATE = 1000
STALEMATE = 0
DEPTH = 3
def findRandomMove(validMoves):
return validMoves[random.randint(0, len(validMoves) - 1)]
# Helper Method To Make The First Recursive Call.
def findBestMove(gs, validMoves : list):
global nextMove, counter
nextMove = None
random.shuffle(validMoves)
counter = 0
# findMoveMinMax(gs, validMoves, DEPTH, gs.whiteToMove)
# findNegaMaxMove(gs, validMoves, DEPTH, 1 if gs.whiteToMove else -1)
findNegaMaxAlphaBeta(gs, validMoves, DEPTH, -CHECKMATE, CHECKMATE, 1 if gs.whiteToMove else -1)
print(counter)
return nextMove
def findMinMaxIterative(gs, validMoves):
turnMultiplier = 1 if gs.whiteToMove else -1
opponentMinMaxScore = CHECKMATE
bestPlaryMove = None
random.shuffle(validMoves)
for playerMove in validMoves:
gs.makeMove(playerMove, bot=True)
opponentValidMoves = gs.getValidMoves()
opponentMaxScore = -CHECKMATE
for opponentMove in opponentValidMoves:
gs.makeMove(opponentMove, bot=True)
if gs.checkmate:
score = -CHECKMATE
elif gs.stalemate:
score = 0
else:
score = -turnMultiplier * scoreMaterial(gs.board) # it became The opposite Color playing
if score > opponentMaxScore:
opponentMaxScore = score
gs.undoMove(bot=True)
if opponentMaxScore < opponentMinMaxScore:
opponentMinMaxScore = opponentMaxScore
bestPlaryMove = playerMove
gs.undoMove(bot=True)
return bestPlaryMove
def findMoveMinMax(gs, validMoves, depth, whiteToMove):
global nextMove, counter
counter += 1
if depth == 0:
return scoreMaterial(gs.board)
if whiteToMove:
maxScore = -CHECKMATE
for move in validMoves:
gs.makeMove(move)
oppMoves = gs.getValidMoves()
score = findMoveMinMax(gs, oppMoves, depth - 1, False)
if score > maxScore:
maxScore = score
if depth == DEPTH:
nextMove = move
gs.undoMove()
return maxScore
else:
minScore = CHECKMATE
for move in validMoves:
gs.makeMove(move)
oppMoves = gs.getValidMoves()
score = findMoveMinMax(gs, oppMoves, depth - 1, True)
if score < minScore:
minScore = score
if depth == DEPTH:
nextMove = move
gs.undoMove()
return minScore
def findNegaMaxMove(gs, validMoves, depth, turnMultiplier):
global nextMove, counter
counter += 1
if depth == 0:
return turnMultiplier * scoreBoard(gs)
maxScore = - CHECKMATE
for move in validMoves:
gs.makeMove(move)
nextMoves = gs.getValidMoves()
score = -findNegaMaxMove(gs, nextMoves, depth - 1, -turnMultiplier)
if score > maxScore:
maxScore = score
if depth == DEPTH:
nextMove = move
gs.undoMove()
return maxScore
def findNegaMaxAlphaBeta(gs, validMoves, depth, alpha, beta, turnMultiplier):
global nextMove, counter
counter += 1
if depth == 0:
return turnMultiplier * scoreBoard(gs)
# Move Ordering - Implement Later
maxScore = - CHECKMATE
for move in validMoves:
gs.makeMove(move)
nextMoves = gs.getValidMoves()
score = -findNegaMaxAlphaBeta(gs, nextMoves, depth - 1, -beta, -alpha, -turnMultiplier)
if score > maxScore:
maxScore = score
if depth == DEPTH:
nextMove = move
gs.undoMove()
if maxScore > alpha: #prunnig Hapens
alpha = maxScore
if alpha >= beta:
break
return maxScore
'''
A Positive Score Means White Is Winnig
A Negative Score Means Black Is Winning
'''
def scoreBoard(gs):
if gs.checkmate:
if gs.whiteToMove:
return - CHECKMATE # Black Wins
else:
return CHECKMATE # white Wins
elif gs.stalemate:
return STALEMATE
score = 0
for row in gs.board:
for square in row:
if square[0] == 'w':
score += pieceScore[square[1]]
elif square[0] == 'b':
score -= pieceScore[square[1]]
return score
def scoreMaterial(board: list):
score = 0
for row in board:
for square in row:
if square[0] == 'w':
score += pieceScore[square[1]]
elif square[0] == 'b':
score -= pieceScore[square[1]]
return score