Home > Back-end >  mini_max not giving optimal move tic tac toe
mini_max not giving optimal move tic tac toe

Time:06-24

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
  • Related