mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-24 20:10:15 -08:00
Add evaluation of deaths
This commit is contained in:
@@ -2,14 +2,15 @@ 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 _land;
|
||||
private float _plantingCost;
|
||||
private float _landValue;
|
||||
private float _arableLand;
|
||||
private float _industryLand;
|
||||
|
||||
public Country(IReadWrite io, IRandom random)
|
||||
: this(
|
||||
@@ -18,7 +19,7 @@ internal class Country
|
||||
(int)(60000 + random.NextFloat(1000) - random.NextFloat(1000)),
|
||||
(int)(500 + random.NextFloat(10) - random.NextFloat(10)),
|
||||
0,
|
||||
2000)
|
||||
InitialLand)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,35 +30,38 @@ internal class Country
|
||||
_rallods = rallods;
|
||||
_countrymen = countrymen;
|
||||
_foreigners = foreigners;
|
||||
_land = land;
|
||||
|
||||
_plantingCost = random.Next(10, 15);
|
||||
_landValue = random.Next(95, 105);
|
||||
_arableLand = land;
|
||||
}
|
||||
|
||||
public string Status => Resource.Status(_rallods, _countrymen, _foreigners, _land, _landValue, _plantingCost);
|
||||
private float FarmLand => _land - 1000;
|
||||
public string GetStatus(int landValue, int plantingCost)
|
||||
=> Resource.Status(_rallods, _countrymen, _foreigners, _arableLand, landValue, plantingCost);
|
||||
|
||||
public float Countrymen => _countrymen;
|
||||
private float FarmLand => _arableLand;
|
||||
public bool HasRallods => _rallods > 0;
|
||||
public float Rallods => _rallods;
|
||||
public float IndustryLand => InitialLand - _arableLand;
|
||||
|
||||
public bool SellLand()
|
||||
public bool SellLand(int landValue, out float landSold)
|
||||
{
|
||||
if (_io.TryReadValue(
|
||||
SellLandPrompt,
|
||||
out var landSold,
|
||||
out landSold,
|
||||
new ValidityTest(v => v <= FarmLand, () => SellLandError(FarmLand))))
|
||||
{
|
||||
_land = (int)(_land - landSold);
|
||||
_rallods = (int)(_rallods + landSold * _landValue);
|
||||
_arableLand = (int)(_arableLand - landSold);
|
||||
_rallods = (int)(_rallods + landSold * landValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DistributeRallods()
|
||||
public bool DistributeRallods(out float rallodsGiven)
|
||||
{
|
||||
if (_io.TryReadValue(
|
||||
GiveRallodsPrompt,
|
||||
out var rallodsGiven,
|
||||
out rallodsGiven,
|
||||
new ValidityTest(v => v <= _rallods, () => GiveRallodsError(_rallods))))
|
||||
{
|
||||
_rallods = (int)(_rallods - rallodsGiven);
|
||||
@@ -67,35 +71,48 @@ internal class Country
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PlantLand()
|
||||
public bool PlantLand(int plantingCost, out float landPlanted)
|
||||
{
|
||||
if (_rallods > 0 &&
|
||||
_io.TryReadValue(
|
||||
if (_io.TryReadValue(
|
||||
PlantLandPrompt,
|
||||
out var landPlanted,
|
||||
out landPlanted,
|
||||
new ValidityTest(v => v <= _countrymen * 2, PlantLandError1),
|
||||
new ValidityTest(v => v <= FarmLand, PlantLandError2(FarmLand)),
|
||||
new ValidityTest(v => v * _plantingCost <= _rallods, PlantLandError3(_rallods))))
|
||||
new ValidityTest(v => v * plantingCost <= _rallods, PlantLandError3(_rallods))))
|
||||
{
|
||||
_rallods -= (int)(landPlanted * _plantingCost);
|
||||
_rallods -= (int)(landPlanted * plantingCost);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ControlPollution()
|
||||
public bool ControlPollution(out float rallodsSpent)
|
||||
{
|
||||
if (_rallods > 0 &&
|
||||
_io.TryReadValue(
|
||||
if (_io.TryReadValue(
|
||||
PollutionPrompt,
|
||||
out var rallodsGiven,
|
||||
out rallodsSpent,
|
||||
new ValidityTest(v => v <= _rallods, () => PollutionError(_rallods))))
|
||||
{
|
||||
_rallods = (int)(_rallods - rallodsGiven);
|
||||
_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);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ internal static class IOExtensions
|
||||
io.TryReadValue(SavedWorkersPrompt, out var workers) &&
|
||||
io.TryReadValue(SavedLandPrompt, v => v is > 1000 and <= 2000, SavedLandError, out var land))
|
||||
{
|
||||
reign = new Reign(io, new Country(io, random, rallods, countrymen, workers, land), years + 1);
|
||||
reign = new Reign(io, random, new Country(io, random, rallods, countrymen, workers, land), years + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,37 +5,40 @@ internal class Reign
|
||||
public const int MaxTerm = 8;
|
||||
|
||||
private readonly IReadWrite _io;
|
||||
private readonly IRandom _random;
|
||||
private readonly Country _country;
|
||||
private float _year;
|
||||
private float _yearNumber;
|
||||
|
||||
public Reign(IReadWrite io, IRandom random)
|
||||
: this(io, new Country(io, random), 1)
|
||||
: this(io, random, new Country(io, random), 1)
|
||||
{
|
||||
}
|
||||
|
||||
public Reign(IReadWrite io, Country country, float year)
|
||||
public Reign(IReadWrite io, IRandom random, Country country, float year)
|
||||
{
|
||||
_io = io;
|
||||
_random = random;
|
||||
_country = country;
|
||||
_year = year;
|
||||
_yearNumber = year;
|
||||
}
|
||||
|
||||
public bool PlayYear()
|
||||
{
|
||||
_io.Write(_country.Status);
|
||||
var year = new Year(_country, _random);
|
||||
|
||||
var playerSoldLand = _country.SellLand();
|
||||
var playerDistributedRallods = _country.DistributeRallods();
|
||||
var playerPlantedLand = _country.PlantLand();
|
||||
var playerControlledPollution = _country.ControlPollution();
|
||||
_io.Write(year.Status);
|
||||
|
||||
if (playerSoldLand || playerDistributedRallods || playerPlantedLand || playerControlledPollution)
|
||||
if (year.GetPlayerActions())
|
||||
{
|
||||
_year++;
|
||||
_io.WriteLine();
|
||||
_io.WriteLine();
|
||||
year.EvaluateResults(_io, _random);
|
||||
_yearNumber++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_io.WriteLine();
|
||||
_io.Write(Goodbye);
|
||||
return false;
|
||||
}
|
||||
|
||||
1
53_King/csharp/Resources/DeathsPollution.txt
Normal file
1
53_King/csharp/Resources/DeathsPollution.txt
Normal file
@@ -0,0 +1 @@
|
||||
{0} countrymen died of carbon-monoxide and dust inhalation
|
||||
1
53_King/csharp/Resources/DeathsStarvation.txt
Normal file
1
53_King/csharp/Resources/DeathsStarvation.txt
Normal file
@@ -0,0 +1 @@
|
||||
{0} countrymen died of starvation
|
||||
3
53_King/csharp/Resources/EndAlso.txt
Normal file
3
53_King/csharp/Resources/EndAlso.txt
Normal 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.
|
||||
10
53_King/csharp/Resources/EndCongratulations.txt
Normal file
10
53_King/csharp/Resources/EndCongratulations.txt
Normal 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.
|
||||
|
||||
|
||||
3
53_King/csharp/Resources/EndConsequences.txt
Normal file
3
53_King/csharp/Resources/EndConsequences.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
You have been thrown out of office and are now
|
||||
residing in prison.;
|
||||
You have been assassinated.
|
||||
7
53_King/csharp/Resources/EndForeignWorkers.txt
Normal file
7
53_King/csharp/Resources/EndForeignWorkers.txt
Normal 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}
|
||||
|
||||
5
53_King/csharp/Resources/EndManyDead.txt
Normal file
5
53_King/csharp/Resources/EndManyDead.txt
Normal 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}
|
||||
|
||||
7
53_King/csharp/Resources/EndMoneyLeftOver.txt
Normal file
7
53_King/csharp/Resources/EndMoneyLeftOver.txt
Normal 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.
|
||||
|
||||
|
||||
7
53_King/csharp/Resources/EndOneThirdDead.txt
Normal file
7
53_King/csharp/Resources/EndOneThirdDead.txt
Normal 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}
|
||||
|
||||
1
53_King/csharp/Resources/FuneralExpenses.txt
Normal file
1
53_King/csharp/Resources/FuneralExpenses.txt
Normal file
@@ -0,0 +1 @@
|
||||
You were forced to spend {0} rallods on funeral expenses
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
Goodbye.
|
||||
(If you wish to continue this game at a later date, answer
|
||||
'again' when asked if you want instructions at the start
|
||||
|
||||
0
53_King/csharp/Resources/InsufficientReserves.txt
Normal file
0
53_King/csharp/Resources/InsufficientReserves.txt
Normal file
5
53_King/csharp/Resources/PollutionEffect.txt
Normal file
5
53_King/csharp/Resources/PollutionEffect.txt
Normal 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.
|
||||
@@ -51,6 +51,28 @@ internal static class Resource
|
||||
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();
|
||||
|
||||
private static string PollutionEffect(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(int termLength) => string.Format(GetString(), termLength);
|
||||
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();
|
||||
@@ -61,6 +83,8 @@ internal static class Resource
|
||||
|
||||
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);
|
||||
|
||||
93
53_King/csharp/Year.cs
Normal file
93
53_King/csharp/Year.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System.Text;
|
||||
|
||||
namespace King;
|
||||
|
||||
internal class Year
|
||||
{
|
||||
private readonly Country _country;
|
||||
private readonly IRandom _random;
|
||||
private readonly int _plantingCost;
|
||||
private readonly int _landValue;
|
||||
|
||||
private float _landSold;
|
||||
private float _rallodsDistributed;
|
||||
private float _landPlanted;
|
||||
private float _pollutionControlCost;
|
||||
|
||||
public Year(Country country, IRandom random)
|
||||
{
|
||||
_country = country;
|
||||
_random = random;
|
||||
|
||||
_plantingCost = random.Next(10, 15);
|
||||
_landValue = random.Next(95, 105);
|
||||
}
|
||||
|
||||
public string Status => _country.GetStatus(_landValue, _plantingCost);
|
||||
|
||||
public bool 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;
|
||||
}
|
||||
|
||||
public Result EvaluateResults(IReadWrite io)
|
||||
{
|
||||
var unspentRallods = _country.Rallods;
|
||||
var statusUpdate = new StringBuilder();
|
||||
|
||||
var result = EvaluateDeaths(statusUpdate, out var deaths);
|
||||
|
||||
io.Write(statusUpdate);
|
||||
|
||||
return Result.Continue;
|
||||
}
|
||||
|
||||
public Result? EvaluateDeaths(StringBuilder statusUpdate, out int deaths)
|
||||
{
|
||||
deaths = default;
|
||||
|
||||
var supportedCountrymen = _rallodsDistributed / 100;
|
||||
var starvationDeaths = _country.Countrymen - supportedCountrymen;
|
||||
if (starvationDeaths > 0)
|
||||
{
|
||||
if (supportedCountrymen < 50) { return Result.GameOver(EndOneThirdDead(_random)); }
|
||||
statusUpdate.AppendLine(DeathsStarvation(starvationDeaths));
|
||||
}
|
||||
|
||||
var pollutionControl = _pollutionControlCost >= 25 ? _pollutionControlCost / 25 : 1;
|
||||
var pollutionDeaths = (int)(_random.Next((int)_country.IndustryLand) / pollutionControl);
|
||||
if (pollutionDeaths > 0)
|
||||
{
|
||||
statusUpdate.AppendLine(DeathsPollution(pollutionDeaths));
|
||||
}
|
||||
|
||||
deaths = (int)(starvationDeaths + pollutionDeaths);
|
||||
if (deaths > 0)
|
||||
{
|
||||
var funeralCosts = deaths * 9;
|
||||
statusUpdate.AppendLine(FuneralExpenses(funeralCosts));
|
||||
|
||||
if (!_country.TrySpend(funeralCosts, _landValue))
|
||||
{
|
||||
statusUpdate.AppendLine(InsufficientReserves);
|
||||
}
|
||||
|
||||
_country.RemoveTheDead(deaths);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
internal record struct Result (bool IsGameOver, string Message)
|
||||
{
|
||||
internal static Result GameOver(string message) => new(true, message);
|
||||
internal static Result Continue => new(false, "");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user