假设我有一个类Game
来玩游戏。一旦游戏结束,我想立即开始新游戏。我认为这可能通过在其自己的类定义中实例化新的Game()
以递归方式实现。这可能吗?
举一个具体的例子,我使用Tkinter用GUI编写Tic Tac Toe游戏:
import numpy as np
import Tkinter as tk
class Game:
def __init__(self, master, player1, player2):
frame = tk.Frame()
frame.grid()
self.master = master
self.player1 = player1
self.player2 = player2
self.current_player = player1
self.empty_text = ""
self.board = Board()
self.buttons = [[None for _ in range(3)] for _ in range(3)]
for i in range(3):
for j in range(3):
self.buttons[i][j] = tk.Button(frame, height=3, width=3, text=self.empty_text, command=lambda i=i, j=j: self.callback(self.buttons[i][j]))
self.buttons[i][j].grid(row=i, column=j)
self.reset_button = tk.Button(text="Reset", command=self.reset)
self.reset_button.grid(row=3)
def callback(self, button):
if button["text"] == self.empty_text:
button.configure(text=self.current_player.mark)
info = button.grid_info()
move = (info["row"], info["column"])
self.board.place_mark(move, self.current_player.mark)
if self.board.over():
print "The game is over. The player with mark %s won!" % self.current_player.mark
self.master.quit()
else:
self.switch_players()
def reset(self):
print "Resetting..."
self.master.destroy()
self = Game(self.master, self.player1, self.player2)
def switch_players(self):
if self.current_player == self.player1:
self.current_player = self.player2
else:
self.current_player = self.player1
class Board:
def __init__(self, grid=np.ones((3,3))*np.nan):
self.grid = grid
def winner(self):
rows = [self.grid[i,:] for i in range(3)]
cols = [self.grid[:,j] for j in range(3)]
diag = [np.array([self.grid[i,i] for i in range(3)])]
cross_diag = [np.array([self.grid[2-i,i] for i in range(3)])]
lanes = np.concatenate((rows, cols, diag, cross_diag)) # A "lane" is defined as a row, column, diagonal, or cross-diagonal
any_lane = lambda x: any([np.array_equal(lane, x) for lane in lanes]) # Returns true if any lane is equal to the input argument "x"
if any_lane(np.ones(3)):
return 1
elif any_lane(np.zeros(3)):
return 0
def over(self):
return (not np.any(np.isnan(self.grid))) or (self.winner() is not None)
def place_mark(self, pos, mark):
num = self.mark2num(mark)
self.grid[tuple(pos)] = num
def mark2num(self, mark):
if mark == "X":
return 1
elif mark == "O":
return 0
else:
print "The player's mark must be either 'X' or 'O'."
class HumanPlayer:
def __init__(self, mark):
self.mark = mark
root = tk.Tk()
app = Game(root, player1=HumanPlayer(mark="X"), player2=HumanPlayer(mark="O"))
root.mainloop()
我第一次玩游戏时一切都很顺利:按钮标签按预期更改并宣布获胜者(见下文)。
问题在于当我按下"重置"按钮,虽然我再次得到一个空白的GUI,Game
仍然认为'结束并继续打印获胜者的声明:
是否可以重新初始化'该类没有将每个属性重置为其初始值?
答案 0 :(得分:0)
最后,我只是做了一本手册'重置相关属性而不是重新实例化'班级。以下是生成的代码:
import numpy as np
import Tkinter as tk
class Game:
def __init__(self, master, player1, player2):
frame = tk.Frame()
frame.grid()
self.master = master
self.player1 = player1
self.player2 = player2
self.current_player = player1
self.empty_text = ""
self.board = Board()
self.buttons = [[None for _ in range(3)] for _ in range(3)]
for i in range(3):
for j in range(3):
self.buttons[i][j] = tk.Button(frame, height=3, width=3, text=self.empty_text, command=lambda i=i, j=j: self.callback(self.buttons[i][j]))
self.buttons[i][j].grid(row=i, column=j)
self.reset_button = tk.Button(text="Reset", command=self.reset)
self.reset_button.grid(row=3, column=0)
self.quit_button = tk.Button(text="Quit", command=self.quit)
# self.quit_button.grid(row=3, column=1)
self.setup_UI()
def setup_UI(self):
self.master.title="Tic Tac Toe"
def callback(self, button):
if self.board.over():
pass
elif button["text"] == self.empty_text:
button.configure(text=self.current_player.mark)
info = button.grid_info()
move = (info["row"], info["column"])
self.board.place_mark(move, self.current_player.mark)
if self.board.over():
print "The game is over. The player with mark %s won!" % self.current_player.mark
else:
self.switch_players()
def reset(self):
print "Resetting..."
for i in range(3):
for j in range(3):
self.buttons[i][j].configure(text=self.empty_text)
self.board = Board(grid=np.ones((3,3))*np.nan)
self.current_player = self.player1
def quit(self):
self.master.destroy()
def switch_players(self):
if self.current_player == self.player1:
self.current_player = self.player2
else:
self.current_player = self.player1
class Board:
def __init__(self, grid=np.ones((3,3))*np.nan):
self.grid = grid
def winner(self):
rows = [self.grid[i,:] for i in range(3)]
cols = [self.grid[:,j] for j in range(3)]
diag = [np.array([self.grid[i,i] for i in range(3)])]
cross_diag = [np.array([self.grid[2-i,i] for i in range(3)])]
lanes = np.concatenate((rows, cols, diag, cross_diag)) # A "lane" is defined as a row, column, diagonal, or cross-diagonal
any_lane = lambda x: any([np.array_equal(lane, x) for lane in lanes]) # Returns true if any lane is equal to the input argument "x"
if any_lane(np.ones(3)):
return 1
elif any_lane(np.zeros(3)):
return 0
def over(self):
return (not np.any(np.isnan(self.grid))) or (self.winner() is not None)
def place_mark(self, pos, mark):
num = self.mark2num(mark)
self.grid[tuple(pos)] = num
def mark2num(self, mark):
if mark == "X":
return 1
elif mark == "O":
return 0
else:
print "The player's mark must be either 'X' or 'O'."
class HumanPlayer:
def __init__(self, mark):
self.mark = mark
root = tk.Tk()
root.title("Tic Tac Toe")
app = Game(root, player1=HumanPlayer(mark="X"), player2=HumanPlayer(mark="O"))
root.mainloop()
下面的屏幕抓点显示了我多次设法玩Tic Tac Toe。