Files
basic-computer-games/77_Salvo/csharp/TurnHandler.cs
2023-05-24 20:58:37 +10:00

93 lines
2.8 KiB
C#

using Salvo.Targetting;
namespace Salvo;
internal class TurnHandler
{
private readonly IReadWrite _io;
private readonly Fleet _humanFleet;
private readonly Fleet _computerFleet;
private readonly bool _humanStarts;
private readonly HumanShotSelector _humanShotSelector;
private readonly ComputerShotSelector _computerShotSelector;
private readonly Func<Winner?> _turnAction;
private int _turnNumber;
public TurnHandler(IReadWrite io, IRandom random)
{
_io = io;
_computerFleet = new Fleet(random);
_humanFleet = new Fleet(io);
_turnAction = AskWhoStarts()
? () => PlayHumanTurn() ?? PlayComputerTurn()
: () => PlayComputerTurn() ?? PlayHumanTurn();
_humanShotSelector = new HumanShotSelector(_humanFleet, io);
_computerShotSelector = new ComputerShotSelector(_computerFleet, random, io);
}
public Winner? PlayTurn()
{
_io.Write(Strings.Turn(++_turnNumber));
return _turnAction.Invoke();
}
private bool AskWhoStarts()
{
while (true)
{
var startResponse = _io.ReadString(Prompts.Start);
if (startResponse.Equals(Strings.WhereAreYourShips, StringComparison.InvariantCultureIgnoreCase))
{
foreach (var ship in _computerFleet.Ships)
{
_io.WriteLine(ship);
}
}
else
{
return startResponse.Equals("yes", StringComparison.InvariantCultureIgnoreCase);
}
}
}
private Winner? PlayComputerTurn()
{
var numberOfShots = _computerShotSelector.NumberOfShots;
_io.Write(Strings.IHaveShots(numberOfShots));
if (numberOfShots == 0) { return Winner.Human; }
if (_computerShotSelector.CanTargetAllRemainingSquares)
{
_io.Write(Streams.IHaveMoreShotsThanSquares);
return Winner.Computer;
}
_humanFleet.ReceiveShots(
_computerShotSelector.GetShots(_turnNumber),
ship =>
{
_io.Write(Strings.IHit(ship.Name));
_computerShotSelector.RecordHit(ship, _turnNumber);
});
return null;
}
private Winner? PlayHumanTurn()
{
var numberOfShots = _humanShotSelector.NumberOfShots;
_io.Write(Strings.YouHaveShots(numberOfShots));
if (numberOfShots == 0) { return Winner.Computer; }
if (_humanShotSelector.CanTargetAllRemainingSquares)
{
_io.WriteLine(Streams.YouHaveMoreShotsThanSquares);
return Winner.Human;
}
_computerFleet.ReceiveShots(
_humanShotSelector.GetShots(_turnNumber),
ship => _io.Write(Strings.YouHit(ship.Name)));
return null;
}
}