0

我对 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

class Maze: """ 一个 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
>>> 

请帮我修复错误信息并将老鼠移动到迷宫中的任何一点(只要它在走廊里)!

4

2 回答 2

1

当你这样做时Maze.content[row][col],python 会查找名为rowand的变量,col并尝试将它们用作Maze.content. 由于row(and col) 没有在 中定义move(),而且它们也没有在全局范围内定义,python 抛出一个NameError.

不过还有一个问题。即使设置row = someNumbercol = 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 被赋值。(实际上它被分配了多个值,每次迭代都有一个不同的值)

关于使用MazeorRat作为self参数的说明:

首先,调用第一个参数实际上并不重要。你可以很容易地做到:

def set_location(balloons, row, col):

    balloons.row = row
    balloons.col = col

这是因为 python 将类实例作为第一个参数传递。您在此处键入的名称只是一个变量名称,以便您可以在该特定方法中引用它。

然而

该参数self按约定调用。您应该调用它self以保持代码清晰。

好吧,为什么不叫它Maze或者Rat,就像我一直在做的那样? 首先,因为它令人困惑。您实际上并没有指代 MazeRat任何方法的内部,python 将这些名称分配给类 instance。有人(包括您自己)稍后可能会阅读您的代码,并认为您指的是类而不是实例。

其次,因为它覆盖了该方法中的类名。如果您真的想在该方法中引用该类怎么办?你不能,因为你用你名字不好的参数覆盖了那个名字。

于 2013-05-01T21:50:20.537 回答
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 约定,你不妨像其他人一样学习它。因此,例如,您的 move 方法将定义如下:

    def move(self, Rat, hor, ver):

然后,在 move 方法中,要引用类变量,例如内容,您可以使用self.content.

您也不应该使用类名作为函数的参数。虽然这在 Python 中是合法的,但它是一种有点先进的技术,我猜这不是你想要的。因此,move 方法最好定义为:

def move(self, rat, hor, ver):

然后,您将使用rat(小写 r) 而不是Rat在您的 move 方法中引用 rat 参数。

  • 不要在 move 方法中重新分配常量。您定义了各种常量,例如 WALL、HALL、SPROUT、LEFT、RIGHT 等。如果您打算将这些用作全局常量(我认为您会这样做),那么您永远不会在赋值的左侧使用它们陈述。因此,例如,声明

    UP = Rat.set_location(row,col+1)

不符合您的预期。

  • 为每个函数添加一些注释以指示它在做什么以及每个参数的作用是一个好主意。这将迫使你思考你想要完​​成什么。因此,在记录 move 方法时,问问自己“hor”和“ver”参数的用途。它们是否表明老鼠将移动的距离?或者,它们是否指示了老鼠将要移动到的绝对坐标?

我会在这里停下来,让你做更多的调查。我知道这很痛苦,但我们经常通过奋斗学习到最好的东西。

祝你好运。

于 2013-05-01T22:30:50.787 回答