Building funds safe from raids; settlement tiers; population and food on the town square
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e3b70c1e3a
commit
3716df7493
6 changed files with 358 additions and 91 deletions
|
|
@ -125,24 +125,112 @@ class GiftTest(unittest.TestCase):
|
|||
|
||||
|
||||
class CityTest(unittest.TestCase):
|
||||
def test_build_needs_stockpile_then_takes_time(self):
|
||||
def test_fund_from_bank_and_stores_then_builds(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
p = world["players"]["fred"]
|
||||
self.assertIn("short", game.commission(world, p, "walls", T0))
|
||||
world["city"]["stockpile"].update({"stone": 1200, "bricks": 500})
|
||||
world["city"]["treasury"] = 300
|
||||
self.assertIsNone(game.commission(world, p, "walls", T0))
|
||||
self.assertEqual(world["city"]["treasury"], 0)
|
||||
self.assertNotIn("stone", world["city"]["stockpile"])
|
||||
city = world["city"]
|
||||
p["bank"] = {"stone": 1500}
|
||||
city["stockpile"] = {"bricks": 600}
|
||||
city["treasury"] = 300
|
||||
self.assertIsNone(game.fund(world, p, "walls", "stone", "all", "bank", T0))
|
||||
self.assertEqual(p["bank"], {"stone": 300}) # only what the fund needed
|
||||
self.assertEqual(p["favour"], 1200)
|
||||
self.assertIsNone(game.fund(world, p, "walls", "bricks", 500, "city", T0))
|
||||
self.assertEqual(city["stockpile"], {"bricks": 100})
|
||||
self.assertIsNone(city["construction"])
|
||||
self.assertEqual(game.fund(world, p, "walls", "stone", 1, "bank", T0), "The fund doesn't need that")
|
||||
self.assertIsNone(game.fund(world, p, "walls", "gold", "all", "city", T0))
|
||||
self.assertEqual(city["construction"]["building"], "walls")
|
||||
self.assertEqual(city["buildings"]["walls"]["fund"], {})
|
||||
game.tick(world, T0 + 3 * game.HOUR, random.Random(1))
|
||||
self.assertEqual(world["city"]["buildings"]["walls"]["level"], 1)
|
||||
self.assertEqual(city["buildings"]["walls"]["level"], 1)
|
||||
self.assertEqual(game.defence(world)["parts"]["walls"], 20)
|
||||
|
||||
def test_funded_buildings_queue_behind_the_builders(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
p = world["players"]["fred"]
|
||||
city = world["city"]
|
||||
for key in ("walls", "houses"):
|
||||
city["buildings"][key]["fund"] = {k: v for k, v in game.build_cost(key, 1).items() if k != "gold"}
|
||||
city["treasury"] += game.build_cost(key, 1)["gold"]
|
||||
self.assertIsNone(game.fund(world, p, key, "gold", "all", "city", T0))
|
||||
self.assertEqual(city["construction"]["building"], "walls")
|
||||
self.assertEqual(city["queue"], ["houses"])
|
||||
game.tick(world, T0 + 3 * game.HOUR, random.Random(1))
|
||||
self.assertEqual(city["construction"]["building"], "houses")
|
||||
self.assertEqual(city["queue"], [])
|
||||
|
||||
def test_raids_never_touch_funds(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
city = world["city"]
|
||||
city["buildings"]["walls"]["fund"] = {"stone": 1000}
|
||||
city["stockpile"] = {"stone": 1000}
|
||||
world["next_event_at"] = T0
|
||||
game.tick(world, T0, random.Random(2))
|
||||
raid = game.upcoming_raid(world)
|
||||
raid["strength"] = 500
|
||||
game.tick(world, raid["fire_at"], random.Random(1))
|
||||
self.assertLess(city["stockpile"]["stone"], 1000)
|
||||
self.assertEqual(city["buildings"]["walls"]["fund"], {"stone": 1000})
|
||||
|
||||
def test_tier_caps_levels_and_promotes_for_good(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
city = world["city"]
|
||||
city["buildings"]["walls"]["level"] = 1
|
||||
self.assertIsNone(game.fund_target(world, "walls")) # hamlet: level 1 only
|
||||
self.assertIsNotNone(game.fund_target(world, "houses")) # houses go to 2
|
||||
slots = game.bank_slots(world, world["players"]["fred"])
|
||||
city["population"] = 41
|
||||
world["next_event_at"] = None
|
||||
game.tick(world, T0 + 1, random.Random(1))
|
||||
self.assertEqual(city["tier"], 1)
|
||||
self.assertIsNotNone(game.fund_target(world, "walls"))
|
||||
self.assertEqual(game.bank_slots(world, world["players"]["fred"]), slots + game.TIER_SLOTS)
|
||||
city["population"] = 10
|
||||
game.tick(world, T0 + 2, random.Random(1))
|
||||
self.assertEqual(city["tier"], 1)
|
||||
|
||||
def test_damage_turns_the_fund_towards_repairs_and_keeps_the_rest(self):
|
||||
world = world_with(("fred", "warrior"))
|
||||
p = world["players"]["fred"]
|
||||
city = world["city"]
|
||||
city["buildings"]["walls"].update(level=1, damaged=True, fund={"stone": 2000})
|
||||
repair = game.repair_cost("walls", 1)
|
||||
self.assertEqual(game.fund_target(world, "walls"), repair)
|
||||
for item, qty in repair.items():
|
||||
if item == "gold":
|
||||
city["treasury"] = qty
|
||||
game.fund(world, p, "walls", "gold", "all", "city", T0)
|
||||
elif item != "stone":
|
||||
city["stockpile"][item] = qty
|
||||
game.fund(world, p, "walls", item, "all", "city", T0)
|
||||
self.assertTrue(city["construction"]["repair"])
|
||||
self.assertEqual(city["buildings"]["walls"]["fund"], {"stone": 2000 - repair["stone"]})
|
||||
|
||||
def test_old_worlds_migrate(self):
|
||||
world = game.new_world(T0)
|
||||
world["version"] = 1
|
||||
for building in world["city"]["buildings"].values():
|
||||
del building["fund"]
|
||||
del world["city"]["queue"], world["city"]["tier"]
|
||||
game.migrate(world)
|
||||
self.assertEqual(world["version"], game.WORLD_VERSION)
|
||||
self.assertEqual(world["city"]["queue"], [])
|
||||
self.assertEqual(world["city"]["buildings"]["walls"]["fund"], {})
|
||||
|
||||
def test_population_view_explains_growth(self):
|
||||
world = world_with()
|
||||
view = game.population_view(world)
|
||||
self.assertEqual(view["tier_name"], "Hamlet")
|
||||
self.assertEqual(view["next_tier"], {"name": "Village", "pop": 40})
|
||||
self.assertGreater(view["growth"], 0)
|
||||
self.assertEqual(view["food_days"], 4.0) # 40 bread for 20 people eating 0.5 a day
|
||||
|
||||
def test_people_eat_and_go_hungry(self):
|
||||
world = world_with()
|
||||
city = world["city"]
|
||||
city["stockpile"] = {"bread": 5}
|
||||
game.tick(world, T0 + 2 * game.DAY, random.Random(1))
|
||||
game.tick(world, T0 + 4 * game.DAY, random.Random(1))
|
||||
self.assertTrue(city["starving"])
|
||||
self.assertNotIn("bread", city["stockpile"])
|
||||
self.assertLess(city["population"], 20)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue