import turtle import random class World: def __init__(self, maxX, maxY): self.maxX = maxX self.maxY = maxY self.thingList = [] self.grid = [] for y in range(maxY): row = [] for x in range(maxX): row.append(None) self.grid.append(row) self.turtle = turtle.Turtle() self.screen = turtle.Screen() self.screen.setworldcoordinates(0, 0, maxX - 1, maxY - 1) self.turtle.hideturtle() def getMaxX(self): return self.maxX def getMaxY(self): return self.maxY def emptyLocation(self, x, y): if self.grid[y][x] == None: return True else: return False def lookAtLocation(self, x, y): return self.grid[y][x] def addThing(self, thing, x, y): thing.setX(x) thing.setY(y) self.grid[y][x] = thing thing.setWorld(self) self.thingList.append(thing) thing.appear() def deleteThing(self, thing): thing.hide() self.grid[thing.getY()][thing.getX()] = None self.thingList.remove(thing) def moveThing(self, oldX, oldY, newX, newY): self.grid[newY][newX] = self.grid[oldY][oldX] self.grid[oldY][oldX] = None def live(self): if len(self.thingList) > 0: index = random.randrange(0, len(self.thingList)) self.thingList[index].live() def draw(self): self.screen.tracer(0) # draw bounding box self.turtle.forward(self.maxX - 1) self.turtle.left(90) self.turtle.forward(self.maxY - 1) self.turtle.left(90) self.turtle.forward(self.maxX - 1) self.turtle.left(90) self.turtle.forward(self.maxY - 1) self.turtle.left(90) # draw horizontal lines for y in range(self.maxY - 1): self.turtle.forward(self.maxX - 1) self.turtle.backward(self.maxX - 1) self.turtle.left(90) self.turtle.forward(1) self.turtle.right(90) self.turtle.forward(1) self.turtle.right(90) # draw vertical lines for x in range(self.maxX - 2): self.turtle.forward(self.maxY - 1) self.turtle.backward(self.maxY - 1) self.turtle.left(90) self.turtle.forward(1) self.turtle.right(90) self.screen.tracer(1) class Creature: def __init__(self): self.turtle = turtle.Turtle() self.turtle.up() self.turtle.hideturtle() self.x = 0 self.y = 0 self.world = None self.breedTick = 0 def setX(self,x): self.x = x def setY(self,y): self.y = y def getX(self): return self.x def getY(self): return self.y def setWorld(self,world): self.world = world def appear(self): self.turtle.goto(self.x, self.y) self.turtle.showturtle() def hide(self): self.turtle.hideturtle() def move(self,newX,newY): self.world.moveThing(self.x,self.y,newX,newY) self.x = newX self.y = newY self.turtle.goto(self.x, self.y) def live(self): print("ERROR: You must define live in the subclass") def tryToBreed(self, LifeForm): x = self.x y = self.y offsets = [(-1,1), (0,1), (1,1), (-1,0), (1,0), (-1,-1), (0,-1), (1,-1)] offset = random.choice(offsets) newX = offset[0] + x newY = offset[1] + y while newX < 0 or newX >= self.world.getMaxX() or newY < 0 or newY >= self.world.getMaxY(): offset = random.choice(offsets) newX = offset[0] + x newY = offset[1] + y if self.world.emptyLocation(newX, newY): child = LifeForm() self.world.addThing(child, newX, newY) self.breedTick = 0 def tryToMove(self): x = self.x y = self.y offsets = [(-1,1), (0,1), (1,1), (-1,0), (1,0), (-1,-1), (0,-1), (1,-1)] offset = random.choice(offsets) newX = offset[0] + x newY = offset[1] + y while newX < 0 or newX >= self.world.getMaxX() or newY < 0 or newY >= self.world.getMaxY(): offset = random.choice(offsets) newX = offset[0] + x newY = offset[1] + y if self.world.emptyLocation(newX, newY): self.move(newX, newY) def tryToEat(self): print("ERROR: You must define tryToEat in the subclass") class Fish(Creature): def __init__(self): super().__init__() self.turtle.shape('triangle') self.turtle.color('blue') self.starveTick = 0 def live(self): offsets = [(-1,1), (0,1), (1,1), (-1,0), (1,0), (-1,-1), (0,-1), (1,-1)] count = 0 x = self.x y = self.y for offset in offsets: newX = offset[0] + x newY = offset[1] + y if newX >= 0 and newY >= 0 and newX < self.world.getMaxX() and newY < self.world.getMaxY(): if not self.world.emptyLocation(newX, newY) and isinstance(self.world.lookAtLocation(newX, newY), Fish): count += 1 self.tryToEat() if count >= 2: self.world.deleteThing(self) else: self.breedTick += 1 if self.breedTick >= 12: self.tryToBreed(Fish) self.tryToMove() def tryToEat(self): offsets = [(-1,1), (0,1), (1,1), (-1,0), (1,0), (-1,-1), (0,-1), (1,-1)] prey = [] x = self.x y = self.y for offset in offsets: newX = offset[0] + x newY = offset[1] + y if newX >= 0 and newY >= 0 and newX < self.world.getMaxX() and newY < self.world.getMaxY(): if not self.world.emptyLocation(newX, newY) and isinstance(self.world.lookAtLocation(newX, newY), Plant): prey.append(self.world.lookAtLocation(newX, newY)) if len(prey) > 0: plant = random.choice(prey) self.world.deleteThing(plant) self.move(plant.getX(), plant.getY()) self.starveTick = 0 else: self.starveTick += 1 class Bear(Creature): def __init__(self): super().__init__() self.turtle.shape('square') self.turtle.color('brown') self.starveTick = 0 def live(self): self.breedTick += 1 if self.breedTick >= 8: self.tryToBreed(Bear) self.tryToEat() if self.starveTick >= 10: self.world.deleteThing(self) else: self.tryToMove() def tryToEat(self): offsets = [(-1,1), (0,1), (1,1), (-1,0), (1,0), (-1,-1), (0,-1), (1,-1)] prey = [] x = self.x y = self.y for offset in offsets: newX = offset[0] + x newY = offset[1] + y if newX >= 0 and newY >= 0 and newX < self.world.getMaxX() and newY < self.world.getMaxY(): if not self.world.emptyLocation(newX, newY) and isinstance(self.world.lookAtLocation(newX, newY), Fish): prey.append(self.world.lookAtLocation(newX, newY)) if len(prey) > 0: fish = random.choice(prey) self.world.deleteThing(fish) self.move(fish.getX(), fish.getY()) self.starveTick = 0 else: self.starveTick += 1 class Plant(Creature): def __init__(self): super().__init__() self.turtle.shape('circle') self.turtle.color('green') def live(self): self.breedTick = self.breedTick + 1 if self.breedTick >= 5: self.tryToBreed(Plant) bearCount = 1 fishCount = 25 plantCount = 20 worldLife = 2500 width = 8 height = 8 world = World(width, height) world.draw() for i in range(fishCount): fish = Fish() x = random.randrange(width) y = random.randrange(height) while not world.emptyLocation(x, y): x = random.randrange(width) y = random.randrange(height) world.addThing(fish, x, y) for i in range(bearCount): bear = Bear() x = random.randrange(width) y = random.randrange(height) while not world.emptyLocation(x, y): x = random.randrange(width) y = random.randrange(height) world.addThing(bear, x, y) for i in range(plantCount): plant = Plant() x = random.randrange(width) y = random.randrange(height) while not world.emptyLocation(x, y): x = random.randrange(width) y = random.randrange(height) world.addThing(plant, x, y) for i in range(worldLife): world.live()