Python终端井字棋游戏优化:格子设置与胜负检测方案咨询
问题
我正在用Python开发一款简单的终端井字棋游戏,目前在实现9个格子的设置与胜负检测功能时遇到了问题。我现在为每个格子都编写了单独的set函数,但这种实现方式显得冗余,想请教是否有更优的实现方法;同时胜负检测模块也需要更高效的方案。
以下是我的现有代码:
main.py
#!/usr/bin/env python3 #file -- grid.py -- import grid def welcome(): print("Welcome") def main(): welcome() grid.setgrid() print(grid.grid) while 1: xinput = input("Player X: ") if xinput.lower() == "a1": grid.seta1("X") elif xinput.lower() == "a2": grid.seta2("X") elif xinput.lower() == "a3": grid.seta3("X") #and so on print(grid.grid) oinput = input("Player O: ") if __name__ == "__main__": main()
grid.py
a1,a2,a3,b1,b2,b3,c1,c2,c3 = " "," "," "," "," "," "," "," "," " grid = f""" 1 2 3 ┌───┬───┬───┐\n a │ {a1} │ {a2} │ {a3} │\n ├───┼───┼───┤\n b │ {b1} │ {b2} │ {b3} │\n ├───┼───┼───┤\n c │ {c1} │ {c2} │ {c3} │\n └───┴───┴───┘""" def setgrid(): global grid grid = f""" ┌───┬───┬───┐\n │ {a1} │ {a2} │ {a3} │\n ├───┼───┼───┤\n │ {b1} │ {b2} │ {b3} │\n ├───┼───┼───┤\n │ {c1} │ {c2} │ {c3} │\n └───┴───┴───┘""" #set functions def seta1(val): global a1 a1=val setgrid() def seta2(val): global a2 a2=val setgrid() def seta3(val): global a3 a3=val setgrid() def setb1(val): global b1 b1=val setgrid() def setb2(val): global b2 b2=val setgrid() def setb3(val): global b3 b3=val setgrid() def setc1(val): global c1 c1=val setgrid() def setc2(val): global c2 c2=val setgrid() def setc3(val): global c3 c3=val setgrid()
解决方案
一、优化格子设置逻辑
1. 用二维数组存储棋盘状态
把分散的a1、a2等变量替换成3×3的二维列表,直接通过索引访问格子,彻底消除冗余的set函数。
2. 实现通用的格子设置函数
写一个统一的函数处理位置转换、合法性校验和格子赋值,同时动态生成棋盘字符串。
修改后的代码示例
grid.py
# 3×3列表存储棋盘:行0对应a,行1对应b,行2对应c;列0对应1,列1对应2,列2对应3 board = [[" " for _ in range(3)] for _ in range(3)] def generate_grid(): """生成并返回格式化的棋盘字符串""" return f""" 1 2 3 ┌───┬───┬───┐ a │ {board[0][0]} │ {board[0][1]} │ {board[0][2]} │ ├───┼───┼───┤ b │ {board[1][0]} │ {board[1][1]} │ {board[1][2]} │ ├───┼───┼───┤ c │ {board[2][0]} │ {board[2][1]} │ {board[2][2]} │ └───┴───┴───┘ """ def set_cell(pos, val): """根据输入位置设置格子值,pos格式如"a1"、"b2"等""" pos = pos.lower() # 转换为数组索引 row = ord(pos[0]) - ord('a') col = int(pos[1]) - 1 # 校验位置合法性和格子是否为空 if 0 <= row < 3 and 0 <= col < 3 and board[row][col] == " ": board[row][col] = val return True return False
main.py
#!/usr/bin/env python3 import grid def welcome(): print("Welcome to Tic-Tac-Toe!") def main(): welcome() print(grid.generate_grid()) current_player = "X" while True: player_input = input(f"Player {current_player}: ") # 支持退出指令 if player_input.lower() == "quit": break # 尝试落子,成功则切换玩家 if grid.set_cell(player_input, current_player): print(grid.generate_grid()) # 后续添加胜负检测逻辑 current_player = "O" if current_player == "X" else "X" else: print("无效操作!请输入空位置,比如'a1'。") if __name__ == "__main__": main()
二、高效的胜负检测方案
1. 预定义所有获胜组合
井字棋的获胜情况固定为8种:3行、3列、2条对角线。将这些组合的索引预存,每次落子后遍历检查即可。
2. 添加检测函数
在grid.py中加入胜负和平局检测函数:
def check_win(player): """检查指定玩家是否获胜""" # 所有获胜组合的索引集合 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] == player for (row, col) in combo): return True return False def check_draw(): """检查是否平局(棋盘已满且无人获胜)""" return all(cell != " " for row in board for cell in row)
3. 在主循环中加入检测逻辑
修改main.py的落子成功后的代码:
if grid.set_cell(player_input, current_player): print(grid.generate_grid()) # 检查获胜 if grid.check_win(current_player): print(f"玩家{current_player}获胜!") break # 检查平局 if grid.check_draw(): print("平局!") break current_player = "O" if current_player == "X" else "X"
内容的提问来源于stack exchange,提问作者ElectricCarrot
相关产品推荐
相关产品推荐

