如何为醉酒散步创建一个围栏​​场

How to create a fenced field for the drunken walk

我买了一本 John V. Guttag 的 Python 简介,我正在尝试自学 python。大部分情况下进展顺利,但我有一个问题在书中没有讨论。最新的部分谈到了druken步行模拟。在模拟中它使用一个字段 class 来创建供醉汉行走的字段。然后他使用继承创建另一种字段。我想知道如何在田野上建一个围栏​​,以限制醉酒者走到边缘,然后醉酒者不得不转身。这是字段代码:

class Field(object):
    def __init__(self):
        self.drunks = {}

    def addDrunk(self, drunk, loc):
        if drunk in self.drunks:
            raise ValueError('Duplicate drunk')
        else:
            self.drunks[drunk] = loc

    def moveDrunk(self, drunk):
        if drunk not in self.drunks:
            raise ValueError('Drunk not in field')
        xDist, yDist = drunk.takeStep()
        currentLocation = self.drunks[drunk]
        #use move method of Location to get new location
        self.drunks[drunk] = currentLocation.move(xDist, yDist)

    def getLoc(self, drunk):
        if drunk not in self.drunks:
            raise ValueError('Drunk not in field')
        return self.drunks[drunk]

这是他使用继承创建的另一个字段:

class oddField(Field):
    def __init__(self, numHoles, xRange, yRange):
        Field.__init__(self)
        self.wormholes = {}
        for w in range(numHoles):
            x = random.randint(-xRange, xRange)
            y = random.randint(-yRange, yRange)
            newX = random.randint(-xRange, xRange)
            newY = random.randint(-yRange, yRange)
            newLoc = Location(newX, newY)
            self.wormholes[(x, y)] = newLoc

    def moveDrunk(self, drunk):
        Field.moveDrunk(self, drunk)
        x = self.drunks[drunk].getX()
        y = self.drunks[drunk].getY()
        if (x, y) in self.wormholes:
            self.drunks[drunk] = self.wormholes[(x, y)]

奇怪的领域用虫洞来移动醉汉,很酷。我对 python 还是个新手,所以我很好奇这是怎么回事。

假设您的问题是关于 OddField 子 class 中的方法 moveDrunk 是如何工作的。

A subclass extends its superclass (这适用于大多数 OO 语言)这里的 OddField class 扩展了 Field class 因为它添加了一个名为 wormholes 的 属性,并且还覆盖了 superclass' moveDrunk 方法,这意味着它为它提供了一个新的实现。

subclass 现在拥有其 superclass 的所有成员,但有一个新的 属性 以及更相关的 moveDrunk 的更自定义的实现到子class.

所以我们知道 subclass OddField 可以像普通字段一样工作,但它具有来自 OddField 实现的额外行为。因此,如果我们在 OddField 上调用 moveDrunk 方法,它将实现新的行为,而不是我们的 superclass.

中的行为

但是,如果你的问题是关于虫洞是如何工作的,很抱歉,我帮不了你。 ;)

简单地覆盖 moveDrunk() 方法的逻辑,这样如果坐标超出您想要的笛卡尔 space,醉汉将留在栅栏内,并且还覆盖初始化以提供受限制的笛卡尔 space。考虑以下伪代码:

class斯蒂芬代达罗斯(场):</p> <p>def <strong>init</strong>(self, cartesianSpace): Field.init(自己) self.fence = 笛卡尔空间 ... def moveDrunk(自我): '''Note where our drunk is located, as he may do something impossible''' lastX = self.drunks[醉].getX() lastY = self.drunks[喝醉].getY() Field.moveDrunk(自己,喝醉了) x = self.drunks[喝醉].getX() y = self.drunks[喝醉].getY() '''check that our drunk is still within parameters''' 如果 self.cartesianSpace.points 中的 (x, y): self.drunks[喝醉] = currentLocation.move(x, y) '''and if he is not, he will stumble back to the old manifold''' 别的: self.drunks[喝醉] = currentLocation.move(lastX, lastY)

你必须实现 CartesianField class,但如果你从数学上考虑这个问题,你可能会想要接受一个点列表,然后用该字段中的整数点填充另一个列表由列表分隔。对新程序员来说是一个有趣的挑战。考虑使用 Python 的矩形 class 来避免欧几里德式的头痛:

https://wiki.python.org/moin/PointsAndRectangles