如何在Python迷宫中移动老鼠

时间:2013-05-01 21:27:22

标签: python list move messages maze

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

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

2 个答案:

答案 0 :(得分:1)

执行Maze.content[row][col]时,python会查找名为rowcol的变量,并尝试将它们用作Maze.content的索引。由于row(和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 在生成器表达式中被赋值。 (事实上​​,它被分配了多个值,每次迭代都有不同的值)

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

首先,你将第一个参数称为什么并不重要。你可以轻松地做到:

def set_location(balloons, row, col):

    balloons.row = row
    balloons.col = col

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

然而

按惯例,该参数称为self。您应该将其称为self,以便保持代码清晰。

那么,为什么不像我一直在做的那样称呼它为MazeRat 首先,因为它令人困惑。您实际上并没有在任何方法中引用 MazeRat,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)

没有达到你的预期。

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

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

祝你好运。