0

我买了一本 John V. Guttag 的 Python 入门书,我正在尝试自学 Python。大部分情况下它都很不错,但我有一个书中没有提到的问题。最新的部分谈到了德鲁肯步行模拟。在模拟中,它使用一个字段类来为醉汉创建一个可以进入的字段。然后他使用继承创建了另一种字段。我想知道如何在场地上制作一个围栏,以限制醉酒者走到边缘,然后醉酒者不得不转身。这是字段代码:

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 新手,所以我很好奇它是如何工作的。

4

2 回答 2

1

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

子类扩展了它的超类(这适用于大多数如果不是所有的 OO 语言),OddField这里的类扩展了 Field 类,因为它添加了一个名为 的属性wormholes,并且还覆盖了超类的moveDrunk方法,这意味着它为它提供了一个新的实现。

子类现在具有其超类的所有成员,但具有一个新属性,并且还有一个moveDrunk与子类更相关的更定制化的实现。

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

但是,如果您的问题是关于虫洞的工作原理,我很抱歉,但我无法帮助您。;)

于 2016-03-28T22:03:17.983 回答
1

只需重写 moveDrunk() 方法的逻辑,这样如果坐标位于所需的笛卡尔空间之外,醉酒者将留在栅栏内,并且还重写初始化以提供受限的笛卡尔空间。考虑以下伪代码:

class stephenDaedalus(Field):

def init(self, cartesianSpace): Field.init(self) self.fence = cartesianSpace ... def moveDrunk(self): '''Note where our drunk is located, as he may do something impossible''' lastX = self.drunks[drunk].getX() lastY = self.drunks[drunk].getY() Field.moveDrunk(self, drunk) x = self.drunks[drunk].getX() y = self.drunks[drunk].getY() '''check that our drunk is still within parameters''' if (x, y) in self.cartesianSpace.points: self.drunks[drunk] = currentLocation.move(x, y) '''and if he is not, he will stumble back to the old manifold''' else: self.drunks[drunk] = currentLocation.move(lastX, lastY)

您必须实现一个 CartesianField 类,但如果您从数学上考虑这一点,您可能希望接受一个点列表,然后用列表分隔的字段内的整数点填充另一个列表。对于新程序员来说是一个有趣的挑战。考虑使用 Python 的 rectangle 类来避免欧几里得头痛:

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

于 2016-03-28T22:11:18.583 回答