Files
basic-computer-games/71_Poker/csharp/Table.cs
2022-07-01 17:20:13 +10:00

214 lines
5.4 KiB
C#

using Poker.Cards;
using Poker.Players;
using Poker.Strategies;
namespace Poker;
internal class Table
{
private readonly IReadWrite _io;
private readonly IRandom _random;
public int Pot;
public Table(IReadWrite io, IRandom random, Deck deck, Human human, Computer computer)
{
_io = io;
_random = random;
Deck = deck;
Human = human;
Computer = computer;
human.Sit(this);
computer.Sit(this);
}
public int Ante { get; } = 5;
public Deck Deck { get; }
public Human Human { get; }
public Computer Computer { get; }
internal void PlayHand()
{
while (true)
{
_io.WriteLine();
Computer.CheckFunds();
if (Computer.IsBroke) { return; }
_io.WriteLine($"The ante is ${Ante}. I will deal:");
_io.WriteLine();
if (Human.Balance <= Ante)
{
Human.RaiseFunds();
if (Human.IsBroke) { return; }
}
Deal(_random);
_io.WriteLine();
GetWagers("I'll open with ${0}", "I check.", allowRaiseAfterCheck: true);
if (SomeoneIsBroke() || SomeoneHasFolded()) { return; }
Draw();
GetWagers();
if (SomeoneIsBroke()) { return; }
if (!Human.HasBet)
{
GetWagers("I'll bet ${0}", "I'll check");
}
if (SomeoneIsBroke() || SomeoneHasFolded()) { return; }
if (GetWinner() is { } winner)
{
winner.TakeWinnings();
return;
}
}
}
private void Deal(IRandom random)
{
Deck.Shuffle(random);
Pot = Human.AnteUp() + Computer.AnteUp();
Human.NewHand();
Computer.NewHand();
_io.WriteLine("Your hand:");
_io.Write(Human.Hand);
}
private void Draw()
{
_io.WriteLine();
_io.Write("Now we draw -- ");
Human.DrawCards();
Computer.DrawCards();
_io.WriteLine();
}
private void GetWagers(string betFormat, string checkMessage, bool allowRaiseAfterCheck = false)
{
if (Computer.Strategy is Bet)
{
Computer.Bet = Computer.GetWager(Computer.Strategy.Value);
if (Computer.IsBroke) { return; }
_io.WriteLine(betFormat, Computer.Bet);
}
else
{
_io.WriteLine(checkMessage);
if (!allowRaiseAfterCheck) { return; }
}
GetWagers();
}
private void GetWagers()
{
while (true)
{
Human.HasBet = false;
while (true)
{
if (Human.SetWager()) { break; }
if (Human.IsBroke || Human.HasFolded) { return; }
}
if (Human.Bet == Computer.Bet)
{
CollectBets();
return;
}
if (Computer.Strategy is Fold)
{
if (Human.Bet > 5)
{
Computer.Fold();
_io.WriteLine("I fold.");
return;
}
}
if (Human.Bet > 3 * Computer.Strategy.Value)
{
if (Computer.Strategy is not Raise)
{
_io.WriteLine("I'll see you.");
Computer.Bet = Human.Bet;
CollectBets();
return;
}
}
var raise = Computer.GetWager(Human.Bet - Computer.Bet);
if (Computer.IsBroke) { return; }
_io.WriteLine($"I'll see you, and raise you {raise}");
Computer.Bet = Human.Bet + raise;
}
}
internal void CollectBets()
{
Human.Balance -= Human.Bet;
Computer.Balance -= Computer.Bet;
Pot += Human.Bet + Computer.Bet;
}
private bool SomeoneHasFolded()
{
if (Human.HasFolded)
{
_io.WriteLine();
Computer.TakeWinnings();
}
else if (Computer.HasFolded)
{
_io.WriteLine();
Human.TakeWinnings();
}
else
{
return false;
}
Pot = 0;
return true;
}
private bool SomeoneIsBroke() => Human.IsBroke || Computer.IsBroke;
private Player? GetWinner()
{
_io.WriteLine();
_io.WriteLine("Now we compare hands:");
_io.WriteLine("My hand:");
_io.Write(Computer.Hand);
_io.WriteLine();
_io.WriteLine($"You have {Human.Hand.Name}");
_io.WriteLine($"and I have {Computer.Hand.Name}");
if (Computer.Hand > Human.Hand) { return Computer; }
if (Human.Hand > Computer.Hand) { return Human; }
_io.WriteLine("The hand is drawn.");
_io.WriteLine($"All $ {Pot} remains in the pot.");
return null;
}
internal bool ShouldPlayAnotherHand()
{
if (Computer.IsBroke)
{
_io.WriteLine("I'm busted. Congratulations!");
return true;
}
if (Human.IsBroke)
{
_io.WriteLine("Your wad is shot. So long, sucker!");
return true;
}
_io.WriteLine($"Now I have $ {Computer.Balance} and you have $ {Human.Balance}");
return _io.ReadYesNo("Do you wish to continue");
}
}