Mercurial > sypikslang
view gamelib/lab.py @ 84:9d0ad8aeb598
Add some gameplay fluff text in readme
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Wed, 09 May 2012 18:12:01 +0200 |
parents | b503ccb0a86e |
children | 182fce9f70b6 |
line wrap: on
line source
# -*- test-case-name: gamelib.tests.test_lab -*- from random import random, choice from gamelib import research, schematics from gamelib.game_base import get_subclasses class Lab(object): BASIC_RESEARCH_SUCCESS_RATE = 0.05 BASIC_RESEARCH_SUCCESS_MULTIPLIER = 2 def __init__(self, init_data=None): self.science = [] self.new_research = get_subclasses(research.ResearchArea) self.new_schematics = get_subclasses(schematics.Schematic) if init_data is not None: # Load stored state. self._load_data(init_data) else: # New game. self._choose_initial_science() def _load_data(self, init_data): sciences = init_data['science'].copy() for science in self.new_schematics + self.new_research: # Check if this science is one we should know. points = sciences.pop(science.save_name(), None) if points is not None: # It is! Learn it. self._gain_science(science(points)) if sciences: # We're supposed to know an unknowable thing. :-( raise ValueError("Unknown science: %s" % (sciences.keys(),)) def save_data(self): return {'science': dict(s.save_data() for s in self.science)} def _choose_initial_science(self): # We always get all starting schematics. for schematic in self.new_schematics[:]: if schematic.STARTING_PRODUCT: self._gain_science(schematic()) # We get three random sciences with no prerequisites. new_science = [] for _ in range(3): science = choice(self.find_new_research())() self._gain_science(science) new_science.append(science) # Add a point to each of our sciences, and see if we get schematics. self.spend_points(new_science, 0) def _gain_science(self, science): self.science.append(science) if isinstance(science, research.ResearchArea): self.new_research.remove(type(science)) elif isinstance(science, schematics.Schematic): self.new_schematics.remove(type(science)) def spend_points(self, things, basic_research): breakthroughs = [] # First, allocate the points. for thing in things: assert thing in self.science assert thing.can_spend(self, 1) thing.spend_point() # Next, check for schematic breakthroughs and upgrades breakthroughs.extend(self.apply_area_research( thing for thing in things if isinstance(thing, research.ResearchArea))) # Finally, check for research breakthroughs. breakthroughs.extend(self.apply_basic_research(basic_research)) return breakthroughs def _get_science(self, science_class): for science in self.science: if isinstance(science, science_class): return science return None def meet_requirements(self, science_class, extra=0): total_points = 0 base_points = 0 for science, level in science_class.PREREQUISITES: my_science = self._get_science(science) if my_science is None: return False if my_science.points < level: return False base_points += level total_points += my_science.points return total_points - base_points >= extra def find_new_schematics(self): available_schematics = [] for schematic_class in self.new_schematics: if self.meet_requirements(schematic_class): available_schematics.append(schematic_class) return available_schematics def find_new_research(self): available_research = [] for research_class in self.new_research: if self.meet_requirements(research_class): available_research.append(research_class) return available_research def apply_area_research(self, researches): options = [schema for schema in self.find_new_schematics() if schema.depends_on(researches)] breakthroughs = [schematic for schematic in options if random() < schematic.ACQUISITION_CHANCE] if breakthroughs: breakthrough = choice(breakthroughs)() self._gain_science(breakthrough) breakthroughs = [breakthrough] return breakthroughs def apply_basic_research(self, basic_research): if basic_research <= 1: return [] options = self.find_new_research() success_chance = self.BASIC_RESEARCH_SUCCESS_RATE * ( self.BASIC_RESEARCH_SUCCESS_MULTIPLIER ** basic_research) breakthroughs = [research for research in options if random() < success_chance] if breakthroughs: breakthrough = choice(breakthroughs)(1) self._gain_science(breakthrough) breakthroughs = [breakthrough] return breakthroughs