Merge pull request #831 from drewjcooper/csharp-53-king

C# 53 king
This commit is contained in:
Jeff Atwood
2023-02-04 12:02:08 -08:00
committed by GitHub
55 changed files with 735 additions and 2 deletions

View File

@@ -1,10 +1,10 @@
## King ## King
This is one of the most comprehensive, difficult, and interesting games. (If youve 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. 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 countrys 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 isnt 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. 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: but it should be:
1997 PRINT " AND 1,000 SQ. MILES OF FOREST LAND." 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

133
53_King/csharp/Country.cs Normal file
View File

@@ -0,0 +1,133 @@
namespace King;
internal class Country
{
private const int InitialLand = 1000;
private readonly IReadWrite _io;
private readonly IRandom _random;
private float _rallods;
private float _countrymen;
private float _foreigners;
private float _arableLand;
private float _industryLand;
public Country(IReadWrite io, IRandom random)
: this(
io,
random,
(int)(60000 + random.NextFloat(1000) - random.NextFloat(1000)),
(int)(500 + random.NextFloat(10) - random.NextFloat(10)),
0,
InitialLand)
{
}
public Country(IReadWrite io, IRandom random, float rallods, float countrymen, float foreigners, float land)
{
_io = io;
_random = random;
_rallods = rallods;
_countrymen = countrymen;
_foreigners = foreigners;
_arableLand = land;
}
public string GetStatus(int landValue, int plantingCost)
=> 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)
{
if (_io.TryReadValue(
SellLandPrompt,
out landSold,
new ValidityTest(v => v <= FarmLand, () => SellLandError(FarmLand))))
{
_arableLand = (int)(_arableLand - landSold);
_rallods = (int)(_rallods + landSold * landValue);
return true;
}
return false;
}
public bool DistributeRallods(out float rallodsGiven)
{
if (_io.TryReadValue(
GiveRallodsPrompt,
out rallodsGiven,
new ValidityTest(v => v <= _rallods, () => GiveRallodsError(_rallods))))
{
_rallods = (int)(_rallods - rallodsGiven);
return true;
}
return false;
}
public bool PlantLand(int plantingCost, out float landPlanted)
{
if (_io.TryReadValue(
PlantLandPrompt,
out landPlanted,
new ValidityTest(v => v <= _countrymen * 2, PlantLandError1),
new ValidityTest(v => v <= FarmLand, PlantLandError2(FarmLand)),
new ValidityTest(v => v * plantingCost <= _rallods, PlantLandError3(_rallods))))
{
_rallods -= (int)(landPlanted * plantingCost);
return true;
}
return false;
}
public bool ControlPollution(out float rallodsSpent)
{
if (_io.TryReadValue(
PollutionPrompt,
out rallodsSpent,
new ValidityTest(v => v <= _rallods, () => PollutionError(_rallods))))
{
_rallods = (int)(_rallods - rallodsSpent);
return true;
}
return false;
}
public bool TrySpend(float amount, float landValue)
{
if (_rallods >= amount)
{
_rallods -= amount;
return true;
}
_arableLand = (int)(_arableLand - (int)(amount - _rallods) / landValue);
_rallods = 0;
return false;
}
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);
public void EntertainTourists(int income)
{
PreviousTourismIncome = income;
_rallods = (int)(_rallods + income);
}
}

47
53_King/csharp/Game.cs Normal file
View File

@@ -0,0 +1,47 @@
namespace King;
internal class Game
{
const int TermOfOffice = 8;
private readonly IReadWrite _io;
private readonly IRandom _random;
public Game(IReadWrite io, IRandom random)
{
_io = io;
_random = random;
}
public void Play()
{
_io.Write(Title);
var reign = SetUpReign();
if (reign != null)
{
while (reign.PlayYear());
}
_io.WriteLine();
_io.WriteLine();
}
private Reign? SetUpReign()
{
var response = _io.ReadString(InstructionsPrompt).ToUpper();
if (response.Equals("Again", StringComparison.InvariantCultureIgnoreCase))
{
return _io.TryReadGameData(_random, out var reign) ? reign : null;
}
if (!response.StartsWith("N", StringComparison.InvariantCultureIgnoreCase))
{
_io.Write(InstructionsText(TermOfOffice));
}
_io.WriteLine();
return new Reign(_io, _random);
}
}

View File

