新手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
相关产品推荐
相关产品推荐

