def find_upgrades(game): state = game.game_state plans = [] COST = { # todo get 'Caretaker': 3500, 'SolarPanel': 6800, 'Insulation': 7200, 'Playground': 5200, 'Charger': 3400, 'Regulator': 1250 } for residence in state.residences: if residence.building_name in SETTINGS.UPGRADE.PRIORITY: for priority, upgrade_name in enumerate( SETTINGS.UPGRADE.PRIORITY[residence.building_name]): if upgrade_name not in residence.effects: if upgrade_name == 'Charger' and SETTINGS.UPGRADE.CHARGER_ONLY_ON_MALL and 'Mall.2' not in residence.effects: continue score = 10.0 - priority plan = Plan(Urgency.UPGRADE, score) if state.funds >= SETTINGS.UPGRADE.FUNDS_THRESHOLD and state.funds >= COST[ upgrade_name]: # never will happen with high threshold plans.append( plan.upgrade((residence.X, residence.Y), upgrade_name).remember_count( memory, 'upgrade', upgrade_name)) elif SETTINGS.UPGRADE.WAIT_FOR_UPGRADE: plans.append(plan.wait()) return plans
def find_construction(game): state = game.game_state plans = [] # new construction? available = available_buildings(state) vacancies = sum([ game.get_blueprint(residence.building_name).max_pop - residence.current_pop for residence in state.residences ]) bad_time = state.housing_queue < SETTINGS.BUILDING.REQ_MIN_HOUSING_QUEUE or vacancies > SETTINGS.BUILDING.REQ_MAX_VACANCIES priority = 1 for entry in memory['planned_buildings']: position, building_name = entry if building_name not in available: continue bp = game.get_blueprint(building_name) score = SETTINGS.BUILDING.PRIORITY_VALUE - 0.01 * priority priority += 1 plan = Plan(Urgency.CONSTRUCTION, score) if bad_time: pass elif state.funds < bp.cost: plans.append(plan.wait()) else: plans.append( plan.construction(position, building_name).forget_entry( memory, 'planned_buildings', entry)) return plans
def find(priorities, urgency): if residence.building_name in priorities: for priority, upgrade_name in enumerate( priorities[residence.building_name]): if upgrade_name not in residence.effects: if upgrade_name in SETTINGS.UPGRADE.DELAY and state.turn < SETTINGS.UPGRADE.DELAY[ upgrade_name]: continue score = SCORE_BASE - priority plan = Plan(urgency, score) if upgrade_name == 'Regulator' and residence.temperature > SETTINGS.UPGRADE.REGULATOR_TEMP: plan.urgency = Urgency.MAJOR_ADJUST_ENERGY plan.score = SCORE_BASE + residence.temperature elif upgrade_name == 'Charger' and SETTINGS.UPGRADE.CHARGER_PRIO_ON_MALL and 'Mall.2' in residence.effects: plan.urgency = Urgency.MAJOR_UPGRADE plan.score = SCORE_BASE + residence.current_pop if state.funds >= COST[upgrade_name] and ( state.funds >= SETTINGS.UPGRADE.FUNDS_THRESHOLD or len(memory['planned_buildings']) == 0): plans.append( plan.upgrade((residence.X, residence.Y), upgrade_name).remember_count( memory, 'upgrade', upgrade_name)) elif SETTINGS.UPGRADE.SAVE_FOR_UPGRADE: plans.append(plan.wait())
def find_build(game): state = game.game_state # always continue construction plans = [] for residence in state.residences: if residence.build_progress < 100: plans.append( Plan(Urgency.BUILD, residence.build_progress).build( (residence.X, residence.Y))) for utility in state.utilities: if utility.build_progress < 100: plans.append( Plan(Urgency.BUILD, utility.build_progress).build( (utility.X, utility.Y))) return plans
def find_maintenance(game): state = game.game_state plans = [] for residence in state.residences: if residence.health < HEALTH_THRESHOLD: plans.append(Plan(Urgency.MAINTENANCE, 100.0 - residence.health).maintenance((residence.X, residence.Y))) return plans
def find_construction(game): state = game.game_state plans = [] # new construction? building_name = "Apartments" pop_tot = 0 pop_cap = 0 for residence in state.residences: pop_tot += residence.current_pop pop_cap += game.get_blueprint(building_name).max_pop if (state.funds >= game.get_blueprint(building_name).cost and state.housing_queue >= 14 and pop_cap - pop_tot <= 5): for i in range(len(state.map)): for j in range(len(state.map)): if state.map[i][j] == 0: plotTaken = False for residence in state.residences: if residence.X == i and residence.Y == j: plotTaken = True break if not plotTaken: x = i y = j plans.append(Plan(Urgency.CONSTRUCTION, 0.0).construction((x, y), building_name)) return plans
def find_adjust_energy(game): def get_energy_need(residence, outside_temp): bp = game.get_residence_blueprint(residence.building_name) def indoor_temp_forecast(energy_in): temp = residence.temperature o_dt = temperatureDerivative() for i in range(FORECAST_DAYS): o_at_t = outside_temp + (i + 1) * o_dt temp = new_temp(energy_in, bp.base_energy_need, temp, o_at_t, residence.current_pop, bp.emissivity) return temp f = lambda energy_in: TEMP_TARGET - indoor_temp_forecast(energy_in) energy = find_root(f, residence.effective_energy_in, H) return max(bp.base_energy_need, energy) state = game.game_state plans = [] for residence in state.residences: need = get_energy_need(residence, state.current_temp) urgency = Urgency.MINOR_ADJUST_ENERGY if residence.temperature < TEMP_LOW or residence.temperature > TEMP_HIGH: urgency = Urgency.MAJOR_ADJUST_ENERGY change = abs(need - residence.requested_energy_in) score = change * residence.current_pop if change > ENERGY_CHANGE_THRESHOLD: plans.append(Plan(urgency, score).adjust_energy((residence.X, residence.Y), need)) return plans
def find_utilities(game): state = game.game_state def score(pos, bp): val = 0 for residence in state.residences: for effect_name in bp.effects: effect = game.get_effect(effect_name) if manhattan(pos, (residence.X, residence.Y)) <= effect.radius: val += 1 return val plans = [] for entry in memory['planned_utilities']: position, building_name = entry bp = game.get_blueprint(building_name) if (state.funds >= bp.cost) and state.turn >= bp.release_tick: val = score(position, bp) if val >= SETTINGS.UTILITY.THRESHOLD: plans.append( Plan(Urgency.CONSTRUCTION, score(position, bp)).construction(position, building_name).forget_entry( memory, 'planned_utilities', entry)) return plans
def find_upgrades(game): state = game.game_state plans = [] upgrades = {} if state.funds > 30000: upgrades = { 'Apartments': ['SolarPanel', 'Playground', 'Caretaker'], 'ModernApartments': ['SolarPanel', 'Playground', 'Caretaker', 'Charger'], 'EnvironmentalHouse': ['Insulation'], 'LuxuryResidence': ['SolarPanel', 'Caretaker', 'Regulator', 'Playground'], 'Cabin': [], 'HighRise': ['Caretaker', 'Playground'] } for residence in state.residences: if residence.building_name in upgrades: for priority, name in enumerate(upgrades[residence.building_name]): upgrade = next((upgrade for upgrade in state.available_upgrades if upgrade.name == name), None) if upgrade is not None and name not in residence.effects and state.funds >= upgrade.cost: score = 10.0 - priority plans.append( Plan(Urgency.UPGRADE, score).upgrade( (residence.X, residence.Y), name).remember_count(memory, 'upgrade', name)) return plans
def take_turn(game): memorize_temperature(game.game_state.current_temp) plans = [Plan(Urgency.NOP, 0.0).wait()] + find_build( game) + find_construction(game) + find_utilities(game) + find_upgrades( game) + find_maintenance(game) + find_adjust_energy(game) plan = max(plans) plan = plan.remember_count(memory, 'urgencies', (plan.name, plan.urgency)) print(' ') print(plan) plan.do(game) return memory['urgencies']
def find_adjust_energy(game): plans = [] ENERGY_CHANGE_COST = 150 THRESHOLD = 0.001 def urgency(residence): if ENERGY.urgent(residence.temperature): return Urgency.MAJOR_ADJUST_ENERGY return Urgency.MINOR_ADJUST_ENERGY def change(residence, energy): return abs(energy - residence.requested_energy_in) def score(residence, energy): return change(residence, energy) * residence.current_pop for residence, energy in recommend_energy_adjustments(game): if change(residence, energy) > THRESHOLD: plan = Plan(urgency(residence), score(residence, energy)) if game.game_state.funds < ENERGY_CHANGE_COST: plan.wait() else: plan.adjust_energy((residence.X, residence.Y), energy) plans.append(plan) return plans
def find_maintenance(game): state = game.game_state plans = [] for residence in state.residences: threshold = HEALTH_THRESHOLD['Other'] if residence.building_name in HEALTH_THRESHOLD: threshold = HEALTH_THRESHOLD[residence.building_name] if residence.health < threshold: plans.append( Plan(Urgency.MAINTENANCE, 100.0 - residence.health).maintenance( (residence.X, residence.Y))) return plans
def find_maintenance(game): state = game.game_state plans = [] COST = { 'Apartments': 950, 'ModernApartments': 1050, 'Cabin': 450, 'EnvironmentalHouse': 950, 'HighRise': 2770, 'LuxuryResidence': 950 } for residence in state.residences: threshold = SETTINGS.MAINTENANCE.THRESHOLD['Other'] if residence.building_name in SETTINGS.MAINTENANCE.THRESHOLD: threshold = SETTINGS.MAINTENANCE.THRESHOLD[residence.building_name] score = 100.0 - residence.health if residence.health < threshold: plan = Plan(Urgency.MAINTENANCE, score).maintenance( (residence.X, residence.Y)) if state.funds < COST[residence.building_name]: plan = Plan(Urgency.MAINTENANCE, score).wait() plans.append(plan) return plans
def find_upgrades(game): global memory state = game.game_state plans = [] upgrades = ["Caretaker", "SolarPanel", "Playground"] #if state.turn > 600: # upgrades.append("Playground") #if state.turn > 400 and regulator_count < 7: # upgrades.append("Insulator") for residence in state.residences: for priority, name in enumerate(upgrades): upgrade = next((upgrade for upgrade in state.available_upgrades if upgrade.name == name), None) if upgrade is not None and name not in residence.effects and state.funds >= upgrade.cost: score = 10.0 - priority plans.append(Plan(Urgency.UPGRADE, score).upgrade((residence.X, residence.Y), name).remember_count(memory, 'upgrade', name)) return plans
def take_turn(game): global memory memory['temperature'].append(game.game_state.current_temp) plans = [Plan(Urgency.NO, 0.0).wait()] + find_build(game) + find_construction(game) + find_upgrades(game) + find_maintenance(game) + find_adjust_energy(game) max(plans).do(game)