我在 python 3 中的井字棋游戏中的获胜检测有问题

I have a problem with the win detection in a tic-tac-toe game in python 3

我是一个 Python 初学者 并尝试编写一个简单的井字游戏(没有 GUI,仅基于文本)。我为移动定义了一个函数,每次移动后我调用一个函数来检测获胜/平局。但不知何故,获胜和平局检测不起作用,即游戏运行良好,但当玩家连续有 3 个符号时,游戏继续进行并且没有显示获胜消息。 我已经用代码更改了一些东西(例如,win 检查功能现在只有 returns 1、-1 或 0,而不是直接返回 win 消息),我读了几次代码,但我没有找到问题在哪里:( 请帮忙 完整代码如下:

board = {
    1: "1", 2: "2", 3: "3",
    4: "4", 5: "5", 6: "6",
    7: "7", 8: "8", 9: "9"
}
taken_spaces = []
players = ("X", "O")
current_player = players[0]
board_lines_win_check = {
    "row1": [board[1], board[2], board[3]],
    "row2": [board[4], board[5], board[6]],
    "row3": [board[7], board[8], board[9]],
    "col1": [board[1], board[4], board[7]],
    "col2": [board[2], board[5], board[8]],
    "col3": [board[3], board[6], board[9]],
    "diagonal_lr": [board[1], board[5], board[9]],
    "diagonal_rl": [board[3], board[5], board[7]]
}


def print_board():
    print(f'''
    {board[1]} | {board[2]} | {board[3]}
  ----|---|----
    {board[4]} | {board[5]} | {board[6]}
  ----|---|----
    {board[7]} | {board[8]} | {board[9]}''')


def player_input():
    print_board()
    print('')
    print(f"Player {current_player}'s turn!")
    while True:
        try:
            while True:
                player_move = int(input(f'Please enter the number of the place you want to set your mark: '))
                if (player_move >= 1) and (player_move <= 9) and player_move not in taken_spaces:
                    break
                else:
                    print('Please enter a number between 1 and 9 that has not yet been taken!')
            break
        except ValueError:
            print('Please enter a valid number')
    taken_spaces.append(player_move)
    return player_move


def move():
    player_move = player_input()
    board[player_move] = current_player
    return board


def win_tie_check():
    for line in board_lines_win_check:
        if line[0] == "X" and line[1] == "X" and line[2] == "X":
            return 1
        elif line[0] == "O" and line[1] == "O" and line[2] == "O":
            return -1
    else:
        for line in board_lines_win_check:
            for value in line:
                if value != "X" and value != "O":
                    return ""
            else:
                return 0


for i in range(9):
    move()
    if current_player == players[0]:
        current_player = players[1]
    else:
        current_player = players[0]
    if win_tie_check() == 1:
        print('Player X wins! Congratulations!')
        break
    elif win_tie_check() == -1:
        print('Player O wins! Congratulations')
        break
    elif win_tie_check() == 0:
        print("It's a tie! Good game!")
        break
print_board()

我怀疑问题出在“win_tie_check()”函数

您创建的字典由 board 的初始值填充 - 它不会更新为稍后来自板的更改值:

demo = [1,2,3]
d = {"demo1": demo[1]}  # 2
print(demo, d)

demo[1] = 42
print(demo, d)

输出:

[1, 2, 3] {'demo1': 2}
[1, 42, 3] {'demo1': 2} 

相反,您可以将要检查的索引存储在字典中:

board = {
    1: "1", 2: "2", 3: "3",
    4: "4", 5: "5", 6: "6",
    7: "7", 8: "8", 9: "9"
}
board_lines_win_check = {
    "row1": (1,2,3),    "row2": (4,5,6),    "row3": (7,8,9),
    "col1": (1,4,7),    "col2": (2,5,8),    "col3": (3,6,9),
    "diagonal_lr": (1,5,9),          "diagonal_rl": (3,5,7)
}

def win_tie_check():
    for (i1,i2,i3) in board_lines_win_check.values():
        # all are equal
        if board[i1] == board[i2] == board[i3]:
           return 1 if board[i1] == "X" else -1
    else:
        # any place still available?
        if any(board[i] not in "XO" for i in board):
            return ""
    # draw
    return 0

board = {
    1: "1", 2: "2", 3: "3",
    4: "4", 5: "5", 6: "6",
    7: "7", 8: "8", 9: "9"
}
print(win_tie_check())


board = {
    1: "X", 2: "X", 3: "X",
    4: "4", 5: "5", 6: "6",
    7: "7", 8: "8", 9: "9"
}
print(win_tie_check())


board = {
    1: "O", 2: "X", 3: "X",
    4: "O", 5: "5", 6: "6",
    7: "O", 8: "8", 9: "9"
}
print(win_tie_check())


board = {
    1: "X", 2: "O", 3: "X",
    4: "4", 5: "X", 6: "6",
    7: "7", 8: "8", 9: "X"
}
print(win_tie_check())


board = {
    1: "X", 2: "O", 3: "O",
    4: "O", 5: "X", 6: "X",
    7: "X", 8: "O", 9: "O"
}
print(win_tie_check())

输出:

1
-1
1
0

board_lines_win_check 在您玩游戏时永远不会更新;所以它是用基本的井字棋盘创建的,从未更新过。因此,当您遍历它以检查是否获胜时,它永远找不到。您可以通过将更新的棋盘移动到您的获胜检查中来检查更新的棋盘,以便它创建一个新的 row/column/diagonals 字典来检查:

def win_tie_check():
    to_check = [(1, 2, 3), (4, 5, 6), (7, 8, 9),
                (1, 4, 7), (2, 5, 8), (3, 6, 9),
                (1, 5, 9), (3, 5, 7)]
    for (a, b, c) in to_check:
        if board[a] == board[b] == board[c]:
            return 1 if board[a] == 'X' else -1
        else:
            return 0