In the main program loop, the for loop goes through each of the empty positions in the TicTacToe board and then applies the minimax function on each position to give the evaluation of that particular move. However, for each particular board configuration at a moment based on input, it returns the same evaluation for all the empty spots.
board= [ "X", 1, 2,
3, "O", 5,
6 , 7, 8]
human = "O"
robot= "X"
def evaluation(board):
if (winning(board, robot)):
return +10
elif (winning(board, human)):
return -10
else:
return 0
def minimax(empty_spots, depth, maximizing_player):
if depth==0 or len(empty_spots)==0:
eval= evaluation(board)
# print(f'The evaluation function returns: {evaluation(board)}')
# return evaluation(board)
return eval
if maximizing_player:
maxEval= -1000000
empty_spots=list(filter(lambda spot: (spot!="O" and spot!="X"), board))
# print(f'testing empty spots from maximizing_player{empty_spots}')
#for the child of that position
for spot in empty_spots:
board[spot]=robot
eval = minimax(empty_spots, depth-1, False)
#then remove the move and replace it with the number
board[spot]=spot
maxEval= max(maxEval, eval)
# print(f'The maxEval is {maxEval}')
# print(f'The maxEval is {maxEval}')
return maxEval
else:
minEval= +1000000
empty_spots=list(filter(lambda spot: (spot!="O" and spot!="X"), board))
# print(f'testing empty spots from minimizing_player{empty_spots}')
#for each child of that position
for spot in empty_spots:
board[spot]=human
eval= minimax(empty_spots, depth-1, True)
#then remove the spot
board[spot]=spot
minEval=min(minEval, eval)
# print(f'The minEval is {minEval}')
return minEval
#the main program loop
while(True):
while(True):
try:
human_input=int(input("Please enter an integer from 0 to 8: "))
#this should only take in empty spots
if(human_input>=0 and human_input<=8):
break
except ValueError:
print("Input must be an integer value.")
board[human_input]= human
#returns a list of empty positions in the array
empty_spots=list(filter(lambda spot: (spot!="O" and spot!="X"), board))
print(empty_spots)
moves= []
for spot in empty_spots:
spot_eval= minimax(empty_spots, len(empty_spots), True)
print(f'The spot eval for {spot} is {spot_eval}')
moves.append(spot_eval)
print(f'This is the moves array {moves}')
#go through the moves array and pick out the best
best_move= empty_spots[0]
for move in moves:
best_move= max(best_move, move)
print(f'The best move is {best_move}')
Where I expected the output of the move array to be [10,-10,0 ..] and so on for each empty spot. My output is instead, for example :
Let's look at this loop you have in the program:
for spot in empty_spots:
spot_eval = minimax(empty_spots, len(empty_spots), True)
print(f'The spot eval for {spot} is {spot_eval}')
moves.append(spot_eval)
Note that the call to minimax
function is the same on all iterations of the for loop because it doesn't depend on the spot
variable. So basically you do len(empty_spots)
calls to minimax
function in this loop (which are all the same). As a result, the moves
array is filled with the same value, which is equal to the value returned by
minimax(empty_spots, len(empty_spots), True)