@@ -0,0 +1,61 @@
using System.Diagnostics.CodeAnalysis;
using static King.Resources.Resource;
namespace King;
internal static class IOExtensions
{
internal static bool TryReadGameData(this IReadWrite io, IRandom random, [NotNullWhen(true)] out Reign? reign)
{
if (io.TryReadValue(SavedYearsPrompt, v => v < Reign.MaxTerm, SavedYearsError(Reign.MaxTerm), out var years) &&
io.TryReadValue(SavedTreasuryPrompt, out var rallods) &&
io.TryReadValue(SavedCountrymenPrompt, out var countrymen) &&
io.TryReadValue(SavedWorkersPrompt, out var workers) &&
io.TryReadValue(SavedLandPrompt, v => v is > 1000 and <= 2000, SavedLandError, out var land))
{
reign = new Reign(io, random, new Country(io, random, rallods, countrymen, workers, land), years + 1);
return true;
}
reign = default;
return false;
}
internal static bool TryReadValue(this IReadWrite io, string prompt, out float value, params ValidityTest[] tests)
{
while (true)
{
var response = value = io.ReadNumber(prompt);
if (response == 0) { return false; }
if (tests.All(test => test.IsValid(response, io))) { return true; }
}
}
internal static bool TryReadValue(this IReadWrite io, string prompt, out float value)
=> io.TryReadValue(prompt, _ => true, "", out value);
internal static bool TryReadValue(
this IReadWrite io,
string prompt,
Predicate<float> isValid,
string error,
out float value)
=> io.TryReadValue(prompt, isValid, () => error, out value);
internal static bool TryReadValue(
this IReadWrite io,
string prompt,
Predicate<float> isValid,
Func<string> getError,
out float value)
{
while (true)
{
value = io.ReadNumber(prompt);
if (value < 0) { return false; }
if (isValid(value)) { return true; }
io.Write(getError());
}
}
}

View File

