private static double GetScoreForBuilding(GameState state, BlueprintResidenceBuilding building) { double ret = 0; if (state.MinTemp < 0) { ret += 10 / building.Emissivity; } if (state.HousingQueue - 5 < building.MaxPop) { ret += 100; } else { ret -= 70; } if (state.Funds - building.Cost - building.MaintenanceCost * 2 < 10000) { ret += building.IncomePerPop * 10; ret -= 60; } if (state.Funds > 20000) { ret -= building.BaseEnergyNeed * 3; ret += building.Co2Cost / 3; ret += building.MaxHappiness * 30; } ret += 100 - building.Co2Cost / 5.0; ret -= building.BaseEnergyNeed * 5; ret += !state.ResidenceBuildings.Any(t => t.BuildingName == building.BuildingName) ? 50 : 0; return(ret); }
internal static Bundle GetBestResidenceBundle(BlueprintResidenceBuilding building, GameLayer layer) { var state = layer.GetState(); int turnsLeft = (state.MaxTurns - state.Turn - (int)Math.Ceiling(100.0 / building.BuildSpeed) - 1); var pos = GetBestResidencePosition(layer); if (pos == null) { return(null); } double potentialScore = (building.MaxHappiness + Constants.AVG_EFFECT_HAPPINESS_INCREASE) * building.MaxPop * turnsLeft * Constants.AVG_POP_HAPPINESS_PRECENT / 10; if (!state.ResidenceBuildings.Any(t => t.BuildingName == building.BuildingName)) { potentialScore += turnsLeft * Constants.TARGET_END_POP_COUNT * Constants.AVG_POP_HAPPINESS * Constants.AVG_POP_HAPPINESS_PRECENT * 0.1 / 30; } //FIXA DET UNDER DENNA double avgTemp = Math.Max(state.MinTemp, state.MinTemp + (state.MaxTemp - state.MinTemp) / 2 - 4); double avgEnergyIn = Math.Max(building.BaseEnergyNeed, ((21 - avgTemp) * building.Emissivity - Constants.DEGREES_PER_POP * building.MaxPop) / Constants.DEGREES_PER_EXCESS_MWH + building.BaseEnergyNeed); if (state.UtilityBuildings.Any(t => t.BuildingName == "WindTurbine" && Math.Abs(pos.x - t.Position.x) + Math.Abs(pos.y - t.Position.y) <= 2)) { avgEnergyIn = Math.Max(0, avgEnergyIn - 3.4); } if (state.Funds > 50000) { avgEnergyIn = Math.Max(0, avgEnergyIn - 3.4); } var el = Helper.GetEnergyLevel(layer, Helper.GetEnergyConsumation(layer)); var elAfter = Helper.GetEnergyLevel(layer, Helper.GetEnergyConsumation(layer) + avgEnergyIn); if (el.CostPerMwh != elAfter.CostPerMwh) { potentialScore -= (Helper.GetEnergyConsumation(layer) + avgEnergyIn) * elAfter.TonCo2PerMwh * turnsLeft + (Helper.GetEnergyConsumation(layer)) * el.TonCo2PerMwh * turnsLeft; } else { potentialScore -= avgEnergyIn * elAfter.TonCo2PerMwh * turnsLeft; } potentialScore += 15 * building.MaxPop; potentialScore -= building.MaxPop * Constants.CO2_PER_POP * turnsLeft; potentialScore -= building.Co2Cost; Bundle bundle = new Bundle { TotalIncome = building.IncomePerPop * building.MaxPop * turnsLeft, ExtraCost = building.MaintenanceCost * turnsLeft / Math.Ceiling(55.0 / (building.DecayRate + Constants.AVG_DECAY_INCREASE)) + elAfter.CostPerMwh * avgEnergyIn * turnsLeft, UpfrontCost = building.Cost, PotentialScore = potentialScore, Turn = new PlaceBuildingTurn(pos.x, pos.y, building, state.GameId), EnergyNeed = avgEnergyIn }; return(bundle); }
public static Turn GetBestPlacedBuilding(GameLayer gameLayer) { Turn placeBuildingTurn = null; var state = gameLayer.GetState(); if ((state.Funds < 5000 && state.ResidenceBuildings.Count > 0) || state.Turn > 650) { return(null); } int spaceLeft = 0; foreach (var building in state.ResidenceBuildings) { spaceLeft += state.AvailableResidenceBuildings.First(x => x.BuildingName == building.BuildingName).MaxPop - building.CurrentPop; } if (state.Turn > 650 || spaceLeft > 0) { return(null); } if (gameLayer.GetState().Funds < 5000 && gameLayer.GetState().ResidenceBuildings.Count > 0) { return(null); } if (state.QueueHappiness > Constants.QUEUE_MAX_HAPPINESS - 5 || state.HousingQueue > Constants.LONG_QUEUE - 1) { double score = 0; BlueprintResidenceBuilding toBuild = null; foreach (var building in state.AvailableResidenceBuildings) { if (building.ReleaseTick > state.Turn) { continue; } double s = GetScoreForBuilding(state, building); if (score < s && (building.Cost + 5000 <= state.Funds || (building.Cost <= state.Funds && state.ResidenceBuildings.Count == 0))) { toBuild = building; score = s; } } if (toBuild == null) { return(null); } var pos = GetBestPos(state); return(new PlaceBuildingTurn(pos.x, pos.y, toBuild, state.GameId)); } return(placeBuildingTurn); }