# HG changeset patch # User Jeremy Thurgood # Date 1336318777 -7200 # Node ID 10d3db1f1e0851ee81b6fdc0f815279a16886f49 # Parent af1bfeb648cb7676f647d20f92666a6c4e1ce226 Set up initial research and rework breakthroughs. diff -r af1bfeb648cb -r 10d3db1f1e08 gamelib/lab.py --- a/gamelib/lab.py Sun May 06 17:12:40 2012 +0200 +++ b/gamelib/lab.py Sun May 06 17:39:37 2012 +0200 @@ -1,23 +1,64 @@ # -*- test-case-name: gamelib.tests.test_lab -*- +from random import random, choice + from gamelib import research, products class Lab(object): + BASIC_RESEARCH_SUCCESS_RATE = 0.05 + BASIC_RESEARCH_SUCCESS_MULTIPLIER = 2 + def __init__(self): self.science = [] self.new_research = research.ResearchArea.__subclasses__() self.new_products = products.Product.__subclasses__() + self._choose_initial_science() + + def _choose_initial_science(self): + # We always get all starting products. + for product in self.new_products[:]: + if product.STARTING_PRODUCT: + self._gain_science(product()) + + # 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 products. + 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, products.Product): + self.new_products.remove(type(science)) def spend_points(self, things, basic_research): - new_stuff = [] + breakthroughs = [] + + # First, allocate the points. for thing in things: assert thing in self.science - thing.spend_points(1) + assert thing.can_spend(self) + thing.spend_point() + + # Next, check for product breakthroughs and upgrades + for thing in things: if isinstance(thing, research.ResearchArea): - new_stuff.extend(self.find_new_product(thing)[:1]) - new_stuff.extend(self.try_basic_research(basic_research)[:1]) - return new_stuff + breakthroughs.extend(self.apply_area_research(thing)) + + # 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): for science in self.science: @@ -25,25 +66,54 @@ return science return None - def _meet_requirements(self, science_class): + 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 - return True + base_points += level + total_points += my_science.points + return total_points - base_points >= extra def find_new_products(self, research_area): available_products = [] for product_class in self.new_products: - if self._meet_requirements(product_class): + if self.meet_requirements(product_class): available_products.append(product_class) return available_products - def find_new_research(self, basic_research): + def find_new_research(self): available_research = [] for research_class in self.new_research: - if self._meet_requirements(research_class): + if self.meet_requirements(research_class): available_research.append(research_class) return available_research + + def apply_area_research(self, research): + options = self.find_new_products(research) + breakthroughs = [product for product in options + if random() < product.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 diff -r af1bfeb648cb -r 10d3db1f1e08 gamelib/products.py --- a/gamelib/products.py Sun May 06 17:12:40 2012 +0200 +++ b/gamelib/products.py Sun May 06 17:39:37 2012 +0200 @@ -6,27 +6,50 @@ PREREQUISITES = () ACQUISITION_CHANCE = 0.8 COST = 0 + UPGRADE_REQUIREMENT = 1 + STARTING_PRODUCT = False - def __init__(self): - self.points = 0 + def __init__(self, points=0): + self.points = points - def spend_points(self, points): - self.points += points + def spend_point(self): + self.points += 1 + + def can_spend(self, lab): + extra = self.UPGRADE_REQUIREMENT * self.points + 1 + return lab.meet_requirements(self, extra) class MachineGun(Product): NAME = "Machine gun" COST = 100 + STARTING_PRODUCT = True + + def __init__(self): + self.points = 1 + + def spend_point(self): + raise NotImplementedError() + + def can_spend(self, lab): + return False -class TeslaGun(Product): - NAME = "Tesla gun" +class LightningGun(Product): + NAME = "Lightning gun" PREREQUISITES = ( (research.Tesla, 1), ) COST = 300 +class TeslaTank(Product): + NAME = "Tesla tank" + PREREQUISITES = ( + (research.Tesla, 3), + ) + + class DoomsdayVirus(Product): NAME = "Doomsday virus" PREREQUISITES = ( diff -r af1bfeb648cb -r 10d3db1f1e08 gamelib/research.py --- a/gamelib/research.py Sun May 06 17:12:40 2012 +0200 +++ b/gamelib/research.py Sun May 06 17:39:37 2012 +0200 @@ -2,11 +2,14 @@ NAME = None PREREQUISITES = () - def __init__(self): - self.points = 0 + def __init__(self, points=0): + self.points = points - def spend_points(self, points): - self.points += points + def spend_point(self): + self.points += 1 + + def can_spend(self, lab): + return True class Tesla(ResearchArea): diff -r af1bfeb648cb -r 10d3db1f1e08 gamelib/tests/test_lab.py --- a/gamelib/tests/test_lab.py Sun May 06 17:12:40 2012 +0200 +++ b/gamelib/tests/test_lab.py Sun May 06 17:39:37 2012 +0200 @@ -9,11 +9,23 @@ self.lab = Lab() def test_find_new_products(self): + # Set up the appropriate research. + if research.Tesla in self.lab.new_research: + self.lab._gain_science(research.Tesla(1)) + self.lab._get_science(research.Tesla).points += 2 + # Check breakthrough options. new_products = self.lab.find_new_products(None) - self.assertTrue(products.MachineGun in new_products) + self.assertTrue(products.TeslaTank in new_products) self.assertTrue(products.DoomsdayVirus not in new_products) def test_find_new_research(self): - new_research = self.lab.find_new_research(None) - self.assertTrue(research.Tesla in new_research) - self.assertTrue(research.Space not in new_research) + # Set up the appropriate research. + if research.Robotics in self.lab.new_research: + self.lab._gain_science(research.Robotics(1)) + if research.Rocketry in self.lab.new_research: + self.lab._gain_science(research.Rocketry(1)) + self.lab._get_science(research.Rocketry).points += 1 + # Check breakthrough options. + new_research = self.lab.find_new_research() + self.assertTrue(research.Space in new_research) + self.assertTrue(research.ArtificialIntelligence not in new_research)