@@ -6,4 +6,12 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Resources/*.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\00_Common\dotnet\Games.Common\Games.Common.csproj" />
</ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,7 @@
global using Games.Common.IO;
global using Games.Common.Randomness;
global using King.Resources;
global using static King.Resources.Resource;
using King;
new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();

45
53_King/csharp/Reign.cs Normal file
View File

@@ -0,0 +1,45 @@
namespace King;
internal class Reign
{
public const int MaxTerm = 8;
private readonly IReadWrite _io;
private readonly IRandom _random;
private readonly Country _country;
private float _yearNumber;
public Reign(IReadWrite io, IRandom random)
: this(io, random, new Country(io, random), 1)
{
}
public Reign(IReadWrite io, IRandom random, Country country, float year)
{
_io = io;
_random = random;
_country = country;
_yearNumber = year;
}
public bool PlayYear()
{
var year = new Year(_country, _random, _io);
_io.Write(year.Status);
var result = year.GetPlayerActions() ?? year.EvaluateResults() ?? IsAtEndOfTerm();
if (result.IsGameOver)
{
_io.WriteLine(result.Message);
return false;
}
return true;
}
private Result IsAtEndOfTerm()
=> _yearNumber == MaxTerm
? Result.GameOver(EndCongratulations(MaxTerm))
: Result.Continue;
}

View File

@@ -0,0 +1 @@
{0} countrymen died of carbon-monoxide and dust inhalation

View File

@@ -0,0 +1 @@
{0} countrymen died of starvation

View File

@@ -0,0 +1 @@
{0} countrymen left the island.

View File

@@ -0,0 +1,3 @@
also had your left eye gouged out!
;have also gained a very bad reputation.
;have also been declared national fink.

View File

@@ -0,0 +1,10 @@
Congratulations!!!!!!!!!!!!!!!!!!
You have successfully completed your {0} year term
of office. You were, of course, extremely lucky, but
nevertheless, it's quite an achievement. Goodbye and good
luck - you'll probably need it if you're the type that
plays this game.

View File

@@ -0,0 +1,3 @@
You have been thrown out of office and are now
residing in prison.;
You have been assassinated.

View File

@@ -0,0 +1,7 @@
The number of foreign workers has exceeded the number
of countrymen. As a minority, they have revolted and
taken over the country.
{0}

View File

@@ -0,0 +1,5 @@
{0} countrymen died in one year!!!!!
due to this extreme mismanagement, you have not only
been impeached and thrown out of office, but you
{1}

View File

@@ -0,0 +1,7 @@
Money was left over in the treasury which you did
not spend. As a result, some of your countrymen died
of starvation. The public is enraged and you have
been forced to resign.

View File

@@ -0,0 +1,7 @@
Over one third of the population has died since you
were elected to office. The people (remaining)
hate your guts.
{0}

View File

@@ -0,0 +1 @@
You were forced to spend {0} rallods on funeral expenses

View File

@@ -0,0 +1 @@
Think again. You've only got {0} rallods in the treasury.

View File

@@ -0,0 +1 @@
How many rallods will you distribute among your countrymen

View File

@@ -0,0 +1,4 @@
Goodbye.
(If you wish to continue this game at a later date, answer
'again' when asked if you want instructions at the start
of the game).

View File

@@ -0,0 +1,2 @@
you harvested {0} sq. miles of crops.
{1}making {2} rallods.

View File

@@ -0,0 +1 @@
(Due to increased air and water pollution from foreign industry.)

View File

@@ -0,0 +1 @@
{0} countrymen came to the island.

View File

@@ -0,0 +1 @@
Do you want instructions

View File

@@ -0,0 +1,17 @@
Congratulations! You've just been elected Premier of Setats
Detinu, a small communist island 30 by 70 miles long. Your
job is to decide upon the country's budget and distribute
money to your countrymen from the communal treasury.
The money system is rallods, and 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. Half your land if farm land
which also has an excellent mineral content and may be sold
to foreign industry (strip mining) who import and support
their own workers. Crops cost between 10 and 15 rallods per
square mile to plant.
Your goal is to complete your {0} year term of office.
Good luck!

View File

@@ -0,0 +1 @@
Of {0} sq. miles planted,

View File

@@ -0,0 +1 @@
Sorry, but each countryman can only plant 2 sq. miles.

View File

@@ -0,0 +1 @@
Sorry, but you've only {0} sq. miles of farm land.

View File

@@ -0,0 +1 @@
Think again, You've only {0} rallods left in the treasury.

View File

@@ -0,0 +1 @@
How many square miles do you wish to plant

View File

@@ -0,0 +1 @@
Think again. You only have {0} rallods remaining.

View File

@@ -0,0 +1 @@
How many rallods do you wish to spend on pollution control

View File

@@ -0,0 +1,112 @@
using System.Reflection;
using System.Runtime.CompilerServices;
namespace King.Resources;
internal static class Resource
{
private static bool _sellLandErrorShown;
public static Stream Title => GetStream();
public static string InstructionsPrompt => GetString();
public static string InstructionsText(int years) => string.Format(GetString(), years);
public static string Status(
float rallods,
float countrymen,
float workers,
float land,
float landValue,
float plantingCost)
=> string.Format(
workers == 0 ? StatusWithWorkers : StatusSansWorkers,
rallods,
(int)countrymen,
(int)workers,
(int)land,
landValue,
plantingCost);
private static string StatusWithWorkers => GetString();
private static string StatusSansWorkers => GetString();
public static string SellLandPrompt => GetString();
public static string SellLandError(float farmLand)
{
var error = string.Format(GetString(), farmLand, _sellLandErrorShown ? "" : SellLandErrorReason);
_sellLandErrorShown = true;
return error;
}
private static string SellLandErrorReason => GetString();
public static string GiveRallodsPrompt => GetString();
public static string GiveRallodsError(float rallods) => string.Format(GetString(), rallods);
public static string PlantLandPrompt => GetString();
public static string PlantLandError1 => GetString();
public static string PlantLandError2(float farmLand) => string.Format(GetString(), farmLand);
public static string PlantLandError3(float rallods) => string.Format(GetString(), rallods);
public static string PollutionPrompt => GetString();
public static string PollutionError(float rallods) => string.Format(GetString(), rallods);
public static string DeathsStarvation(float deaths) => string.Format(GetString(), (int)deaths);
public static string DeathsPollution(int deaths) => string.Format(GetString(), deaths);
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() : "";
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
{
<= 3 => GetStrings()[0],
<= 6 => GetStrings()[1],
_ => GetStrings()[2]
};
public static string EndCongratulations(int termLength) => string.Format(GetString(), termLength);
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() => GetString();
public static string EndOneThirdDead(IRandom random) => string.Format(GetString(), EndConsequences(random));
public static string SavedYearsPrompt => GetString();
public static string SavedYearsError(int years) => string.Format(GetString(), years);
public static string SavedTreasuryPrompt => GetString();
public static string SavedCountrymenPrompt => GetString();
public static string SavedWorkersPrompt => GetString();
public static string SavedLandPrompt => GetString();
public static string SavedLandError => GetString();
public static string Goodbye => GetString();
private static string[] GetStrings([CallerMemberName] string? name = null) => GetString(name).Split(';');
private static string GetString([CallerMemberName] string? name = null)
{
using var stream = GetStream(name);
using var reader = new StreamReader(stream);
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}'.");
}

View File

@@ -0,0 +1 @@
How many countrymen

View File

@@ -0,0 +1,2 @@
Come on, you started with 1000 sq. miles of farm land
and 10,000 sq. miles of forest land

View File

@@ -0,0 +1 @@
How many square miles of land

View File

@@ -0,0 +1 @@
How much did you have in the treasury

View File

@@ -0,0 +1 @@
How many workers

View File

@@ -0,0 +1 @@
Come on, your term in office is only {0} years.

View File

@@ -0,0 +1 @@
How many years had you been in office when interrupted

View File

@@ -0,0 +1,2 @@
*** Think again. You only have {0} square miles of farm land.
{1}

View File

@@ -0,0 +1,4 @@
(Foreign industry will only buy farm land because
forest land is uneconomical to strip mine due to trees,
thicker top soil, etc.)

View File

@@ -0,0 +1 @@
How many square miles do you wish to sell to industry

View File

@@ -0,0 +1,6 @@
You now have {0} rallods in the treasury.
{1} countrymen, and {3} sq. miles of land.
This year industry will buy land for {4} rallods per square mile.
Land currently costs {5} rallods per square mile to plant.

View File

@@ -0,0 +1,6 @@
You now have {0} rallods in the treasury.
{1} countrymen, {2} foreign workers and {3} sq. miles of land.
This year industry will buy land for {4} rallods per square mile.
Land currently costs {5} rallods per square mile to plant.

View File

@@ -0,0 +1,5 @@
King
Creative Computing Morristown, New Jersey

View File

@@ -0,0 +1 @@
Decrease because {0}

View File

@@ -0,0 +1 @@
You made {0} rallods from tourist trade.

View File

@@ -0,0 +1,5 @@
fish population has dwindled due to water pollution.
;air pollution is killing game bird population.
;mineral baths are being ruined by water pollution.
;unpleasant smog is discouraging sun bathers.
;hotels are looking shabby due to smog grit.

View File

@@ -0,0 +1 @@
{0} workers came to the country and

7
53_King/csharp/Result.cs Normal file
View File

@@ -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, "");
}

View File

@@ -0,0 +1,26 @@
namespace King;
internal class ValidityTest
{
private readonly Predicate<float> _isValid;
private readonly Func<string> _getError;
public ValidityTest(Predicate<float> isValid, string error)
: this(isValid, () => error)
{
}
public ValidityTest(Predicate<float> isValid, Func<string> getError)
{
_isValid = isValid;
_getError = getError;
}
public bool IsValid(float value, IReadWrite io)
{
if (_isValid(value)) { return true; }
io.Write(_getError());
return false;
}
}

154
53_King/csharp/Year.cs Normal file
View File

@@ -0,0 +1,154 @@
using System.Text;
namespace King;
internal class Year
{
private readonly Country _country;
private readonly IRandom _random;
private readonly IReadWrite _io;
private readonly int _plantingCost;
private readonly int _landValue;
private float _landSold;
private float _rallodsDistributed;
private float _landPlanted;
private float _pollutionControlCost;
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);
}
public string Status => _country.GetStatus(_landValue, _plantingCost);
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
? null
: Result.GameOver(Goodbye);
}
public Result? EvaluateResults()
{
var rallodsUnspent = _country.Rallods;
_io.WriteLine();
_io.WriteLine();
return EvaluateDeaths()
?? EvaluateMigration()
?? EvaluateAgriculture()
?? EvaluateTourism()
?? DetermineResult(rallodsUnspent);
}
public Result? EvaluateDeaths()
{
var supportedCountrymen = _rallodsDistributed / 100;
_citizenSupport = supportedCountrymen - _country.Countrymen;
_starvationDeaths = -_citizenSupport;
if (_starvationDeaths > 0)
{
if (supportedCountrymen < 50) { return Result.GameOver(EndOneThirdDead(_random)); }
_io.WriteLine(DeathsStarvation(_starvationDeaths));
}
var pollutionControl = _pollutionControlCost >= 25 ? _pollutionControlCost / 25 : 1;
_pollutionDeaths = (int)(_random.Next((int)_country.IndustryLand) / pollutionControl);
if (_pollutionDeaths > 0)
{
_io.WriteLine(DeathsPollution(_pollutionDeaths));
}
_deaths = (int)(_starvationDeaths + _pollutionDeaths);
if (_deaths > 0)
{
var funeralCosts = _deaths * 9;
_io.WriteLine(FuneralExpenses(funeralCosts));
if (!_country.TrySpend(funeralCosts, _landValue))
{
_io.WriteLine(InsufficientReserves);
}
_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);
}
_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;
}
private Result? EvaluateTourism()
{
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;
}
}