iam making a minimax program for tic tac toe in python it works in some state but other it jest return first space call in array
space = ' '
def rate_state(state):
'''
this def is returning
10 if X wins
-10 if O wins
0 if nothing
'''
ter = terminate(state)
if ter != False:
if state[ter[0]] == 'X':
return 10
elif state[ter[0]] == 'O':
return -10
return 0
def terminate(state):
'''
this def is returning
position of same X or O in a line
or False if bord full not wins
'''
win_pos = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
for ws in win_pos:
# print(ws)
if state[ws[0]] != space and state[ws[0]] == state[ws[1]] and state[ws[0]] == state[ws[2]]:
return [ws[0],ws[1], ws[2]]
return False
def min_max(bord):
def deep(state,isMax):
state_scor = rate_state(state)
if state_scor == 10:
return state_scor
elif state_scor == -10:
return state_scor
if terminate(state) == False:
return 0
if isMax:
score = -1000
for itr in range(len(state)):
if state[itr] == space:
state[itr] = 'X'
score = max(score, deep(state, False))
state[itr] = space
return score
else:
score = 1000
for itr in range(len(state)):
if state[itr] == space:
state[itr] = 'O'
score = min(score, deep(state, True))
state[itr] = space
return score
best_score = -1000
best_move = 0
for i in range(len(bord)):
if bord[i] == space:
bord[i] = 'X'
move_sc = deep(bord, False)
bord[i] = space
if move_sc > best_score:
best_score = move_sc
best_move = i
return best_move
# this is the bord mini_max is doing good
workin_board = [
'O', ' ', 'X',
' ', ' ', ' ',
'X', ' ', 'O',
]
# this is the bord mini_max is not doing good i thing the answer most be (4)
not_working_board = [
'O', 'X', ' ',
' ', ' ', ' ',
'X', ' ', 'O',
]
print('next moxe of X is on:',min_max(not_working_board))
=--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------_=
CodePudding user response:
The fix is easy. After you check whether X wins, just check whether an O in that spot loses. If so, pick that move.
It's a little silly to track the move "score" either. The choice is really binary. A move either wins, or blocks a loss, or does nothing.
def min_max(bord):
best_score = -1000
best_move = 0
for i in range(len(bord)):
if bord[i] == space:
bord[i] = 'X'
move_sc = deep(bord, False)
if move_sc > best_score:
best_score = move_sc
best_move = i
bord[i] = 'O'
move_sc = -deep(bord, False)
if move_sc > best_score:
best_score = move_sc
best_move = i
bord[i] = space
return best_move