from random import randrange import struct class Terminate(Exception): pass class Restore(Exception): pass def decision(quest,cond,msg): while True: val = raw_input(quest) if val.lower() == "quit": raise Terminate(quitstrings[randrange(0,len(quitstrings))]) if val.lower() == "save": city.save('pharoh.sav') print "Game saved to file." continue if val.lower() in ("open", "load", "restore"): raise Restore() if val.lower() == "help": print "","","","" print "The Pharoh Simulator - Created by the AFA Verba Project." print "Version 1.16." print "","" print "Type 'help' to show this screen." print "Type 'quit' to shamefully exit." print "Hit Ctrl+D to shamelessly exit." print "Type 'save' to save your current game." print "Type 'load' to restore your old game." print "","","","" print "Just remember before you continue ruling your city:" print "With great power comes great responsibility." print "","","" continue if val.lower() in ("mrcarey", "mr.carey", "mr. carey"): print "Horrors! Why bring him up?!" print "","","","" print "OK. He came to your city and gave you ten thousand wisemen." print "Whether that's a good thing or a bad thing, you'll just have to see!" city.wisemen+=10000 continue if val.lower() == "666": print "That's too evil. Try another number." continue try: val = int(val) if val < 0: print "Please enter a number greater than zero." continue if cond(val): return val print msg except: print "Please enter a number, or 'quit'" quitstrings = [ "Coward!","Game Quitter!","Chicken!"] deathstrings = [ "The survivors revolt and put a poisonous snake in your \ bed; you die.", "The survivors put poison in your drink; you die.", """You were taking a walk in the night, suddenly hands grab your shoulders... your funeral is very small; only your wife is there.""", """You wake up in the middle of the night when you hear your wife scream that the assasins are here. You knew they would come - there was no food. You see a glint in the air, you try to hide but it's to late - you and your wife are buried the next morning.""", "The survivors revolt, you are thrown out of a window.", """The survivors revolt - they starve you, whip you till you're half dead, then chop your head off.""", """You are riding on your horse by a cliff. Suddenly a stone flies through the air and hits your horse. He rears and you fall into the cliff...""", """ There is a war because of the lack of food; half the city is on your side, and the other half is against you; you die fighting.""", """You were murdered by Mr. Carey!""" ] attackers = [ "Assyrians","Nubians","Hittites","Babylonians","Israelites","Americans","Syrians","terrorists","Libyans","Greeks","Carthiginians","Romans" ] class AnnualPlan(object): def __init__(self): self.shrinkage = 0 self.yld = 0 self.promotions = 0 self.enlistments = 0 self.plant = 0 self.req = 0 self.food = 0 self.migration = 0 self.attacks = 0 self.births = 0 self.deaths = 0 class AnnualYield(object): def __str__(self): s = "harvest=%(harvest)d loss=%(loss)d starved=%(starved)d" % self.__dict__ if self.event == City.REVOLT: s += " REVOLT" elif self.event == City.ATTACK: s += " ATTACK" return s class City(object): ATTACK = 1 REVOLT = 2 def __init__(self): print "Pharoh v1.16, Copyright (C) 2007 AFA Verba Project." print "Pharoh comes with ABSOLUTELY NO WARRANTY." print "This is free software, and you are welcome to redistribute it under the GPL licence" print "under certain conditions." print "" print "Type 'help' for information at any time, or 'quit' to exit." print "","","","","","","","" self.grain = 2000 self.people = 500 self.wisemen = 0 self.soldiers = 0 self.turn = 1 self.deaths = 0 def attack(self): print " " print "A neighboring country attacked you..." enemy = self.soldiers + randrange(-25,25) print "They have %d soldiers." % enemy print "You have %d soldiers." % self.soldiers oursurvivors = randrange(10,(self.soldiers-10)) theirsurvivors = randrange(10,(enemy-10)) if oursurvivors > theirsurvivors: print "You defeated the enemy!" print "%d soldiers survived." % oursurvivors self.soldiers = self.soldiers - oursurvivors elif oursurvivors < theirsurvivors: print "The enemy defeated you.",self.people self.deaths = randrange(10,self.people) print "%d peasants were killed." % self.deaths self.wisemen = 0 print "All your wisemen were killed." if oursurvivors+10 < theirsurvivors: raise Terminate("You were executed by the enemy.") elif oursurvivors+10 > theirsurvivors: print "The enemy has graciously saved your life." def status(self): print "You are on turn number %d" % self.turn print "There are %d peasants in your city." % self.people print "You have %d bushels of grain." % self.grain print "You have %d wisemen." % self.wisemen print "You have %d soldiers." % self.soldiers def decision(self): plan = AnnualPlan() plan.shrinkage = randrange(10,50) - self.wisemen if plan.shrinkage < 0: plan.shrinkage = 0 plan.yld = randrange(1,5) promotions = decision( "How many peasants do you want to promote to wisemen?", lambda x: x <= self.people,"You don't have that many peasants") wisemen = self.wisemen people = self.people soldiers = self.soldiers wisemen += promotions people -= promotions enlistments = decision( "How many peasants do you want to enlist in the army?", lambda x: x <= people,"You don't have that many peasants.") soldiers += enlistments people -= enlistments print "You now have %d peasants, %d wisemen, and %d soldiers." % (people, wisemen, soldiers) plan.enlistments = enlistments plan.promotions = promotions plan.plant=decision("How much will you plant?",lambda x:x <= people, "With only %d peasants, you can plant at most %d bushels." % ( people,people )) plan.req = people + wisemen*1.5 + soldiers*2 + 3 cangive = self.grain + plan.plant print "The nation requires %d bushels of food. You can give a total of %d bushels." % (plan.req, cangive) plan.food=decision("How much food will you give the people?", lambda x: x <= cangive, "We don't have that much grain.") # add random elements to plan if plan.food > plan.req: plan.migration = randrange(0,50) * (plan.food - plan.req)/200 else: plan.migration = 0 strength = int(plan.req/10) plan.attacks = randrange(1,10) plan.deaths = randrange(0,10) * people/100 plan.births = randrange(0,10) * people/100 return plan def showYield(self,plan,yld): print "Out of the %d bushels you planted, you harvested %d." % ( plan.plant, yld.harvest) print "You stored %d bushels from what you had remaining." % ( self.grain + yld.loss) print "The rats got into %d bushels - you have %d bushels remaining." % ( yld.loss,self.grain) print "%d peasants came to the city." % plan.migration if yld.event == City.REVOLT: raise Terminate(deathstrings[randrange(0,len(deathstrings))]) if yld.event == City.ATTACK: self.attack() elif yld.starved > 0: print "You didn't give enough food for everyone." if self.people <= 0: raise Terminate("No peasants survived. With only a few nobility remaining, your country soon collapses.") print "%d peasants starved. %d survived." %(yld.starved,self.people) print "You have suffered a loss due to the famine." print "However, enough peasants survived for your country to go on." elif self.turn != 1: if plan.deaths != 0: print "%d peasants died." % plan.deaths print "%d peasants were born." % plan.births def update(self,plan): self.wisemen += plan.promotions self.soldiers += plan.enlistments self.people -= plan.enlistments + plan.promotions yld = AnnualYield() yld.harvest = plan.yld * plan.plant yld.event = 0 totalgive = yld.harvest + self.grain store = (totalgive - plan.food) yld.loss = store*plan.shrinkage/100 store -= yld.loss self.grain = store self.turn += 1 if plan.attacks == 1: yld.event = City.ATTACK if plan.food > plan.req: yld.starved = 0 self.people += plan.migration + plan.births - plan.deaths elif plan.food <= plan.req: nobilityreq = (self.soldiers*2) + (self.wisemen*1.5) + 3 if plan.food <= nobilityreq: yld.starved = self.people self.people = 0 elif plan.food > nobilityreq: plan.food = plan.food - nobilityreq yld.starved = self.people - plan.food survived = self.people - yld.starved if survived < (self.people/2): yld.event = City.REVOLT elif survived >= (self.people/2): self.people = survived self.people = int(self.people) return yld def save(self,filename): fileHandle = open( filename , 'wb' ) rec = struct.pack("lllll", self.people,self.wisemen,self.soldiers,self.grain,self.turn) fileHandle.write(rec) fileHandle.close() def load(self,filename): fileHandle = open( filename , 'rb' ) rec = fileHandle.read() self.people,self.wisemen,self.soldiers,self.grain,self.turn = struct.unpack("lllll",rec) fileHandle.close() city = City() def cycle(): city.status() plan = city.decision() yld = city.update(plan) print yld city.showYield(plan,yld) if __name__ == '__main__': try: while True: try: cycle() except Restore: city.load('pharoh.sav') print "Game loaded from file." except Terminate,x: print x