mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-24 12:04:17 -08:00
214 lines
5.4 KiB
C#
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");
|
|
}
|
|
} |