diff --git a/53_King/README.md b/53_King/README.md index a363a2be..14a66fe9 100644 --- a/53_King/README.md +++ b/53_King/README.md @@ -1,10 +1,10 @@ ## King -This is one of the most comprehensive, difficult, and interesting games. (If you’ve never played one of these games, start with HAMMURABI.) +This is one of the most comprehensive, difficult, and interesting games. (If you've never played one of these games, start with HAMMURABI.) In this game, you are Premier of Setats Detinu, a small communist island 30 by 70 miles long. Your job is to decide upon the budget of your country and distribute money to your country from the communal treasury. -The money system is Rollods; each person needs 100 Rallods per year to survive. Your country’s income comes from farm produce and tourists visiting your magnificent forests, hunting, fishing, etc. Part of your land is farm land but it also has an excellent mineral content and may be sold to foreign industry for strip mining. Industry import and support their own workers. Crops cost between 10 and 15 Rallods per square mile to plant, cultivate, and harvest. Your goal is to complete an eight-year term of office without major mishap. A word of warning: it isn’t easy! +The money system is Rollods; each person needs 100 Rallods per year to survive. Your country's income comes from farm produce and tourists visiting your magnificent forests, hunting, fishing, etc. Part of your land is farm land but it also has an excellent mineral content and may be sold to foreign industry for strip mining. Industry import and support their own workers. Crops cost between 10 and 15 Rallods per square mile to plant, cultivate, and harvest. Your goal is to complete an eight-year term of office without major mishap. A word of warning: it isn't easy! The author of this program is James A. Storer who wrote it while a student at Lexington High School. @@ -66,3 +66,15 @@ On basic line 1997 it is: but it should be: 1997 PRINT " AND 1,000 SQ. MILES OF FOREST LAND." + +### Bug 4 + +On basic line 1310 we see this: + + 1310 IF C=0 THEN 1324 + 1320 PRINT "OF ";INT(J);"SQ. MILES PLANTED,"; + 1324 ... + +but it should probably be: + + 1310 IF J=0 THEN 1324 diff --git a/53_King/csharp/Country.cs b/53_King/csharp/Country.cs index b1b473e7..d1ba9235 100644 --- a/53_King/csharp/Country.cs +++ b/53_King/csharp/Country.cs @@ -37,6 +37,7 @@ internal class Country => Resource.Status(_rallods, _countrymen, _foreigners, _arableLand, landValue, plantingCost); public float Countrymen => _countrymen; + public bool HasWorkers => _foreigners > 0; private float FarmLand => _arableLand; public bool HasRallods => _rallods > 0; public float Rallods => _rallods; @@ -115,4 +116,10 @@ internal class Country } public void RemoveTheDead(int deaths) => _countrymen = (int)(_countrymen - deaths); + + public void Migration(int migration) => _countrymen = (int)(_countrymen + migration); + + public void AddWorkers(int newWorkers) => _foreigners = (int)(_foreigners + newWorkers); + + public void SellCrops(int income) => _rallods = (int)(_rallods + income); } diff --git a/53_King/csharp/Reign.cs b/53_King/csharp/Reign.cs index 727f71d3..1955c81b 100644 --- a/53_King/csharp/Reign.cs +++ b/53_King/csharp/Reign.cs @@ -24,7 +24,7 @@ internal class Reign public bool PlayYear() { - var year = new Year(_country, _random); + var year = new Year(_country, _random, _io); _io.Write(year.Status); @@ -32,7 +32,7 @@ internal class Reign { _io.WriteLine(); _io.WriteLine(); - year.EvaluateResults(_io, _random); + year.EvaluateResults(); _yearNumber++; return true; } diff --git a/53_King/csharp/Resources/Emigration.txt b/53_King/csharp/Resources/Emigration.txt new file mode 100644 index 00000000..01f67094 --- /dev/null +++ b/53_King/csharp/Resources/Emigration.txt @@ -0,0 +1 @@ + {0} countrymen left the island. \ No newline at end of file diff --git a/53_King/csharp/Resources/Harvest.txt b/53_King/csharp/Resources/Harvest.txt new file mode 100644 index 00000000..7cedf658 --- /dev/null +++ b/53_King/csharp/Resources/Harvest.txt @@ -0,0 +1,2 @@ + you harvested {0} sq. miles of crops. +{1}making {2} rallods. \ No newline at end of file diff --git a/53_King/csharp/Resources/HarvestReason.txt b/53_King/csharp/Resources/HarvestReason.txt new file mode 100644 index 00000000..82faccb5 --- /dev/null +++ b/53_King/csharp/Resources/HarvestReason.txt @@ -0,0 +1 @@ + (Due to increased air and water pollution from foreign industry.) diff --git a/53_King/csharp/Resources/Immigration.txt b/53_King/csharp/Resources/Immigration.txt new file mode 100644 index 00000000..30d8b6b3 --- /dev/null +++ b/53_King/csharp/Resources/Immigration.txt @@ -0,0 +1 @@ + {0} countrymen came to the island. \ No newline at end of file diff --git a/53_King/csharp/Resources/LandPlanted.txt b/53_King/csharp/Resources/LandPlanted.txt new file mode 100644 index 00000000..e52529aa --- /dev/null +++ b/53_King/csharp/Resources/LandPlanted.txt @@ -0,0 +1 @@ +Of {0} sq. miles planted, \ No newline at end of file diff --git a/53_King/csharp/Resources/Resource.cs b/53_King/csharp/Resources/Resource.cs index 496bc250..9fd56b8d 100644 --- a/53_King/csharp/Resources/Resource.cs +++ b/53_King/csharp/Resources/Resource.cs @@ -56,6 +56,18 @@ internal static class Resource public static string FuneralExpenses(int expenses) => string.Format(GetString(), expenses); public static string InsufficientReserves => GetString(); + public static string WorkerMigration(int newWorkers) => string.Format(GetString(), newWorkers); + public static string Migration(int migration) + => string.Format(migration < 0 ? Emigration : Immigration, Math.Abs(migration)); + public static string Emigration => GetString(); + public static string Immigration => GetString(); + + public static string LandPlanted(float landPlanted) + => landPlanted > 0 ? string.Format(GetString(), (int)landPlanted) : ""; + public static string Harvest(int yield, int income, bool hasIndustry) + => 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)]; private static string EndAlso(IRandom random) diff --git a/53_King/csharp/Resources/WorkerMigration.txt b/53_King/csharp/Resources/WorkerMigration.txt new file mode 100644 index 00000000..d2f3b378 --- /dev/null +++ b/53_King/csharp/Resources/WorkerMigration.txt @@ -0,0 +1 @@ + {0} workers came to the country and \ No newline at end of file diff --git a/53_King/csharp/Year.cs b/53_King/csharp/Year.cs index 18f208e4..526db454 100644 --- a/53_King/csharp/Year.cs +++ b/53_King/csharp/Year.cs @@ -6,6 +6,7 @@ internal class Year { private readonly Country _country; private readonly IRandom _random; + private readonly IReadWrite _io; private readonly int _plantingCost; private readonly int _landValue; @@ -14,7 +15,12 @@ internal class Year private float _landPlanted; private float _pollutionControlCost; - public Year(Country country, IRandom random) + private float _citizenSupport; + private int _deaths; + private int _pollutionDeaths; + + + public Year(Country country, IRandom random, IReadWrite io) { _country = country; _random = random; @@ -35,54 +41,81 @@ internal class Year return playerSoldLand || playerDistributedRallods || playerPlantedLand || playerControlledPollution; } - public Result EvaluateResults(IReadWrite io) + public Result EvaluateResults() { var unspentRallods = _country.Rallods; - var statusUpdate = new StringBuilder(); - var result = EvaluateDeaths(statusUpdate, out var deaths); - - io.Write(statusUpdate); + var result = EvaluateDeaths(); return Result.Continue; } - public Result? EvaluateDeaths(StringBuilder statusUpdate, out int deaths) + public Result? EvaluateDeaths() { - deaths = default; - var supportedCountrymen = _rallodsDistributed / 100; - var starvationDeaths = _country.Countrymen - supportedCountrymen; + _citizenSupport = supportedCountrymen - _country.Countrymen; + var starvationDeaths = -_citizenSupport; if (starvationDeaths > 0) { if (supportedCountrymen < 50) { return Result.GameOver(EndOneThirdDead(_random)); } - statusUpdate.AppendLine(DeathsStarvation(starvationDeaths)); + _io.WriteLine(DeathsStarvation(starvationDeaths)); } var pollutionControl = _pollutionControlCost >= 25 ? _pollutionControlCost / 25 : 1; - var pollutionDeaths = (int)(_random.Next((int)_country.IndustryLand) / pollutionControl); - if (pollutionDeaths > 0) + _pollutionDeaths = (int)(_random.Next((int)_country.IndustryLand) / pollutionControl); + if (_pollutionDeaths > 0) { - statusUpdate.AppendLine(DeathsPollution(pollutionDeaths)); + _io.WriteLine(DeathsPollution(_pollutionDeaths)); } - deaths = (int)(starvationDeaths + pollutionDeaths); - if (deaths > 0) + _deaths = (int)(starvationDeaths + _pollutionDeaths); + if (_deaths > 0) { - var funeralCosts = deaths * 9; - statusUpdate.AppendLine(FuneralExpenses(funeralCosts)); + var funeralCosts = _deaths * 9; + _io.WriteLine(FuneralExpenses(funeralCosts)); if (!_country.TrySpend(funeralCosts, _landValue)) { - statusUpdate.AppendLine(InsufficientReserves); + _io.WriteLine(InsufficientReserves); } - _country.RemoveTheDead(deaths); + _country.RemoveTheDead(_deaths); } return null; } + private Result? EvaluateMigration() + { + if (_landSold > 0) + { + var newWorkers = (int)(_landSold + _random.NextFloat(10) - _random.NextFloat(20)); + if (!_country.HasWorkers) { newWorkers += 20; } + _io.Write(WorkerMigration(newWorkers)); + _country.AddWorkers(newWorkers); + } + + var migration = + (int)(_citizenSupport / 10 + _pollutionControlCost / 25 - _country.IndustryLand / 50 - _pollutionDeaths / 2); + _io.WriteLine(Migration(migration)); + _country.Migration(migration); + + return null; + } + + private Result? EvaluateAgriculture() + { + var ruinedCrops = (int)Math.Min(_country.IndustryLand * (_random.NextFloat() + 1.5f) / 2, _landPlanted); + var yield = (int)(_landPlanted - ruinedCrops); + var income = (int)(yield * _landValue / 2f); + + _io.Write(LandPlanted(_landPlanted)); + _io.Write(Harvest(yield, income, _country.IndustryLand > 0)); + + _country.SellCrops(income); + + return null; + } internal record struct Result (bool IsGameOver, string Message) {