Skip to content

Instantly share code, notes, and snippets.

@luccabb
Last active December 7, 2021 04:43
Show Gist options
  • Save luccabb/141a947c2b545dc4e2943617f0289a8d to your computer and use it in GitHub Desktop.
Save luccabb/141a947c2b545dc4e2943617f0289a8d to your computer and use it in GitHub Desktop.
python minimax function
def minimax(
board: chess.Board,
depth: int,
player: int) -> Tuple[Union[int, chess.Move]]:
"""
This functions receives a board, depth and a player; and it returns
the best move for the current board based on how many depths we're looking ahead
and which player is playing. For every move we will do the recursion until
leaf nodes and evaluate all leaf lodes.
OBS:
- We only need to evaluate the value for leaf nodes because they are our final states
of the board and therefore we need to use their scores to decide the best move.
Arguments:
- board: chess board state
- depth: how many depths we want to calculate for this board
- player: player that is currently moving pieces. 1 for AI (max), -1 for human (min).
Returns:
- best_score, best_move: returns best move that it found and its value.
"""
# recursion base case
if depth == 0:
# evaluate current board
score = board_value(board)
return score, None
best_move = None
# initializing best_move_value found depending on the player
if player:
best_move_value = float("-inf")
else:
best_move_value = float("inf")
for move in board.legal_moves:
# make the move
board.push(move)
# if threefold repetition we do not analyze this position
if board.can_claim_threefold_repetition():
board.pop() # unmake the last move
continue
score = minimax(board, depth-1, not player)[0]
if player:
# look for moves that maximize position, max player (AI moves)
if score > best_move_value:
# if it was the highest score move so far, we make this move
best_move_value = score
best_move = move
else:
# look for best moves that minimize position, min player (Human moves)
if score < best_move_value:
# we assume human is making the best move for himself
best_move_value = score
best_move = move
# take move back
board.pop()
# if it returned no best move, we make a random one
if not best_move:
if board.legal_moves:
best_move = random.choice([move for move in board.legal_moves])
else:
best_move = (None, None)
return best_move_value, best_move
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment