I need help with a minimax bot for tic-tac-toe (naughts and crosses)

I am trying to create a tic-tac-toe bot that uses the minimax algorithm to help me.
I would like help with the function that detects if a state is a terminal state.
For some reason it is always return False.
Note that the state is a list of strings, one string for every grid space.
1: your enemy’s mark(o/x)
0: your mark(x/o)
space: empty space

def terminal(state):
    lines = [
        " #  #  # ",
        "   ###   ",
        "###      ",
        "      ###",
        "#  #  #  ",
        "  #  #  #",
        "#   #   #",
        "  # # #  ",
    player = "0"
    playerlines = [
        list(str(line).replace("#", player)) for line in lines
    ]  # lines but with hashtags replaced wth the player
    evalstate = list(
        str(state).replace(otherplayer(player), " ")
    )  # the gameboard with only the current player for detection
    if evalstate in playerlines:
        return 1
    player = "1"
    playerlines = [list(str(line).replace("#", player)) for line in lines]
    evalstate = list(str(state).replace(otherplayer(player), " "))
    if evalstate in playerlines:
        return -1
    if not " " in state:
        return 0
    return False

0 == False, so False is returned. Maybe that’s the problem?
Now I understand. If there’s no blank space then the move is terminal (it’s a draw), so this behaviour is intended


I don’t get it? Are you sure that the game you’re refering is Tic-Tac-Toe? What are this lines?


I think you meant to put list(str(line).replace("#", player) for line in lines). Also, you’re creating a list with a list inside of it.


the “lines” variable represents all the possible ways a player could get three in a row.
so " # # # " represents
" # "
" # "
" # "
on a 3x3 grid.

1 Like

I thought that if one value was returned, the function would return that and stop.

Ooooh I get it now. You’re mapping a 3x3 grid to a single string of length 9. In that case ins’t better to create a function that goes through all possible winning lines for both? I think the key issue here is how you compare the state and the winning lines.

For example, for each line it checks if all relevant positions in the state match the current player. If they do, the function returns 1 for a bot’s win or -1 for an opponent’s win.