mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
119 lines
3.8 KiB
C#
119 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using CivilWar;
|
|
|
|
var options = GameOptions.Input();
|
|
var armies = new List<Army> { new Army(Side.Confederate), options.TwoPlayers ? new Army(Side.Union) : new ComputerArmy(Side.Union) };
|
|
|
|
Battle? battle = null;
|
|
while (OneBattle(ref battle)) { }
|
|
DisplayResult();
|
|
|
|
bool OneBattle(ref Battle? previous)
|
|
{
|
|
var (option, selected) = Battle.SelectBattle();
|
|
var (battle, isReplay, quit) = option switch
|
|
{
|
|
Option.Battle => (selected!, false, false),
|
|
Option.Replay when previous != null => (previous, true, false), // can't replay if no previous battle
|
|
_ => (null!, false, true),
|
|
};
|
|
if (quit)
|
|
return false;
|
|
|
|
if (!isReplay)
|
|
{
|
|
Console.WriteLine($"This is the battle of {battle.Name}.");
|
|
if (options.ShowDescriptions)
|
|
ConsoleUtils.WriteWordWrap(battle.Description);
|
|
armies.ForEach(a => a.PrepareBattle(battle.Men[(int)a.Side], battle.Casualties[(int)a.Side]));
|
|
}
|
|
|
|
ConsoleUtils.WriteTable(armies, new()
|
|
{
|
|
new("", a => a.Side),
|
|
new("Men", a => a.Men),
|
|
new("Money", a => a.Money, Before: "$"),
|
|
new("Inflation", a => a.InflationDisplay, After: "%")
|
|
});
|
|
|
|
armies.ForEach(a => a.AllocateResources());
|
|
armies.ForEach(a => a.DisplayMorale());
|
|
|
|
string offensive = battle.Offensive switch
|
|
{
|
|
Side.Confederate => "You are on the offensive",
|
|
Side.Union => "You are on the defensive",
|
|
_ => "Both sides are on the offensive"
|
|
};
|
|
Console.WriteLine($"Confederate general---{offensive}");
|
|
|
|
if (armies.Any(a => a.ChooseStrategy(isReplay)))
|
|
{
|
|
return false; // someone surrendered
|
|
}
|
|
armies[0].CalculateLosses(armies[1]);
|
|
armies[1].CalculateLosses(armies[0]);
|
|
|
|
ConsoleUtils.WriteTable(armies, new()
|
|
{
|
|
new("", a => a.Side),
|
|
new("Casualties", a => a.Casualties),
|
|
new("Desertions", a => a.Desertions),
|
|
});
|
|
if (options.TwoPlayers)
|
|
{
|
|
var oneDataCol = new[] { 1 };
|
|
Console.WriteLine($"Compared to the actual casualties at {battle.Name}");
|
|
ConsoleUtils.WriteTable(oneDataCol, armies.Select(a => new ConsoleUtils.TableRow<int>(
|
|
a.Side.ToString(),
|
|
_ => $"{(double)a.Casualties / battle.Casualties[(int)a.Side]}", After: "% of the original")
|
|
).ToList());
|
|
}
|
|
|
|
Side winner;
|
|
switch (armies[0].AllLost, armies[1].AllLost, armies[0].MenLost - armies[1].MenLost)
|
|
{
|
|
case (true, true, _) or (false, false, 0):
|
|
Console.WriteLine("Battle outcome unresolved");
|
|
winner = Side.Both; // Draw
|
|
break;
|
|
case (false, true, _) or (false, false, < 0):
|
|
Console.WriteLine($"The Confederacy wins {battle.Name}");
|
|
winner = Side.Confederate;
|
|
break;
|
|
case (true, false, _) or (false, false, > 0):
|
|
Console.WriteLine($"The Union wins {battle.Name}");
|
|
winner = Side.Union;
|
|
break;
|
|
}
|
|
if (!isReplay)
|
|
{
|
|
armies.ForEach(a => a.RecordResult(winner));
|
|
}
|
|
Console.WriteLine("---------------");
|
|
previous = battle;
|
|
return true;
|
|
}
|
|
|
|
void DisplayResult()
|
|
{
|
|
armies[0].DisplayWarResult(armies[1]);
|
|
|
|
int battles = armies[0].BattlesFought;
|
|
if (battles > 0)
|
|
{
|
|
Console.WriteLine($"For the {battles} battles fought (excluding reruns)");
|
|
|
|
ConsoleUtils.WriteTable(armies, new()
|
|
{
|
|
new("", a => a.Side),
|
|
new("Historical Losses", a => a.CumulativeHistoricCasualties),
|
|
new("Simulated Losses", a => a.CumulativeSimulatedCasualties),
|
|
new(" % of original", a => ((double)a.CumulativeSimulatedCasualties / a.CumulativeHistoricCasualties).ToString("p2"))
|
|
}, transpose: true);
|
|
|
|
armies[1].DisplayStrategies();
|
|
}
|
|
} |