From 62db3a9c9a7994d468a2238fc618be7532b71afb Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 21 Jan 2023 22:24:20 +1100 Subject: [PATCH] Finish game --- 53_King/csharp/Country.cs | 8 +++ 53_King/csharp/Game.cs | 6 +- 53_King/csharp/Reign.cs | 21 +++--- 53_King/csharp/Resources/Harvest.txt | 2 +- 53_King/csharp/Resources/Resource.cs | 7 +- 53_King/csharp/Resources/TourismDecrease.txt | 1 + 53_King/csharp/Resources/TourismEarnings.txt | 1 + ...{PollutionEffect.txt => TourismReason.txt} | 0 53_King/csharp/Result.cs | 7 ++ 53_King/csharp/Year.cs | 64 +++++++++++++------ 10 files changed, 81 insertions(+), 36 deletions(-) create mode 100644 53_King/csharp/Resources/TourismDecrease.txt create mode 100644 53_King/csharp/Resources/TourismEarnings.txt rename 53_King/csharp/Resources/{PollutionEffect.txt => TourismReason.txt} (100%) create mode 100644 53_King/csharp/Result.cs diff --git a/53_King/csharp/Country.cs b/53_King/csharp/Country.cs index d1ba9235..1a37bcd8 100644 --- a/53_King/csharp/Country.cs +++ b/53_King/csharp/Country.cs @@ -37,11 +37,13 @@ internal class Country => Resource.Status(_rallods, _countrymen, _foreigners, _arableLand, landValue, plantingCost); public float Countrymen => _countrymen; + public float Workers => _foreigners; public bool HasWorkers => _foreigners > 0; private float FarmLand => _arableLand; public bool HasRallods => _rallods > 0; public float Rallods => _rallods; public float IndustryLand => InitialLand - _arableLand; + public int PreviousTourismIncome { get; private set; } public bool SellLand(int landValue, out float landSold) { @@ -122,4 +124,10 @@ internal class Country public void AddWorkers(int newWorkers) => _foreigners = (int)(_foreigners + newWorkers); public void SellCrops(int income) => _rallods = (int)(_rallods + income); + + public void EntertainTourists(int income) + { + PreviousTourismIncome = income; + _rallods = (int)(_rallods + income); + } } diff --git a/53_King/csharp/Game.cs b/53_King/csharp/Game.cs index 92d8063f..6a91010c 100644 --- a/53_King/csharp/Game.cs +++ b/53_King/csharp/Game.cs @@ -15,7 +15,7 @@ internal class Game public void Play() { - _io.Write(Resource.Title); + _io.Write(Title); var reign = SetUpReign(); if (reign != null) @@ -29,7 +29,7 @@ internal class Game private Reign? SetUpReign() { - var response = _io.ReadString(Resource.InstructionsPrompt).ToUpper(); + var response = _io.ReadString(InstructionsPrompt).ToUpper(); if (response.Equals("Again", StringComparison.InvariantCultureIgnoreCase)) { @@ -38,7 +38,7 @@ internal class Game if (!response.StartsWith("N", StringComparison.InvariantCultureIgnoreCase)) { - _io.Write(Resource.InstructionsText(TermOfOffice)); + _io.Write(InstructionsText(TermOfOffice)); } _io.WriteLine(); diff --git a/53_King/csharp/Reign.cs b/53_King/csharp/Reign.cs index 1955c81b..7a96a30f 100644 --- a/53_King/csharp/Reign.cs +++ b/53_King/csharp/Reign.cs @@ -28,19 +28,18 @@ internal class Reign _io.Write(year.Status); - if (year.GetPlayerActions()) + var result = year.GetPlayerActions() ?? year.EvaluateResults() ?? IsAtEndOfTerm(); + if (result.IsGameOver) { - _io.WriteLine(); - _io.WriteLine(); - year.EvaluateResults(); - _yearNumber++; - return true; - } - else - { - _io.WriteLine(); - _io.Write(Goodbye); + _io.WriteLine(result.Message); return false; } + + return true; } + + private Result IsAtEndOfTerm() + => _yearNumber == MaxTerm + ? Result.GameOver(EndCongratulations(MaxTerm)) + : Result.Continue; } diff --git a/53_King/csharp/Resources/Harvest.txt b/53_King/csharp/Resources/Harvest.txt index 7cedf658..287e0c42 100644 --- a/53_King/csharp/Resources/Harvest.txt +++ b/53_King/csharp/Resources/Harvest.txt @@ -1,2 +1,2 @@ you harvested {0} sq. miles of crops. -{1}making {2} rallods. \ No newline at end of file +{1}making {2} rallods. diff --git a/53_King/csharp/Resources/Resource.cs b/53_King/csharp/Resources/Resource.cs index 9fd56b8d..5ea09e1c 100644 --- a/53_King/csharp/Resources/Resource.cs +++ b/53_King/csharp/Resources/Resource.cs @@ -68,7 +68,9 @@ internal static class Resource => string.Format(GetString(), yield, HarvestReason(hasIndustry), income); private static string HarvestReason(bool hasIndustry) => hasIndustry ? GetString() : ""; - private static string PollutionEffect(IRandom random) => GetStrings()[random.Next(5)]; + public static string TourismEarnings(int income) => string.Format(GetString(), income); + public static string TourismDecrease(IRandom random) => string.Format(GetString(), TourismReason(random)); + private static string TourismReason(IRandom random) => GetStrings()[random.Next(5)]; private static string EndAlso(IRandom random) => random.Next(10) switch @@ -82,7 +84,7 @@ internal static class Resource private static string EndConsequences(IRandom random) => GetStrings()[random.Next(2)]; public static string EndForeignWorkers(IRandom random) => string.Format(GetString(), EndConsequences(random)); public static string EndManyDead(int deaths, IRandom random) => string.Format(GetString(), deaths, EndAlso(random)); - public static string EndMoneyLeftOver(int termLength) => string.Format(GetString(), termLength); + public static string EndMoneyLeftOver() => GetString(); public static string EndOneThirdDead(IRandom random) => string.Format(GetString(), EndConsequences(random)); public static string SavedYearsPrompt => GetString(); @@ -104,7 +106,6 @@ internal static class Resource return reader.ReadToEnd(); } - private static Stream GetStream([CallerMemberName] string? name = null) => Assembly.GetExecutingAssembly().GetManifestResourceStream($"{typeof(Resource).Namespace}.{name}.txt") ?? throw new Exception($"Could not find embedded resource stream '{name}'."); diff --git a/53_King/csharp/Resources/TourismDecrease.txt b/53_King/csharp/Resources/TourismDecrease.txt new file mode 100644 index 00000000..dcb45fc7 --- /dev/null +++ b/53_King/csharp/Resources/TourismDecrease.txt @@ -0,0 +1 @@ + Decrease because {0} \ No newline at end of file diff --git a/53_King/csharp/Resources/TourismEarnings.txt b/53_King/csharp/Resources/TourismEarnings.txt new file mode 100644 index 00000000..db9251dd --- /dev/null +++ b/53_King/csharp/Resources/TourismEarnings.txt @@ -0,0 +1 @@ + You made {0} rallods from tourist trade. \ No newline at end of file diff --git a/53_King/csharp/Resources/PollutionEffect.txt b/53_King/csharp/Resources/TourismReason.txt similarity index 100% rename from 53_King/csharp/Resources/PollutionEffect.txt rename to 53_King/csharp/Resources/TourismReason.txt diff --git a/53_King/csharp/Result.cs b/53_King/csharp/Result.cs new file mode 100644 index 00000000..185f4617 --- /dev/null +++ b/53_King/csharp/Result.cs @@ -0,0 +1,7 @@ +namespace King; + +internal record struct Result (bool IsGameOver, string Message) +{ + internal static Result GameOver(string message) => new(true, message); + internal static Result Continue => new(false, ""); +} diff --git a/53_King/csharp/Year.cs b/53_King/csharp/Year.cs index 526db454..8e6bb0b4 100644 --- a/53_King/csharp/Year.cs +++ b/53_King/csharp/Year.cs @@ -17,13 +17,15 @@ internal class Year private float _citizenSupport; private int _deaths; + private float _starvationDeaths; private int _pollutionDeaths; - + private int _migration; public Year(Country country, IRandom random, IReadWrite io) { _country = country; _random = random; + _io = io; _plantingCost = random.Next(10, 15); _landValue = random.Next(95, 105); @@ -31,34 +33,41 @@ internal class Year public string Status => _country.GetStatus(_landValue, _plantingCost); - public bool GetPlayerActions() + public Result? GetPlayerActions() { var playerSoldLand = _country.SellLand(_landValue, out _landSold); var playerDistributedRallods = _country.DistributeRallods(out _rallodsDistributed); var playerPlantedLand = _country.HasRallods && _country.PlantLand(_plantingCost, out _landPlanted); var playerControlledPollution = _country.HasRallods && _country.ControlPollution(out _pollutionControlCost); - return playerSoldLand || playerDistributedRallods || playerPlantedLand || playerControlledPollution; + return playerSoldLand || playerDistributedRallods || playerPlantedLand || playerControlledPollution + ? null + : Result.GameOver(Goodbye); } - public Result EvaluateResults() + public Result? EvaluateResults() { - var unspentRallods = _country.Rallods; + var rallodsUnspent = _country.Rallods; - var result = EvaluateDeaths(); + _io.WriteLine(); + _io.WriteLine(); - return Result.Continue; + return EvaluateDeaths() + ?? EvaluateMigration() + ?? EvaluateAgriculture() + ?? EvaluateTourism() + ?? DetermineResult(rallodsUnspent); } public Result? EvaluateDeaths() { var supportedCountrymen = _rallodsDistributed / 100; _citizenSupport = supportedCountrymen - _country.Countrymen; - var starvationDeaths = -_citizenSupport; - if (starvationDeaths > 0) + _starvationDeaths = -_citizenSupport; + if (_starvationDeaths > 0) { if (supportedCountrymen < 50) { return Result.GameOver(EndOneThirdDead(_random)); } - _io.WriteLine(DeathsStarvation(starvationDeaths)); + _io.WriteLine(DeathsStarvation(_starvationDeaths)); } var pollutionControl = _pollutionControlCost >= 25 ? _pollutionControlCost / 25 : 1; @@ -68,7 +77,7 @@ internal class Year _io.WriteLine(DeathsPollution(_pollutionDeaths)); } - _deaths = (int)(starvationDeaths + _pollutionDeaths); + _deaths = (int)(_starvationDeaths + _pollutionDeaths); if (_deaths > 0) { var funeralCosts = _deaths * 9; @@ -95,10 +104,10 @@ internal class Year _country.AddWorkers(newWorkers); } - var migration = + _migration = (int)(_citizenSupport / 10 + _pollutionControlCost / 25 - _country.IndustryLand / 50 - _pollutionDeaths / 2); - _io.WriteLine(Migration(migration)); - _country.Migration(migration); + _io.WriteLine(Migration(_migration)); + _country.Migration(_migration); return null; } @@ -117,10 +126,29 @@ internal class Year return null; } - internal record struct Result (bool IsGameOver, string Message) + private Result? EvaluateTourism() { - internal static Result GameOver(string message) => new(true, message); - internal static Result Continue => new(false, ""); + var reputationValue = (int)((_country.Countrymen - _migration) * 22 + _random.NextFloat(500)); + var industryAdjustment = (int)(_country.IndustryLand * 15); + var tourismIncome = Math.Abs(reputationValue - industryAdjustment); + + _io.WriteLine(TourismEarnings(tourismIncome)); + if (industryAdjustment > 0 && tourismIncome < _country.PreviousTourismIncome) + { + _io.Write(TourismDecrease(_random)); + } + + _country.EntertainTourists(tourismIncome); + + return null; + } + + private Result? DetermineResult(float rallodsUnspent) + { + if (_deaths > 200) { return Result.GameOver(EndManyDead(_deaths, _random)); } + if (_country.Countrymen < 343) { return Result.GameOver(EndOneThirdDead(_random)); } + if (rallodsUnspent / 100 > 5 && _starvationDeaths >= 2) { return Result.GameOver(EndMoneyLeftOver()); } + if (_country.Workers > _country.Countrymen) { return Result.GameOver(EndForeignWorkers(_random)); } + return null; } } -