【发布时间】:2021-11-30 23:54:50
【问题描述】:
我必须在 Python 中创建一个推箱子游戏,并且我在我的推箱子类中定义了 find_player() 、 complete() 、 get_steps() 和 move() 方法。我需要创建一个 restart() 方法和一个 undo() 方法,但我不知道该怎么做。我找不到存储原始板或以前的板的方法。我尝试在__init__ 中定义另一个板,但它只是用self.__board 更新,而不是保存初始板。我还尝试在__init__ 中列出一个列表,并尝试将每个动作的“棋盘”附加到列表中,但它会更改列表中的每个棋盘。如果有人可以提供帮助,我已附上我的代码。
class Sokoban:
"""Your code here"""
def __init__(self, board):
self.__board = board
self.__original_board = board
self.__steps = 0
self.__last_step = []
self.__position = (0, 0)
def restart(self):
first_board = self.__original[0]
new_board = []
for i in range(len(first_board)):
new_board.append(first_board[i])
print(self.__original)
return Sokoban(self.__original_board)
def undo(self):
return
def main(board):
game = Sokoban(board)
message = 'Press w/a/s/d to move, r to restart, or u to undo'
print(message)
while not game.complete():
print(game)
move = input('Move: ').lower()
while move not in ('w', 'a', 's', 'd', 'r', 'u'):
print('Invalid move.', message)
move = input('Move: ').lower()
if move == 'r':
game.restart()
elif move == 'u':
game.undo()
else:
game.move(move)
print(game)
print(f'Game won in {game.get_steps()} steps!')
test_board = [
['*', '*', '*', '*', '*', '*', '*', '*'],
['*', ' ', ' ', ' ', ' ', ' ', ' ', '*'],
['*', 'P', ' ', '#', ' ', ' ', ' ', '*'],
['*', '*', '*', '*', '*', ' ', '#', '*'],
['*', 'o', ' ', ' ', ' ', ' ', ' ', '*'],
['*', ' ', ' ', ' ', ' ', ' ', 'o', '*'],
['*', '*', '*', '*', '*', '*', '*', '*']
]
main(test_board)
【问题讨论】:
-
不要为变量使用
__前缀。这不是 Pythonic。 -
@AKX,你能详细说明为什么
__不是pythonic吗?你是说this 用例无效? -
名称修改适用于您要将一些名称混合到现有名称空间中,并且您不想意外使用与该名称空间中已有名称相同的名称。它主要用于代理类型(模仿其他类的 API)或混合类型。这些都是相当先进的技术,所以如果您还不了解它们,请不要担心。在任何情况下,你都没有在这里做这些事情。您的变量没有真正需要是私有的。您有像
get_steps这样的方法,只需将__steps设为公共属性,就可以更自然地处理这些方法。 -
@Chris 是的——正如你链接的段落所说,私有字段的 Pythonic 约定是一个下划线。如果有的话,你很少需要隐藏的名称损坏字段。