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

Python Tkinter战舰游戏完成玩家2回合后无法切回玩家1求助

战舰游戏界面切换问题解决方案

问题根源

  1. 界面组件未隐藏:切换玩家界面时,未将当前显示的棋盘按钮隐藏,导致新界面按钮被旧按钮覆盖,视觉上无法完成切换。
  2. 按钮列表创建冗余:buttons1和buttons2的创建多了一层for i in range(2)循环,生成了20行按钮(远超棋盘需要的10行),属于无效代码且易引发逻辑混乱。
  3. 重复创建next按钮:每次切换界面都会新建一个next按钮,旧按钮仍存在于界面中,可能导致事件冲突或视觉遮挡。

修复后的代码

import tkinter as tk
import random

window = tk.Tk()

ship_sizes = [5,4,3,2,2]
board_size = 10

# 初始化玩家棋盘
board1 = [[0 for _ in range(board_size)] for _ in range(board_size)]
board2 = [[0 for _ in range(board_size)] for _ in range(board_size)]

# 为玩家1随机放置战舰
for ship in ship_sizes:
    while True:
        x = random.randint(0, board_size-1)
        y = random.randint(0, board_size-1)
        orien = random.choice(['hor','vert'])
        if orien == 'hor' and x + ship <= board_size:
            valid = all(board1[x+i][y] == 0 for i in range(ship))
            if valid:
                for i in range(ship):
                    board1[x+i][y] = ship
                break
        elif orien == 'vert' and y + ship <= board_size:
            valid = all(board1[x][y+i] == 0 for i in range(ship))
            if valid:
                for i in range(ship):
                    board1[x][y+i] = ship
                break

# 为玩家2随机放置战舰
for ship in ship_sizes:
    while True:
        x = random.randint(0, board_size-1)
        y = random.randint(0, board_size-1)
        orien = random.choice(['hor','vert'])
        if orien == 'hor' and x + ship <= board_size:
            valid = all(board2[x+i][y] == 0 for i in range(ship))
            if valid:
                for i in range(ship):
                    board2[x+i][y] = ship
                break
        elif orien == 'vert' and y + ship <= board_size:
            valid = all(board2[x][y+i] == 0 for i in range(ship))
            if valid:
                for i in range(ship):
                    board2[x][y+i] = ship
                break

def button_click1(x,y):
    if board1[x][y] == 0:
        buttons1[x][y].config(text="Miss", bg="white")
    else:
        buttons1[x][y].config(text="Hit", bg="darkkhaki")
        # 标记已击中,防止重复点击
        board1[x][y] = 1

def button_click2(x,y):
    if board2[x][y] == 0:
        buttons2[x][y].config(text="Miss", bg="white")
    else:
        buttons2[x][y].config(text="Hit", bg="darkkhaki")
        # 标记已击中,防止重复点击
        board2[x][y] = 1

# 创建玩家1的棋盘按钮(修复循环冗余)
buttons1 = []
for j in range(board_size):
    row = []
    for k in range(board_size):
        button = tk.Button(master=window, text="", bg="deepskyblue", width=2, height=1,
                           command=lambda x=j, y=k: button_click1(x, y))
        row.append(button)
    buttons1.append(row)

# 创建玩家2的棋盘按钮(修复循环冗余)
buttons2 = []
for j in range(board_size):
    row = []
    for k in range(board_size):
        button = tk.Button(master=window, text="", bg="deepskyblue", width=2, height=1,
                           command=lambda x=j, y=k: button_click2(x, y))
        row.append(button)
    buttons2.append(row)

# 全局next按钮,避免重复创建
next_btn = None

def hide_all_boards():
    # 隐藏玩家1和玩家2的所有按钮
    for i in range(board_size):
        for j in range(board_size):
            buttons1[i][j].grid_forget()
            buttons2[i][j].grid_forget()
    # 隐藏之前的next按钮
    global next_btn
    if next_btn:
        next_btn.grid_forget()

def frame1():
    hide_all_boards()
    # 显示玩家1的棋盘
    for i in range(board_size):
        for j in range(board_size):
            buttons1[i][j].grid(row=i, column=j)
    # 创建/显示next按钮
    global next_btn
    next_btn = tk.Button(master=window, text="next", bg="green", width=5, height=2, command=frame2)
    next_btn.grid(row=11, column=11)

def frame2():
    hide_all_boards()
    # 显示玩家2的棋盘
    for i in range(board_size):
        for j in range(board_size):
            buttons2[i][j].grid(row=i, column=j)
    # 创建/显示next按钮
    global next_btn
    next_btn = tk.Button(master=window, text="next", bg="green", width=5, height=2, command=frame1)
    next_btn.grid(row=11, column=11)

frame1()
window.mainloop()

关键修改点

  • 新增hide_all_boards函数:切换界面时先隐藏所有棋盘按钮和旧的next按钮,彻底避免组件重叠问题。
  • 修复按钮列表创建循环:移除多余的for i in range(2)循环,确保buttons1和buttons2仅生成10行(匹配棋盘尺寸)。
  • 全局next按钮管理:将next按钮设为全局变量,每次切换时先隐藏旧按钮再创建新的,避免重复创建引发的冲突。
  • 优化点击逻辑:击中后将棋盘对应位置设为1,防止重复点击同一位置时重复触发状态变化,同时简化了原代码中冗余的按钮属性设置操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:07:34