!pip install chess
Requirement already satisfied: chess in /home/plaub/miniconda3/envs/ai2024/lib/python3.11/site-packages (1.10.0)
ACTL3143 & ACTL5111 Deep Learning for Actuaries
Your task is to make a Chess-playing AI which uses the minimax algorithm.
!pip install chess
Requirement already satisfied: chess in /home/plaub/miniconda3/envs/ai2024/lib/python3.11/site-packages (1.10.0)
import chess
import math
import random
from IPython import display
= {"P": 1, "N": 3, "B": 3,
STANDARD_PIECE_VALUES "R": 5, "Q": 9, "K": 0}
def static_evaluation(board):
if board.is_game_over():
= board.outcome()
outcome if outcome.winner == chess.WHITE:
return 1_000_000
elif outcome.winner == chess.BLACK:
return -1_000_000
else:
return 0
= 0
points_balance for square in chess.SQUARES:
= board.piece_at(square)
piece if piece:
= STANDARD_PIECE_VALUES[piece.symbol().upper()]
piece_value if piece.symbol().isupper():
+= piece_value
points_balance else:
-= piece_value
points_balance
return points_balance
# Testing 'static_evaluation' on a board.
= chess.Board("2r3k1/p3bp1p/2Bp1np1/4p3/1r6/B1R5/P1PP1P1P/R5K1 b - - 0 1")
board board
# Expect this to be -1 (i.e. black up one pawn)
static_evaluation(board)
-1
Pseudocode to evaluate the ‘minimax’ algorithm’s value of a chess board position.
function minimax (position, depth, maximizingPlayer)
if depth == 0 or game over in position
return static evaluation of position
if maximizingPlayer
maxEval = -infinity
for each child of position
eval = minimax(child, depth - 1, false)
maxEval = max(maxEval, eval)
return maxEval
else
minEval = infinity
for each child of position
eval = minimax(child, depth - 1, true)
minEval = min(minEval, eval)
return minEval
Source of the pseudocode: Around 3-4 minute mark of the following video:
# TODO: Create a 'minimax' function here, according to the pseudocode above.
def minimax(board, depth):
pass
# TODO: Redefine the 'minimax' function to include the alpha-beta pruning extension.
The following code will play a weaker AI (minimax with depth 2) against a stronger AI (minimax with depth 3).
def choose_move(board, depth=2):
= list(board.legal_moves)
options = []
scores
for move in options:
board.push(move)-1))
scores.append(minimax(board, depth
board.pop()
= board.turn == chess.WHITE
maximising_player
if maximising_player:
= max(scores)
best_score else:
= min(scores)
best_score
= []
best_options for move, score in zip(options, scores):
if score == best_score:
best_options.append(move)
return random.choice(best_options)
def play_ai_vs_ai():
42)
random.seed(
= chess.Board()
board
display.display(board)
= 1
move_number while not board.is_game_over():
= list(board.legal_moves)
moves if len(moves) == 0:
print("No moves are possible!")
break
if board.turn == chess.WHITE:
= choose_move(board, depth=2)
move else:
= choose_move(board, depth=3)
move
board.push(move)
=True)
display.clear_output(wait
display.display(board)
print(f"Move #{move_number}: Score = {static_evaluation(board)}")
+= 1 move_number
Uncomment and run the following after you’ve finished making your minimax function.
# play_ai_vs_ai()