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

Tkinter井字棋:点击交替显示X/O功能实现报错求助

问题修复与功能实现

原代码核心问题

  • 无效全局变量声明:global buttons[0][0]不符合Python语法,且手动创建的两个按钮会被后续循环覆盖,属于冗余代码。
  • 缺少回合控制:没有标记当前落子方,无法实现X/O交替。
  • 未实现点击核心逻辑:点击按钮后未设置文本、禁用按钮,也没有切换回合。

修正后的完整代码

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import font as tkFont

# 全局变量:记录当前回合(X先手)和按钮数组
current_player = 'X'
buttons = []

# 打开游戏窗口
def play_game():
    global buttons, current_player
    # 重置回合为X
    current_player = 'X'
    
    game_window = tk.Toplevel(win)
    game_window.title("井字棋游戏")
    game_window.geometry("600x600")
    game_window.resizable(False, False)

    # 绘制棋盘分割线
    canvas = tk.Canvas(game_window, width=600, height=600)
    canvas.pack()
    for i in range(1, 3):
        canvas.create_line(0, i * 200, 600, i * 200, fill="black")
        canvas.create_line(i * 200, 0, i * 200, 600, fill="black")

    # 创建3x3按钮网格
    buttons = [[None] * 3 for _ in range(3)]
    for i in range(3):
        for j in range(3):
            x1 = j * 200
            y1 = i * 200
            buttons[i][j] = ttk.Button(game_window, text=" ", style='tmrn.TButton')
            # 绑定点击事件并传递行列坐标
            buttons[i][j].config(command=lambda row=i, col=j: button_click(row, col))
            buttons[i][j].place(x=x1, y=y1, width=200, height=200)

    # 添加重置按钮
    reset_btn = ttk.Button(game_window, text="重置游戏", command=lambda: reset_game(game_window), style='tmrn.TButton')
    reset_btn.place(relx=0.5, rely=0.95, anchor=tk.CENTER)

# 按钮点击事件处理
def button_click(row, col):
    global current_player
    button = buttons[row][col]
    # 跳过已点击的按钮
    if button['text'] != " ":
        return
    # 设置当前玩家标记
    button.config(text=current_player)
    # 禁用按钮防止重复点击
    button.config(state=tk.DISABLED)
    # 切换回合
    current_player = 'O' if current_player == 'X' else 'X'

# 重置游戏
def reset_game(game_window):
    game_window.destroy()
    play_game()

# 打开用户指南
def open_user_guide():
    guide_window = tk.Toplevel(win)
    guide_window.title("用户指南")
    guide_window.geometry("800x300")
    guide_window.resizable(False, False)

    frame = ttk.Frame(guide_window)
    frame.pack(expand=True, fill='both', padx=20, pady=20)

    guide_label = ttk.Label(frame, text="用户指南", font=('Times New Roman', 20, 'bold'))
    guide_label.pack(pady=(0, 10), anchor='center')

    instructions_label = ttk.Label(frame, text="""
    欢迎来到Tkinter版井字棋游戏!

    游戏规则:
    1. 游戏在3x3网格上进行,先手用X,后手用O,双方轮流落子。
    2. 率先将三个相同标记连成一线(横、竖、斜)的玩家获胜。
    3. 若所有格子填满仍无胜者,则游戏平局。
    点击「重置游戏」可重新开始!""",
    font=('Times New Roman', 12))
    instructions_label.pack(anchor='w')

# 主窗口初始化
win = tk.Tk()
win.geometry("1000x600")
win.resizable(False, False)
win.title("井字棋")

# 加载背景图片(路径需正确,加载失败时用纯色背景)
try:
    bg = tk.PhotoImage(file="tictac.png")
    backgroundimage = tk.Label(win, image=bg) 
    backgroundimage.place(x=0, y=0)
except:
    win.config(bg="#f0f0f0")

# 配置按钮样式
tmrn = tkFont.Font(family='Times New Roman', size=15, weight='bold')
style = ttk.Style()
style.configure('tmrn.TButton', font=('Times New Roman', 15, 'bold'), padding=(200, 10))

# 主窗口组件
title_label = ttk.Label(win, text="井字棋游戏!", font=('Times New Roman', 40, 'bold'), foreground='black')
title_label.pack(side=tk.TOP, pady=20)

play_button = ttk.Button(win, text="开始游戏", command=play_game, style='tmrn.TButton')
play_button.place(relx=0.5, rely=0.6, anchor=tk.CENTER)

guide_button = ttk.Button(win, text="用户指南", command=open_user_guide, style='tmrn.TButton')
guide_button.place(relx=0.5, rely=0.7, anchor=tk.CENTER)

win.mainloop()

关键修改说明

  • 全局变量优化:用current_player控制回合,buttons存储按钮实例,确保函数间状态共享。
  • 移除冗余代码:删除无效的全局声明和手动创建的按钮,统一用循环生成棋盘。
  • 点击逻辑完善:检查按钮状态,设置标记后禁用按钮,自动切换回合。
  • 新增重置功能:通过销毁当前游戏窗口并重新调用play_game实现重置。
  • 指南汉化:将用户指南文本改为中文,适配国内用户。

内容的提问来源于stack exchange,提问作者Pei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:23:12