You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新手tic-tac-toe游戏代码优化咨询:平局判断与继续游玩逻辑分离及改进建议

新手tic-tac-toe游戏代码优化咨询:平局判断与继续游玩逻辑分离及改进建议

嘿,别担心!作为新手能写出完整运行的井字棋已经超棒了,咱们一步步拆解问题,优化代码逻辑和结构~

一、分离平局判断与继续游玩逻辑

当前你的victory_for函数既处理胜利判断,又输出模糊的“tie or we keep playing”,这会导致逻辑混在一起。咱们可以把这部分拆成两个独立的逻辑:

1. 单独实现平局判断函数

写一个专门检查平局的函数,当所有格子都被填满且没有玩家获胜时,判定为平局:

def check_tie(board):
    # 遍历所有格子,只要还有数字(未被占据)就不是平局
    for row in board:
        for cell in row:
            if isinstance(cell, int):
                return False
    return True

2. 在主游戏循环中明确处理流程

把胜利判断、平局判断、继续游玩的逻辑分开,每次回合结束后依次检查:

  • 先检查当前玩家是否获胜
  • 若未获胜,检查是否平局
  • 若平局或获胜,询问玩家是否重新开始游戏

二、代码结构与细节优化建议

除了平局逻辑,还有几个小细节可以让代码更健壮、易维护:

  • 函数职责单一化:
    现在的victory_for函数直接调用exit()结束程序,这会让代码灵活性变差。改成让函数返回布尔值(是否获胜),由主逻辑决定后续操作:

    def victory_for(board, sign):
        win_combinations = [
            [(0,0), (0,1), (0,2)],  # 横向
            [(1,0), (1,1), (1,2)],
            [(2,0), (2,1), (2,2)],
            [(0,0), (1,0), (2,0)],  # 纵向
            [(0,1), (1,1), (2,1)],
            [(0,2), (1,2), (2,2)],
            [(0,0), (1,1), (2,2)],  # 对角线
            [(0,2), (1,1), (2,0)]
        ]
        # 检查每一组获胜组合
        for combo in win_combinations:
            if all(board[row][col] == sign for row, col in combo):
                print(f"Game wins the {sign} player!")
                return True
        return False
    

    这里把获胜组合直接用坐标表示,不用再依赖board1字典,逻辑更直接。

  • 优化输入验证:
    当前enter_move没有处理无效输入(比如输入非数字、超出1-9范围、位置已被占据),可以加循环让玩家重新输入:

    def enter_move(board):
        while True:
            try:
                move = int(input("Podaj liczbe na ktorej chcesz postawic O (1-9): "))
                if move < 1 or move > 9:
                    print("请输入1-9之间的数字!")
                    continue
                # 转换为棋盘坐标
                row = (move - 1) // 3
                col = (move - 1) % 3
                if isinstance(board[row][col], int):
                    board[row][col] = "O"
                    break
                else:
                    print("这个位置已经被占据了,请选另一个!")
            except ValueError:
                print("请输入有效的数字!")
    

    这里直接通过计算转换坐标,去掉了board1字典,减少冗余。

  • 避免全局变量:
    当前board是全局变量,每次重新游戏时不会重置。可以把棋盘初始化放到game()函数里,每次开始新游戏都生成新棋盘:

    def game():
        while True:
            # 初始化新棋盘
            board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
            print("新游戏开始!")
            while True:
                display_board(board)
                enter_move(board)
                # 检查玩家O是否获胜
                if victory_for(board, "O"):
                    display_board(board)
                    break
                # 检查是否平局
                if check_tie(board):
                    display_board(board)
                    print("平局!")
                    break
                display_board(board)
                draw_move(board)
                # 检查AI玩家X是否获胜
                if victory_for(board, "X"):
                    display_board(board)
                    break
                # 检查平局
                if check_tie(board):
                    display_board(board)
                    print("平局!")
                    break
            # 询问是否继续游玩
            play_again = input("想再玩一局吗?(y/n): ").lower()
            if play_again != "y":
                print("游戏结束!")
                break
    
  • 简化make_list_of_free_fields函数:
    如果已经用坐标直接处理,可以把这个函数改成返回可用坐标的列表,更实用:

    def make_list_of_free_fields(board):
        free_fields = []
        for row_idx, row in enumerate(board):
            for col_idx, cell in enumerate(row):
                if isinstance(cell, int):
                    free_fields.append((row_idx, col_idx))
        return free_fields
    

    然后修改draw_move函数,直接从可用坐标里选,效率更高:

    def draw_move(board):
        free_fields = make_list_of_free_fields(board)
        if free_fields:
            row, col = random.choice(free_fields)
            board[row][col] = "X"
    

三、完整优化后的代码参考

把上面的修改整合起来,完整代码会更清晰、健壮:

import random

def display_board(board):
    print(f"""
+-------+-------+-------+
|       |       |       |
|   {board[0][0]}   |   {board[0][1]}   |   {board[0][2]}   |
|       |       |       |
+-------+-------+-------+
|       |       |       |
|   {board[1][0]}   |   {board[1][1]}   |   {board[1][2]}   |
|       |       |       |
+-------+-------+-------+
|       |       |       |
|   {board[2][0]}   |   {board[2][1]}   |   {board[2][2]}   |
|       |       |       |
+-------+-------+-------+""")

def enter_move(board):
    while True:
        try:
            move = int(input("Podaj liczbe na ktorej chcesz postawic O (1-9): "))
            if move < 1 or move > 9:
                print("请输入1-9之间的数字!")
                continue
            row = (move - 1) // 3
            col = (move - 1) % 3
            if isinstance(board[row][col], int):
                board[row][col] = "O"
                break
            else:
                print("这个位置已经被占据了,请选另一个!")
        except ValueError:
            print("请输入有效的数字!")

def make_list_of_free_fields(board):
    free_fields = []
    for row_idx, row in enumerate(board):
        for col_idx, cell in enumerate(row):
            if isinstance(cell, int):
                free_fields.append((row_idx, col_idx))
    return free_fields

def victory_for(board, sign):
    win_combinations = [
        [(0,0), (0,1), (0,2)],
        [(1,0), (1,1), (1,2)],
        [(2,0), (2,1), (2,2)],
        [(0,0), (1,0), (2,0)],
        [(0,1), (1,1), (2,1)],
        [(0,2), (1,2), (2,2)],
        [(0,0), (1,1), (2,2)],
        [(0,2), (1,1), (2,0)]
    ]
    for combo in win_combinations:
        if all(board[row][col] == sign for row, col in combo):
            print(f"Game wins the {sign} player!")
            return True
    return False

def check_tie(board):
    for row in board:
        for cell in row:
            if isinstance(cell, int):
                return False
    return True

def draw_move(board):
    free_fields = make_list_of_free_fields(board)
    if free_fields:
        row, col = random.choice(free_fields)
        board[row][col] = "X"
        print(f"AI选择了位置{(row*3)+col+1}")

def game():
    while True:
        board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
        print("新游戏开始!")
        current_turn = "O"  # 玩家先出
        while True:
            display_board(board)
            if current_turn == "O":
                enter_move(board)
                if victory_for(board, "O"):
                    break
            else:
                draw_move(board)
                if victory_for(board, "X"):
                    break
            if check_tie(board):
                display_board(board)
                print("平局!")
                break
            # 切换回合
            current_turn = "X" if current_turn == "O" else "O"
        play_again = input("想再玩一局吗?(y/n): ").lower()
        if play_again != "y":
            print("游戏结束!")
            break

game()

备注:内容来源于stack exchange,提问作者Demcio Demcio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 11:59:39