I bought an Introduction to Python book by John V. Guttag and I am trying to teach myself python. It is going decent for the most part, but I have a question that is not talked about in the book. The latest part talked about the druken walk simulation. In the simulation it uses a field class to create the field for the drunk to walk in. He then creates another kind of field using inheritance. I was wondering what it would take to make a fenced in field that would restrict the drunk from going on the edge and then the drunk having to turn around. Here is the field code:
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]
and here is the other field he made using inheritance:
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)]
The odd field uses wormwholes to move the drunk which is pretty cool. I am still new to python so I am curious how this would work.
Simply override the logic of the moveDrunk() method, such that the drunk remains within the fence if the coordinates are outside of your desired Cartesian space, and also override the initialization to provide that restricted Cartesian space. Consider the following pseudocode:
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)
You'll have to implement a CartesianField class, but if you think about this mathematically, you'd like to accept maybe a list of points and then fill another list with the integer points within the field delimited by the list. An interesting challenge for the new programmer. Consider using Python's rectangle class to save yourself the Euclidean headache: