/// <summary> /// 路線建造コスト計算ロジック /// </summary> /// <param name="bestSpeed"></param> /// <param name="laneSu"></param> /// <param name="distance"></param> /// <param name="railType"></param> /// <param name="railGauge"></param> /// <param name="isElectrified"></param> /// <param name="taihisen"></param> /// <param name="lineProperty"></param> /// <param name="gameInfo"></param> /// <returns></returns> public static long CalcLineConstructionCost( int bestSpeed, int laneSu, int distance, RailTypeEnum railType, RailGaugeEnum?railGauge, bool?isElectrified, TaihisenEnum taihisen, LinePropertyType lineProperty, GameInfo gameInfo) { if (gameInfo is null) { throw new ArgumentNullException(nameof(gameInfo)); } int railCostKeisu = gameInfo.LineMakeCost, year = gameInfo.Year, basicYear = gameInfo.BasicYear, economicIndex = gameInfo.CalcEconomicIndex(); long railCost; long taihiCost; int taihiKeisu; if (laneSu == 3) { laneSu = 4; } switch (lineProperty) { case LinePropertyType.JapaneseInterCity: railCost = (bestSpeed + 40) * (laneSu + 1) * (distance + 10) * 4; taihiKeisu = 400; break; case LinePropertyType.Surburb: railCost = (bestSpeed + 40) * (laneSu) * (distance + 1) * 6; taihiKeisu = 500; break; case LinePropertyType.Outskirts: railCost = (bestSpeed + 40) * (laneSu) * (distance + 1) * 8; taihiKeisu = 700; break; case LinePropertyType.Plain: railCost = (bestSpeed + 200) * (laneSu + 1) * (distance + 10) * 4 / 3; taihiKeisu = 300; break; case LinePropertyType.Mountain: if (bestSpeed > 80) { railCost = (bestSpeed + 200) * (laneSu + 1) * (distance + 10) * 4; taihiKeisu = 500; } else { railCost = (bestSpeed + 40) * (laneSu + 1) * (distance + 10) * 4; taihiKeisu = 400; } break; case LinePropertyType.Alpine: if (bestSpeed > 60) { railCost = (bestSpeed + 200) * (laneSu + 1) * (distance + 10) * 5; taihiKeisu = 550; } else { railCost = (bestSpeed + 30) * (laneSu + 1) * (distance + 10) * 5; taihiKeisu = 450; } break; case LinePropertyType.Sea: if (bestSpeed > 40) { railCost = (bestSpeed + 500) * (laneSu + 1) * (distance + 10) * 5; taihiKeisu = 800; } else { railCost = 240 * (laneSu + 1) * (distance + 10) * 5; taihiKeisu = 500; } break; case LinePropertyType.RussianPlain: railCost = (bestSpeed + 500) * (laneSu + 1) / 7 * (distance + 20) * 4; taihiKeisu = 200; break; case LinePropertyType.Underground: if (bestSpeed > 40) { railCost = (bestSpeed + 200) * (laneSu + 1) * (distance + 10) * 8; taihiKeisu = 200; } else { railCost = 240 * (laneSu + 1) * (distance + 10); taihiKeisu = 500; } break; default: throw new ArgumentException($"引数の内容が誤りです 内容:{lineProperty}", nameof(lineProperty)); } //標準軌、リニア if (railType == RailTypeEnum.LinearMotor || railGauge == RailGaugeEnum.Regular) { railCost = railCost * 6 / 5; } //電化(リニアは電化) if (railType == RailTypeEnum.LinearMotor || isElectrified.GetValueOrDefault(true)) { railCost = railCost * 3 / 2; } //リニア地下鉄(都営大江戸線、福岡市営地下鉄七隈線みたいな) if (lineProperty == LinePropertyType.Underground && railType == RailTypeEnum.LinearMotor && bestSpeed < 200) { railCost /= 2; } switch (taihisen) { case TaihisenEnum.None: taihiCost = 0; break; case TaihisenEnum.Every100km: taihiCost = (distance / 100 + 1) * taihiKeisu * laneSu; break; case TaihisenEnum.Every50km: taihiCost = (distance / 50 + 1) * taihiKeisu * laneSu; break; case TaihisenEnum.Every20km: taihiCost = (distance / 20 + 1) * taihiKeisu * laneSu; break; case TaihisenEnum.Every10km: taihiCost = (distance / 10 + 1) * taihiKeisu * laneSu; break; case TaihisenEnum.Every5km: taihiCost = (distance / 5 + 1) * taihiKeisu * laneSu; break; case TaihisenEnum.Every2km: taihiCost = (distance / 2 + 1) * taihiKeisu * laneSu; break; default: throw new ArgumentException($"引数の内容が誤りです 内容:{taihisen}", nameof(taihisen)); } var totalCost = railCost + taihiCost; return(totalCost / 100 * railCostKeisu / 188 * (year / 10 - basicYear / 10 + 188) / 10 * economicIndex / 10); }