[Edu-sig] A simple simulation
Kirby Urner
pdx4d@teleport.com
Tue, 04 Apr 2000 16:58:42 -0700
Greetings Python fans --
Took me a an hour or more to throw this together: a simple
simulation. Ducks, Wolves and Bugs are all subclasses of
creature with a favorite food (Wolves eat Ducks eat Bugs
eat each other).
Every clock cycle triggers a random happening in the life
of each creature. It either: gives birth, hunts (finds
favorite food or goes hungry), or dies. Pretty simple.
Too simple of course. For one thing, solo creatures of
these types can't auto-reproduce (well, maybe some bugs...).
I should add a "find mate" algorithm similar to the "hunt"
one (only randomly successful). If we're down to only
one of a kind, no more offspring.
Assigning the attribute male/female at random and only
letting opposites mate would require yet more lines of code
(but not many). Then there's age to think about. So
many ways to make this more "realistic".
And what about the environment, what about pollution
and global warming? Some bugs might _like_ global warming.
But still, as a "cave painting", we're already well on
the way to sketching what simulations are about. Re
"cave paintings" see:
http://www.python.org/pipermail/edu-sig/2000-February/000154.html
Here's what it looks like when running:
>>> import simula
>>> simula.run(4)
>>> --- Initialize -------
Duck1 is born
Duck2 is born
Bug1 is born
Bug2 is born
Wolf1 is born
--- Tick 0 -------
Bug1 gives birth
Bug3 is born
Duck2 gives birth
Duck3 is born
Bug1 gets eaten by Duck1
Bug1 dies
Bug2 dies
Wolf1 gives birth
Wolf2 is born
--- Tick 1 -------
Duck2 dies
Duck1 goes hungry
Duck1 gets eaten by Wolf2
Duck1 dies
Duck3 goes hungry
Wolf1 gives birth
Wolf3 is born
Bug3 dies
--- Tick 2 -------
Wolf2 gives birth
Wolf4 is born
Wolf3 dies
Duck3 goes hungry
Duck3 gets eaten by Wolf1
Duck3 dies
--- Tick 3 -------
Wolf2 dies
Wolf1 dies
Wolf4 gives birth
Wolf5 is born
Here's the source code (simula.py module):
# primitive simulation
# by kirby urner
# oregon curriculum network
# april 4, 2000
import copy, random
creatures = {}
counter = {}
def run(n):
setstage()
for j in range(n): # time spans
print "--- Tick %s -------" % j
for i in creatures.values():
i.randevent()
def setstage():
print "--- Initialize -------"
Duck()
Duck()
Bug()
Bug()
Wolf()
class Creature:
def __init__(self):
self.isborn()
def isborn(self):
species = self.__class__.__name__
if not counter.has_key(species):
counter[species]=0
counter[species] = counter[species] + 1
self.name = species + str(counter[species])
creatures[self.name] = self
print self.name + " is born"
self.stomach = 3 # gets an initial boost (thanks mom!)
def reproduces(self):
print self.name + " gives birth"
species = self.__class__.__name__
newobj = copy.copy(self) # conceived
newobj.isborn() # Hello World!
def dies(self):
print self.name + " dies"
del creatures[self.name] # Goodbye World!
self = None
def hunts(self):
mealfound = 0
for i in range(3): # three chances to find favorite food
gotcha = random.choice(creatures.values())
if (gotcha.__class__.__name__ == self.favoritefood
and not (gotcha.name == self.name)): # can't eat self
mealfound = 1
self.stomach = self.stomach + 1
print gotcha.name + " gets eaten by " + self.name
gotcha.dies()
break
if not mealfound: # didn't find food this time
self.stomach = self.stomach - 1
print self.name + " goes hungry"
if self.stomach == 0: # 3 strikes and you're out
print self.name + " starves"
self.die()
def randevent(self):
event = random.choice(range(3)) # reproduce, hunt
if event == 0: self.reproduces()
elif event == 1: self.hunts()
else: self.dies() # ... or die
class Duck(Creature):
favoritefood = 'Bug'
class Wolf(Creature):
favoritefood = 'Duck'
class Bug(Creature):
favoritefood = 'Bug'