Mercurial > sypikslang
changeset 23:f6a3b213857b
Fix up some game state logic, add very basic REPL game interface.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Sun, 06 May 2012 19:06:28 +0200 |
parents | 296ce36fa7d9 |
children | 23720d0fd9a0 |
files | gamelib/gamestate.py gamelib/lab.py gamelib/mission.py gamelib/missions.py gamelib/tests/repl_game.py |
diffstat | 5 files changed, 175 insertions(+), 153 deletions(-) [+] |
line wrap: on
line diff
--- a/gamelib/gamestate.py Sun May 06 18:38:54 2012 +0200 +++ b/gamelib/gamestate.py Sun May 06 19:06:28 2012 +0200 @@ -54,8 +54,8 @@ result.apply(self) # Update the science state with result of spend_points for science in new_stuff: - self.lab.science.append(science) - # FIXME: Update UI + # FIXME: Update UI better. + print "You learned new stuff:", science.NAME def save_data(self): """Serialize the game state into a dict"""
--- a/gamelib/lab.py Sun May 06 18:38:54 2012 +0200 +++ b/gamelib/lab.py Sun May 06 19:06:28 2012 +0200 @@ -81,9 +81,6 @@ # Finally, check for research breakthroughs. breakthroughs.extend(self.apply_basic_research(basic_research)) - # Now that we have our breakthroughs, apply them. - print breakthroughs - return breakthroughs def _get_science(self, science_class):
--- a/gamelib/mission.py Sun May 06 18:38:54 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4 - -from product import DoomsdayVirus, MachineGun, TeslaGun - -MAJOR_SETBACK, FAILURE, SUCCESS, MAJOR_SUCCESS, GAME_WIN = range(5) - - -class Result(object): - """Results of a mission""" - - def __init__(self, outcome, money, reputation, msg): - self.outcome = outcome - self.money = money - self.reputation = reputation - self.message = msg - self.applied = False - - def apply(self, state): - if not self.applied: - state.money += self.money - state.reputation += self.reputation - self.applied = True - else: - raise RuntimeError('attempted to apply result twice') - - -class Mission(object): - """Base class for the mission objects. - Missions have a name, short description (for list displays) and - long description (which may contain clues about approaches)""" - - NAME = "Generic Mission" - SHORT_DESCRIPTION = None - LONG_DESCRIPTION = None - available = True - - def __init__(self, init_data=None): - pass - - def save_data(self): - """Serialize the mission state for saving, etc.""" - return [] - - def attempt(self, equipment, state): - """Attempt the mission with the given equipment list. - - Returns a result object with the results of the mission.""" - return Result(FAILURE, 0, 0, "You can't succceed at this mission") - - -class PlaygroundBully(Mission): - - NAME = "Rob kids in the playground" - SHORT_DESCRIPTION = "Steal from those significantly weaker than yourself" - LONG_DESCRIPTION = ("It's not menancing, or lucrative, but when the bills" - " are due, no one cares how you earn the money") - - def attempt(sefl, equipment, state): - return Result(SUCCESS, 100, -1, "You devote your resources to" - " robbing kids in a playpark. It's not the finest moment" - " in your reign of terror, but at least you walked away" - " with a surprising amount of small change.") - - -class RansomChina(Mission): - - NAME = "Hold China to ransom" - SHORT_DESCRIPTION = "Surely a path to riches and fame" - LONG_DESCRIPTION = "Holding China to ransom. The rewards for" \ - " successfully threatening the largest country in the world" \ - " are great, but the risks are significant. Without " \ - "some serious firepower, the chances of success are small." - - def __init__(self, init_data=None): - # Track prior approaches to this mission - self._prior_attempts = [] - if init_data: - self._prior_attempts = init_data - - def save_data(self): - return self._prior_attempts - - def attempt(self, equipment, state): - failures = [] - reputation = 0 - for item in equipment: - if isinstance(item, DoomsdayVirus) and \ - item.NAME not in self._prior_attempts: - self._prior_attempts.add(item.NAME) - return Result(SUCCESS, 1000000, 1, "Trembling at the threat of" - " your doomsday virus, the chinese government pays the" - " ransom") - elif isinstance(item, DoomsdayVirus): - reputation = -1 - failures.append("'Hah, we've developed an antidote to your" - " virus, doctor'. You cannot threaten us with that" - " again'") - else: - failures.append("You fail to inspire fear with your %s" - % item.name) - return Result(FAILURE, 0, reputation, "\n".join(failures)) - - -class RobBank(Mission): - - NAME = "Rob the local bank" - SHORT_DESCRIPTION = "A trivial challenge, but easy money" - LONG_DESCRIPTION = "The security guards and local police are of minor" \ - " concern. Walk in, clean out the vault, walk out. Couldn't be" \ - " simpler." - - def attempt(self, equipment, state): - failures = [] - for item in equipment: - if isinstance(item, DoomsdayVirus): - if state.reputation < 10: - failures.append("The clerk doesn't realise the threat of" - " the vial you hold, and, although watching him" - " die in agony would be statisfying, you decide" - " it's not worth wasting this on something so" - " trivial") - else: - return Result(SUCCESS, 1000, 0, "Holding up a bank with" - " only a small vial of clear liquid. Now that" - " is power.") - elif isinstance(item, MachineGun) or isinstance(item, TeslaGun): - return Result(SUCCESS, 1000, 0, "The threat of your weapons is" - " enough to inspire an impressive level of cooperation") - else: - failures.append("You fail to inspire fear with your %s" - % item.name) - return Result(FAILURE, 0, 0, "\n".join(failures)) - - -class DestroyMountRushmore(Mission): - - NAME = "Destroy Mount Rushmore" - SHORT_DESCRIPTION = "Monuments to other people? Intolerable" - LONG_DESCRIPTION = "While potentially expensive, destroying" \ - " major monument is a good way to secure your reputation." - - def attempt(self, equipment, state): - if not self.available: - raise RuntimeError('Cannot attempt an unavailable mission') - self.available = False - return Result(SUCCESS, 0, 100, - "Mount Rushmore is remarkably easy to destroy.")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gamelib/missions.py Sun May 06 19:06:28 2012 +0200 @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +# vim:fileencoding=utf-8 ai ts=4 sts=4 et sw=4 + +from products import DoomsdayVirus, MachineGun, LightningGun + +MAJOR_SETBACK, FAILURE, SUCCESS, MAJOR_SUCCESS, GAME_WIN = range(5) + + +class Result(object): + """Results of a mission""" + + def __init__(self, outcome, money, reputation, msg): + self.outcome = outcome + self.money = money + self.reputation = reputation + self.message = msg + self.applied = False + + def apply(self, state): + if not self.applied: + state.money += self.money + state.reputation += self.reputation + self.applied = True + else: + raise RuntimeError('attempted to apply result twice') + + +class Mission(object): + """Base class for the mission objects. + Missions have a name, short description (for list displays) and + long description (which may contain clues about approaches)""" + + NAME = "Generic Mission" + SHORT_DESCRIPTION = None + LONG_DESCRIPTION = None + available = True + + def __init__(self, init_data=None): + pass + + def save_data(self): + """Serialize the mission state for saving, etc.""" + return [] + + def attempt(self, equipment, state): + """Attempt the mission with the given equipment list. + + Returns a result object with the results of the mission.""" + return Result(FAILURE, 0, 0, "You can't succceed at this mission") + + +class PlaygroundBully(Mission): + + NAME = "Rob kids in the playground" + SHORT_DESCRIPTION = "Steal from those significantly weaker than yourself" + LONG_DESCRIPTION = ("It's not menancing, or lucrative, but when the bills" + " are due, no one cares how you earn the money") + + def attempt(sefl, equipment, state): + return Result(SUCCESS, 100, -1, "You devote your resources to" + " robbing kids in a playpark. It's not the finest moment" + " in your reign of terror, but at least you walked away" + " with a surprising amount of small change.") + + +class RansomChina(Mission): + + NAME = "Hold China to ransom" + SHORT_DESCRIPTION = "Surely a path to riches and fame" + LONG_DESCRIPTION = "Holding China to ransom. The rewards for" \ + " successfully threatening the largest country in the world" \ + " are great, but the risks are significant. Without " \ + "some serious firepower, the chances of success are small." + + def __init__(self, init_data=None): + # Track prior approaches to this mission + self._prior_attempts = [] + if init_data: + self._prior_attempts = init_data + + def save_data(self): + return self._prior_attempts + + def attempt(self, equipment, state): + failures = [] + reputation = 0 + for item in equipment: + if isinstance(item, DoomsdayVirus) and \ + item.NAME not in self._prior_attempts: + self._prior_attempts.add(item.NAME) + return Result(SUCCESS, 1000000, 1, "Trembling at the threat of" + " your doomsday virus, the chinese government pays the" + " ransom") + elif isinstance(item, DoomsdayVirus): + reputation = -1 + failures.append("'Hah, we've developed an antidote to your" + " virus, doctor'. You cannot threaten us with that" + " again'") + else: + failures.append("You fail to inspire fear with your %s" + % item.name) + return Result(FAILURE, 0, reputation, "\n".join(failures)) + + +class RobBank(Mission): + + NAME = "Rob the local bank" + SHORT_DESCRIPTION = "A trivial challenge, but easy money" + LONG_DESCRIPTION = "The security guards and local police are of minor" \ + " concern. Walk in, clean out the vault, walk out. Couldn't be" \ + " simpler." + + def attempt(self, equipment, state): + failures = [] + for item in equipment: + if isinstance(item, DoomsdayVirus): + if state.reputation < 10: + failures.append("The clerk doesn't realise the threat of" + " the vial you hold, and, although watching him" + " die in agony would be statisfying, you decide" + " it's not worth wasting this on something so" + " trivial") + else: + return Result(SUCCESS, 1000, 0, "Holding up a bank with" + " only a small vial of clear liquid. Now that" + " is power.") + elif isinstance(item, (MachineGun, LightningGun)): + return Result(SUCCESS, 1000, 0, "The threat of your weapons is" + " enough to inspire an impressive level of cooperation") + else: + failures.append("You fail to inspire fear with your %s" + % item.name) + return Result(FAILURE, 0, 0, "\n".join(failures)) + + +class DestroyMountRushmore(Mission): + + NAME = "Destroy Mount Rushmore" + SHORT_DESCRIPTION = "Monuments to other people? Intolerable" + LONG_DESCRIPTION = "While potentially expensive, destroying" \ + " major monument is a good way to secure your reputation." + + def attempt(self, equipment, state): + if not self.available: + raise RuntimeError('Cannot attempt an unavailable mission') + self.available = False + return Result(SUCCESS, 0, 100, + "Mount Rushmore is remarkably easy to destroy.")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gamelib/tests/repl_game.py Sun May 06 19:06:28 2012 +0200 @@ -0,0 +1,25 @@ +from gamelib.gamestate import Game + + +class ReplGame(object): + def __init__(self, init_data=None): + self.game = Game(init_data=init_data) + self._begin_turn() + + def _begin_turn(self): + self.game.start_turn() + self.display_state() + + def display_state(self): + print "Game:", self.game + print "Science:" + for science in self.game.lab.science: + print " %s %s (%s)" % ( + "*" if science.can_spend(self.game.lab) else "-", + science.NAME, science.points) + + def next_turn(self, research_list, missions): + self.game.cur_allocation.extend(research_list) + self.game.cur_missions.extend(missions) + self.game.end_turn() + self._begin_turn()