1

我正在尝试使用 Tkinter 在 Python 中创建一个基本的 Battleship 游戏。

下面是我的代码的一个非常简化的版本。本质上,我正在创建一个 10*10 的按钮网格并使用.grid. 我想做的是单击其中一个按钮并将该按钮的网格值(x,y)从GameBoard类传递给Battleship类以定位船。

我试过使用self.row = rowand self.column = column,但是当我这样做时,我立即收到一个属性错误,'GameBoard' object has no attribute 'row'.

import tkinter as tk

class GameBoard:
    def __init__(self):
        self.mw = tk.Tk()
        self.size = 10

    def build_grid(self):
        for x in range(self.size):
            for y in range(self.size):
                self.button = tk.Button(self.mw, text = '', width = 2, height = 1,\
                command = lambda row = x, column = y: self.clicked(row, column))
                self.button.grid(row = x, column = y)
            
    def clicked(self, row, column):
        print(row, column)
        self.row = row
        self.column = column

class Battleship:
    def __init__(self, board):
        self.gboard = board

    def position_ship(self):
        x = self.gboard.row
        y = self.gboard.column
        for i in range (3):
            self.submarine = tk.Button(self.gboard.mw, background = "black", text = '',\
                                   width = 2, height = 1)
            self.submarine.grid(row = x, column = y)
              
def main():
    gboard = GameBoard()
    gboard.build_grid()
    bt = Battleship(gboard)
    bt.position_ship()    
main()
4

1 回答 1

0

正如@acw1668 在评论中指出的那样,问题在于gboard属性row,并且在您调用函数column时尚未创建。bt.position_ship()main()

我不知道你的整体游戏设计,但解决这个问题的一个非常简单的方法是在GameBoard.__init__()方法中为它们分配一个随机的棋盘位置。

我还修改了代码以显示bt.position_ship()单击按钮时如何调用。这是通过将BattleShip实例传递btbuild_grid()函数来完成的,因此它可以包含在对该方法的调用中,该clicked()方法现在可以在调用它时调用它。

from random import randrange
import tkinter as tk

class GameBoard:
    def __init__(self):
        self.mw = tk.Tk()
        self.size = 10
        self.row = randrange(self.size)
        self.column = randrange(self.size)

    def build_grid(self, bt):
        for x in range(self.size):
            for y in range(self.size):
                self.button = tk.Button(self.mw, text='', width=2, height=1,
                                        command=lambda row=x, column=y:
                                            self.clicked(bt, row, column))
                self.button.grid(row=x, column=y)

    def clicked(self, bt, row, column):
        print(row, column)
        self.row = row
        self.column = column
        bt.position_ship()


class Battleship:
    def __init__(self, board):
        self.gboard = board

    def position_ship(self):
        x = self.gboard.row
        y = self.gboard.column
        for i in range (3):
            self.submarine = tk.Button(self.gboard.mw, background="black", text='',
                                       width=2, height=1)
            self.submarine.grid(row=x, column=y)


def main():
    gboard = GameBoard()
    bt = Battleship(gboard)
    gboard.build_grid(bt)
    bt.position_ship()
    tk.mainloop()

main()
于 2021-12-16T12:34:51.167 回答