class Kingdom(GameState): world_id = db.Column(db.Integer, db.ForeignKey('world.id'), nullable=False) name = db.Column(db.String(128), nullable=False) counties = db.relationship('County', backref='kingdom') def __init__(self, name): self.world_id = 1 self.name = name def advance_day(self): for county in self.counties: county.advance_day()
class Military(GameState): county_id = db.Column(db.Integer, db.ForeignKey('county.id'), nullable=False) county = relationship("County", back_populates="military") units = relationship("Unit", back_populates="military") # FIXME: @klondikemarlen # peasant = relationship? # soldier = relationship? # archer = relationship? def __init__(self, county_id, race): self.county_id = county_id self.peasant = Unit(unit_type="Peasant", race=race) self.soldier = Unit(unit_type="Soldier", race=race) self.archer = Unit(unit_type="Archer", race=race) self.units = [self.peasant, self.soldier, self.archer] def offensive_power(self): power = 0 for unit in self.units: power += unit.get_available() * unit.attack return power def defensive_power(self): power = 0 for unit in self.units: power += unit.get_available() * unit.defence return power
class Preference(GameState): county_id = db.Column(db.Integer, db.ForeignKey('county.id'), nullable=False) county = relationship("County", back_populates="preference") _tax_rate = db.Column(db.Integer) rations = db.Column(db.Float) production_choice = db.Column(db.String(16)) def __init__(self, county_id): self.county_id = county_id self._tax_rate = 7 self.rations = Rations.NORMAL self.production_choice = ProductionChoice.OVERWORK
class County(GameState): # Basics name = db.Column(db.String(128), nullable=False) leader = db.Column(db.String(128)) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = db.relationship('User', back_populates='county') kingdom_id = db.Column(db.Integer, db.ForeignKey('kingdom.id'), nullable=False) race = db.Column(db.String(16)) title = db.Column(db.String(16)) background = db.Column(db.String(16)) # Misc weather = db.Column(db.String(16)) economy = relationship("Economy", uselist=False, back_populates="county") infrastructure = relationship("Infrastructure", uselist=False, back_populates="county") military = relationship("Military", uselist=False, back_populates="county") preference = relationship("Preference", uselist=False, back_populates="county") def __init__(self, kingdom_id, name, leader, user_id, race, title, background): self.kingdom_id = kingdom_id self.name = name self.leader = leader self.user_id = user_id self.race = race self.title = title self.background = background # Misc self.weather = generate_weather() self.save() print( f"CREATING ECONOMY/INFRASTRUCTURE/PREFERENCE WITH COUNTY ID {self.id}" ) self.economy = Economy(county_id=self.id) self.infrastructure = Infrastructure(county_id=self.id, race=self.race) self.military = Military(county_id=self.id, race=self.race) self.preference = Preference(county_id=self.id) @property def day(self): return self.kingdom.world.day def advance_day(self): self.economy.gold += 25 self.economy.wood += 25 self.economy.iron += 25 self.economy.stone += 5
class World(GameState): kingdoms = db.relationship('Kingdom', backref='world') age = db.Column(db.Integer) day = db.Column(db.Integer) season = db.Column(db.String(16)) def __init__(self): self.age = 1 self.day = 0 self.season = "Summer" def advance_day(self): for kingdom in self.kingdoms: kingdom.advance_day() self.day += 1 def advance_age(self): pass
class User(GameState): # Basic data username = db.Column(db.String(128), nullable=False) # Flask is_authenticated = db.Column( db.Boolean) # User has logged in through flask. (Flask) is_active = db.Column( db.Boolean ) # Account has been activated via email and not been locked. (Flask) is_anonymous = db.Column( db.Boolean ) # Current_user is set to is_anonymous when not yet logged in. (Flask) is_admin = db.Column( db.Boolean) # Current user is a game creator with unlimited power is_bot = db.Column( db.Boolean) # Current user is a game creator with unlimited power county = db.relationship('County', back_populates='user', uselist=False) def __init__(self, username): # Basic data self.username = username # Flask login self.is_authenticated = True self.is_active = True self.is_anonymous = False def get_id(self): # Required for flask-login return self.id
class Infrastructure(GameState): county_id = db.Column(db.Integer, db.ForeignKey('county.id'), nullable=False) county = relationship("County", back_populates="infrastructure") buildings = relationship("Building", back_populates="infrastructure") def __init__(self, county_id, race): self.county_id = county_id self.house = Building(building_type="House", race=race) self.field = Building(building_type="Field", race=race) self.pasture = Building(building_type="Pasture", race=race) self.buildings = [self.house, self.field, self.pasture] def get_employed_workers(self): total = 0 for building in self.buildings: total += building.worker_capacity * building.total_owned return total
class Building(GameState): infrastructure_id = db.Column(db.Integer, db.ForeignKey('infrastructure.id'), nullable=False) infrastructure = relationship("Infrastructure", back_populates="buildings") building_type = db.Column(db.String(16)) class_name = db.Column(db.String(16)) class_name_plural = db.Column(db.String(16)) total_owned = db.Column(db.Integer) worker_capacity = db.Column(db.Integer) gold_cost = db.Column(db.Integer) wood_cost = db.Column(db.Integer) stone_cost = db.Column(db.Integer) output = db.Column(db.Integer) description = db.Column(db.String(128)) def __init__(self, building_type, race): self.building_type = building_type racial_metadata = getattr(Buildings, race)[building_type] self.class_name = racial_metadata["Singular"] self.class_name_plural = racial_metadata["Plural"] self.total_owned = 10 self.worker_capacity = 5 self.gold_cost = racial_metadata["Gold"] self.wood_cost = racial_metadata["Wood"] self.stone_cost = racial_metadata["Stone"] self.output = racial_metadata["Output"] self.description = racial_metadata["Description"].format(self.output)
class Economy(GameState): county_id = db.Column(db.Integer, db.ForeignKey('county.id'), nullable=False) county = relationship("County", back_populates="economy") BASE_BUILD_SLOTS = 3 build_slots = db.Column(db.Integer) BASE_HAPPINESS = 7 happiness_change = db.Column(db.Integer) _population = db.Column(db.Integer) _land = db.Column(db.Integer) _happiness = db.Column(db.Integer) # Out of 100 _healthiness = db.Column(db.Integer) # Out of 100 _gold = db.Column(db.Integer) _wood = db.Column(db.Integer) _iron = db.Column(db.Integer) _stone = db.Column(db.Integer) _research = db.Column(db.Integer) _mana = db.Column(db.Integer) grain_stores = db.Column(db.Integer) def __init__(self, county_id): self.county_id = county_id self._population = 500 self._land = 150 self._healthiness = 75 self._happiness = 100 self._gold = 750 self._wood = 250 self._iron = 50 self._stone = 0 self._research = 0 self._mana = 0 self.grain_stores = 500 @property def population(self): return self._population @population.setter def population(self, value): self._population = max(value, 1) def get_population_change(self): growth = self.get_expected_births() # + self.get_immigration_rate() decay = self.get_expected_deaths() # + self.get_emigration_rate() delta = growth - decay maximum_decay = -0.03 * self.population # Can't decay more than 3% an hour return int(max(delta, maximum_decay)) @property def land(self): return self._land @land.setter def land(self, value): if value <= 0: self._land = "YOU LOST THE GAME" self._land = value @property def gold(self): return self._gold @gold.setter def gold(self, value): self._gold = max(value, 0) @property def wood(self): return self._wood @wood.setter def wood(self, value): self._wood = max(value, 0) @property def iron(self): return self._iron @iron.setter def iron(self, value): self._iron = max(value, 0) @property def stone(self): return self._stone @stone.setter def stone(self, value): self._stone = max(value, 0) @property def mana(self): return self._mana @mana.setter def mana(self, value): value = min(value, 10) # Should be max_mana self._mana = max(value, 0) @property def happiness(self): return self._happiness @happiness.setter def happiness(self, value): self._happiness = int(max(min(100, value), 1)) @property def healthiness(self): return self._healthiness @healthiness.setter def healthiness(self, value): self._healthiness = int(max(min(100, value), 1)) def get_expected_births(self): basic_births = (self.happiness / 100) * (self.land / 5) # 5% times your happiness rating modifier = self.get_birth_rate_modifier() return round(basic_births * modifier) def get_birth_rate_modifier(self): house_bonus = (self.county.infrastructure.house.total_owned ** 0.75 * self.county.infrastructure.house.output) / self.land modifier = 1 + house_bonus return modifier def get_expected_deaths(self): rate = (2 / self.healthiness) deaths = rate * self.population return round(deaths)
class Unit(GameState): military_id = db.Column(db.Integer, db.ForeignKey('military.id'), nullable=False) military = relationship("Military", back_populates="units") unit_type = db.Column(db.String(16)) class_name = db.Column(db.String(16)) class_name_plural = db.Column(db.String(16)) total_owned = db.Column(db.Integer) gold_cost = db.Column(db.Integer) wood_cost = db.Column(db.Integer) iron_cost = db.Column(db.Integer) upkeep = db.Column(db.Integer) attack = db.Column(db.Integer) defence = db.Column(db.Integer) health = db.Column(db.Integer) category = db.Column(db.String(16)) armour = db.Column(db.String(16)) description = db.Column(db.String(128)) def __init__(self, unit_type, race): self.unit_type = unit_type racial_metadata = getattr(Units, race)[unit_type] self.class_name = racial_metadata["Singular"] self.class_name_plural = racial_metadata["Plural"] self.total_owned = 0 self.gold_cost = racial_metadata["Gold"] self.wood_cost = racial_metadata["Wood"] self.iron_cost = racial_metadata["Iron"] self.upkeep = racial_metadata["Upkeep"] self.attack = racial_metadata["Attack"] self.defence = racial_metadata["Defence"] self.health = racial_metadata["Health"] self.category = racial_metadata["Category"] self.armour = racial_metadata["Armour"] self.description = racial_metadata["Description"] def get_available(self): return self.total_owned