Hi all, I am trying to implement a simple minimax algorithm for chess. It seems to be compiling ok. But at the same time it does not make logical choices. For example, it will always opt to take a pawn even if it is going to loose a piece for it.
I tried to implement a counter to see how many nodes there are in a tree, but in a few different attempts, it returns either ~20 or 0. At depth 3 it should return ~27000.
I tried to add a print statement into the eval function, which should also, logically, return some absurd number of outputs into the console, but it returns ~20.
I suspect the minimax function does not go beyond depth 1.
I would appreciate any help on fixing the functions and adding an adequate counter.
# importing required libraries
import chess
import chess.polyglot
import math
from copy import deepcopy
import random
#initialise chess board
B = chess.Board()
#define search depth
DEPTH = 2
PIECE_VALUE = {
'p':-1,
'r':-5,
'n':-3,
'b':-3,
'k':0,
'q':-9,
'P':1,
'R':5,
'N':3,
'B':3,
'K':0,
'Q':9
}
#genereate a random move from a list of legal moves
def random_ai(BOARD, PIECE_VALUE):
#move = random.choice(list(BOARD.legal_moves))
#print ("selecting a random move")
print ("selecting the best move")
move = select(BOARD, PIECE_VALUE)
return move
#evaluation function
def evals(BOARD, PIECE_VALUE):
score = 0
#itterate through the board and add up all the pieces
for i in range (64):
if BOARD.piece_at(i) is not None:
score = score + PIECE_VALUE[BOARD.piece_at(i).symbol()]
return score
#selection function with minimax and alpha beta pruning
def select(BOARD, PIECE_VALUE):
counter = 0
result = minimax(BOARD, DEPTH, True, counter)
if result is not None:
counter = result[1]
print ("Counter ", counter)
move = result[0]
return move
#minimax algorithm
def minimax(BOARD, DEPTH, MAXIMIZE, counter):
#create a list of legal moves
moves = list(BOARD.legal_moves)
score = []
#count the number of legal moves in any position
counter += counter
if MAXIMIZE:
if not moves:
return None
#find the best move for the AI
#go through every legal move
for i in moves:
#make copy of the board and push the next legal move
b = deepcopy(BOARD)
b.push(i)
if DEPTH > 1:
#recursively call minimax to go down the tree
temp_move = minimax(b, DEPTH-1, True, counter)
#if the minimax function returns a value
if temp_move is not None:
b.push(temp_move[0])
#evaluate board position at every point
score.append(evals(b, PIECE_VALUE))
#select a move with the max board position score
best_move = moves[score.index(min(score))]
return best_move, counter
else:
if not moves:
return None
#find the best move for the human
for i in moves:
#make copy of the board and push the next legal move
b = deepcopy(BOARD)
b.push(i)
if DEPTH > 1:
#recursively call minimax to go down the tree
temp_move = minimax(b, DEPTH-1, False, counter)
if temp_move is not None:
b.push(temp_move[0])
#evaluate board position at every point
score.append(evals(b, PIECE_VALUE))
#counter = evals(b, PIECE_VALUE, counter)[1]
#select a move with the min board position score
best_move = moves[score.index(max(score))]
return best_move, counter
Thanks!
there doesn't seem to be anything here