我是Python的新手,我正在尝试做一个迷宫中的老鼠尝试吃布鲁塞尔豆芽的游戏 - 所以我有2只老鼠 - 'J'和'P'以及2类 - 鼠和迷宫。到目前为止,Rat课程的所有功能都工作 - 而且我被困在Maze课程的最后一个!两个类都交织在一起。我在修复Maze类的move方法时遇到问题 - 以下是两个类。
# The visual representation of a wall.
WALL = '#'
# The visual representation of a hallway.
HALL = '.'
# The visual representation of a brussels sprout.
SPROUT = '@'
# Constants for the directions. Use these to make Rats move.
# The left direction.
LEFT = -1
# The right direction.
RIGHT = 1
# No change in direction.
NO_CHANGE = 0
# The up direction.
UP = -1
# The down direction.
DOWN = 1
# The letters for rat_1 and rat_2 in the maze.
RAT_1_CHAR = 'J'
RAT_2_CHAR = 'P'
num_sprouts_eaten = 0
class Rat:
""" A rat caught in a maze. """
# Write your Rat methods here.
def __init__(Rat, symbol, row, col):
Rat.symbol = symbol
Rat.row = row
Rat.col = col
num_sprouts_eaten = 0
def set_location(Rat, row, col):
Rat.row = row
Rat.col = col
def eat_sprout(Rat):
num_sprouts_eaten += 1
def __str__(Rat):
""" (Contact) -> str
Return a string representation of this contact.
"""
result = ''
result = result + '{0} '.format(Rat.symbol) + 'at '
result = result + '('+ '{0}'.format(Rat.row) + ', '
result = result + '{0}'.format(Rat.col) + ') ate '
result = result + str(num_sprouts_eaten) + ' sprouts.'
return result
课堂迷宫:
“”一个2D迷宫。“”“
def __init__(Maze, content, rat_1, rat_2):
Maze.content= content
Maze.rat_1 = RAT_1_CHAR
Maze.rat_2 = RAT_2_CHAR
def is_wall(Maze, row,col):
return (Maze.content[row][col] == '#')
def get_character(Maze,row, col):
chars = ''
if 'J' in Maze.content[row][col]:
chars = 'J'
elif 'P' in Maze.content[row][col]:
chars = 'P'
elif '#' in Maze.content[row][col]:
chars = WALL
else:
chars = HALL
return chars
def move(Maze, Rat, hor, ver):
num_sprouts_left = sum(x.count('@') for x in Maze.content[row][col])
nowalls = False
if Rat in Maze.content[row][col] and Maze.is_wall(row, col) == True:
NO_CHANGE = Rat.set_location(row+0,col+0)
if Rat in Maze.content[row][col] and Maze.is_wall(row, col) == False:
UP = Rat.set_location(row,col+1)
if UP == SPROUT:
Rat.eat_sprout(Rat)
num_sprouts_left -= 1
SPROUT=HALL
if Rat in Maze.content[row][col] and Maze.is_wall(row, col) == False:
DOWN = Rat.set_location(row,col-1)
if DOWN == SPROUT:
Rat.eat_sprout(Rat)
num_sprouts_left -= 1
SPROUT=HALL
if Rat in Maze.content[row][col] and Maze.is_wall(row, col) == False:
LEFT = Rat.set_location(row-1,col)
if LEFT == SPROUT:
Rat.eat_sprout(Rat)
num_sprouts_left -= 1
SPROUT=HALL
if Rat in Maze.content[row][col] and Maze.is_wall(row, col) == False:
RIGHT = Rat.set_location(row+1,col)
if RIGHT == SPROUT:
Rat.eat_sprout(Rat)
num_sprouts_left -= 1
SPROUT=HALL
nowalls = True
return nowalls
所以当我通过Maze对象调用move方法时 - 我收到一条错误消息!
>>> d = Maze([['#', '#', '#', '#', '#', '#', '#'],
['#', '.', '.', '.', '.', '.', '#'],
['#', '.', '#', '#', '#', '.', '#'],
['#', '.', '.', '@', '#', '.', '#'],
['#', '@', '#', '.', '@', '.', '#'],
['#', '#', '#', '#', '#', '#', '#']],
Rat('J', 1, 1),
Rat('P', 1, 4))
>>> d.move('J',2,2)
Traceback (most recent call last):
File "<pyshell#167>", line 1, in <module>
d.move('J',2,2)
File "C:\Users\gijoe\Downloads\a2.py", line 96, in move
num_sprouts_left = sum(x.count('@') for x in Maze.content[row][col])
NameError: global name 'row' is not defined
>>>
请帮我修复错误信息并将鼠标移动到迷宫中的任何一点(只要它在走廊里)!
答案 0 :(得分:1)
执行Maze.content[row][col]
时,python会查找名为row
和col
的变量,并尝试将它们用作Maze.content
的索引。由于row
(和col
)未在move()
中定义,并且由于它们也未在全局定义,因此python会抛出NameError
。
但还有一个问题。即使如果您在该行之前设置了row = someNumber
和col = someOtherNumber
,您仍然无法获得预期的结果。
调用Maze.content[row][col]
将返回长度为1的字符串。 (值为“#”,“@”或“_”)。因此,对该字符串执行x.count(“@”)将返回1或0.由于您对长度为1的字符串进行操作,num_sprouts_left
将只取值1或0。
我假设您希望遍历整个迷宫来计算萌芽的数量。你会这样做:
num_sprouts_left = sum(row.count('@') for row in Maze.content)
在上述情况下,row
在生成器表达式中被赋值。 (事实上,它被分配了多个值,每次迭代都有不同的值)
Maze
或Rat
作为self
参数的说明:首先,你将第一个参数称为什么并不重要。你可以轻松地做到:
def set_location(balloons, row, col):
balloons.row = row
balloons.col = col
这是因为python将类实例作为第一个参数传递。您在那里输入的名称只是一个变量名称,因此您可以在该特定方法中引用 。
然而
按惯例,该参数称为self
。您应该将其称为self
,以便保持代码清晰。
那么,为什么不像我一直在做的那样称呼它为Maze
或Rat
?
首先,因为它令人困惑。您实际上并没有在任何方法中引用类 Maze
或Rat
,python将这些名称分配给类实例。有人(包括你自己)可能会在以后阅读你的代码并认为你指的是类,而不是实例。
其次,因为它覆盖了该方法中的类名。如果您真的想在该方法中引用该类,该怎么办?你不能,因为你用你名字不好的参数覆盖了那个名字。
答案 1 :(得分:1)
您的计划存在一些问题。我会指出一些主要的,并让你研究它们。在学习Python时,请记住python.org上的Python文档是你的朋友。
您需要为每只老鼠声明Rat对象。您可以按如下方式执行此操作:
JRat = Rat('J', 1, 1)
PRat = Rat('P', 1, 4)
然后,移动“J”老鼠,你会说,d.Move(JRat, 2, 2)
正如Joel所说,每个类方法的第一个参数应该是self。这是一个Python惯例,你也可以像其他人一样学习它。因此,例如,您的移动方法将定义如下:
def move(self, Rat, hor, ver):
然后,在move方法中,要引用类变量(例如内容),可以使用self.content
。
您也不应该使用类名作为函数的参数。虽然这在Python中是合法的,但它是一种稍微先进的技术,我猜这不是你想要的。因此,移动方法可以更好地定义为:
def move(self, rat, hor, ver):
然后你会在移动方法中使用rat
(小写r)而不是Rat
来引用rat参数。
不要在移动方法中重新分配常量。您定义了各种常量,如WALL,HALL,SPROUT,LEFT,RIGHT等。如果您打算将这些常量用作全局常量(我认为您这样做),则永远不会在赋值的左侧使用这些常量。声明。所以,例如,声明
UP = Rat.set_location(row,col+1)
没有达到你的预期。
我会在这里停下来,让你做更多的调查。我知道这很痛苦,但我们经常通过挣扎来学习最好的东西。
祝你好运。