Last active
December 7, 2021 04:43
-
-
Save luccabb/141a947c2b545dc4e2943617f0289a8d to your computer and use it in GitHub Desktop.
python minimax function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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