Move end game checks and text to main loop

This commit is contained in:
Andrew Cooper
2022-06-25 15:50:12 +10:00
parent 3d8bae0a09
commit 860dd40276
6 changed files with 71 additions and 52 deletions

View File

@@ -30,29 +30,27 @@ internal class Game
_io.Write(Resource.Streams.Title);
_io.Write(Resource.Streams.Instructions);
while (true)
do
{
var gameOver = PlayHand(table);
if (gameOver) { break; }
_io.WriteLine($"Now I have $ {table.Computer.Balance} and you have $ {table.Human.Balance}");
if (!_io.ReadYesNo("Do you wish to continue")) { break; }
}
PlayHand(table);
} while (!table.IsGameOver());
}
internal bool PlayHand(Table table)
internal void PlayHand(Table table)
{
while (true)
{
_io.WriteLine();
if (table.Computer.Balance <= table.Ante)
{
_io.WriteLine("I'm busted. Congratulations!");
return true;
}
table.Computer.CheckFunds();
if (table.Computer.IsBroke) { return; }
_io.WriteLine($"The ante is ${table.Ante}. I will deal:");
_io.WriteLine();
if (table.Human.Balance <= table.Ante && table.Human.IsBroke()) { return true; }
if (table.Human.Balance <= table.Ante)
{
table.Human.RaiseFunds();
if (table.Human.IsBroke) { return; }
}
table.Deal(_random);
@@ -62,12 +60,12 @@ internal class Game
(true, _, _) when Get0To9() < 2 => Strategy.Bluff(23, 0b11100),
(true, _, _) when Get0To9() < 2 => Strategy.Bluff(23, 0b11110),
(true, _, _) when Get0To9() < 1 => Strategy.Bluff(23, 0b11111),
(true, _, _) => Strategy.Fold,
(true, _, _) => Strategy.Fold,
(false, true, _) => Get0To9() < 2 ? Strategy.Bluff(23) : Strategy.Check,
(false, false, true) => Strategy.Bet(35),
(false, false, false) => Get0To9() < 1 ? Strategy.Bet(35) : Strategy.Raise
};
if (table.Computer.Strategy is Strategies.Bet)
if (table.Computer.Strategy is Bet)
{
V = table.Computer.Strategy.Value + Get0To9();
if (table.Computer.Balance - table.Human.Bet - V < 0)
@@ -82,10 +80,10 @@ internal class Game
table.Computer.Bet = table.Human.Bet;
table.UpdatePot();
}
else if (!table.Computer.TrySellWatch())
else
{
_io.WriteLine("I'm busted. Congratulations!");
return true;
table.Computer.RaiseFunds();
if (table.Computer.IsBroke) { return; }
}
}
_io.WriteLine($"I'll open with ${V}");
@@ -95,8 +93,8 @@ internal class Game
{
_io.WriteLine("I check.");
}
if (GetWager(table.Computer.Strategy)) { return true; }
if (table.SomeoneHasFolded()) { return false; }
GetWager(table.Computer.Strategy);
if (table.SomeoneIsBroke() || table.SomeoneHasFolded()) { return; }
table.Draw();
@@ -109,12 +107,13 @@ internal class Game
(false, false, false) => Strategy.Raise
};
if (GetWager(table.Computer.Strategy)) { return true; }
GetWager(table.Computer.Strategy);
if (table.SomeoneIsBroke()) { return; }
if (table.Human.HasBet)
{
if (table.SomeoneHasFolded()) { return false; }
if (table.SomeoneHasFolded()) { return; }
}
else if (table.Computer.Strategy is Strategies.Bet)
else if (table.Computer.Strategy is Bet)
{
V = table.Computer.Strategy.Value + Get0To9();
if (table.Computer.Balance - table.Human.Bet - V < 0)
@@ -129,16 +128,16 @@ internal class Game
table.Computer.Bet = table.Human.Bet;
table.UpdatePot();
}
else if (!table.Computer.TrySellWatch())
else
{
_io.WriteLine("I'm busted. Congratulations!");
return true;
table.Computer.RaiseFunds();
if (table.Computer.IsBroke) { return; }
}
}
_io.WriteLine($"I'll bet ${V}");
table.Computer.Bet = V;
if (GetWager(table.Computer.Strategy)) { return true; }
if (table.SomeoneHasFolded()) { return false; }
GetWager(table.Computer.Strategy);
if (table.SomeoneIsBroke() || table.SomeoneHasFolded()) { return; }
}
else
{
@@ -147,11 +146,11 @@ internal class Game
if (table.GetWinner() is { } winner)
{
winner.TakeWinnings();
return false;
return;
}
}
bool GetWager(Strategy computerStrategy)
void GetWager(Strategy computerStrategy)
{
while (true)
{
@@ -172,20 +171,21 @@ internal class Game
table.Human.Bet += humanStrategy.Value;
break;
}
if (table.Human.IsBroke()) { return true; }
table.Human.RaiseFunds();
if (table.Human.IsBroke) { return; }
continue;
}
else
{
table.Human.Fold();
table.UpdatePot();
return false;
return;
}
}
if (table.Human.Bet == table.Computer.Bet)
{
table.UpdatePot();
return false;
return;
}
if (computerStrategy is Fold)
{
@@ -193,7 +193,7 @@ internal class Game
{
table.Computer.Fold();
_io.WriteLine("I fold.");
return false;
return;
}
V = 5;
}
@@ -204,7 +204,7 @@ internal class Game
_io.WriteLine("I'll see you.");
table.Computer.Bet = table.Human.Bet;
table.UpdatePot();
return false;
return;
}
}
@@ -221,10 +221,10 @@ internal class Game
table.Computer.Bet = table.Human.Bet;
table.UpdatePot();
}
else if (!table.Computer.TrySellWatch())
else
{
_io.WriteLine("I'm busted. Congratulations!");
return true;
table.Computer.RaiseFunds();
if (table.Computer.IsBroke) { return; }
}
}
_io.WriteLine($"I'll see you, and raise you{V}");

View File

@@ -14,16 +14,11 @@ internal class Computer : Player
{
_io = io;
_random = random;
Strategy = Strategy.Check;
Strategy = Strategy.None;
}
public Strategy Strategy { get; set; }
public override void NewHand()
{
base.NewHand();
}
protected override void DrawCards(Deck deck)
{
var keepMask = Strategy.KeepMask ?? Hand.KeepMask;
@@ -65,19 +60,21 @@ internal class Computer : Player
return true;
}
public bool TrySellWatch()
public void RaiseFunds()
{
if (Table.Human.HasWatch) { return false; }
if (Table.Human.HasWatch) { return; }
var response = _io.ReadString("Would you like to buy back your watch for $50");
if (response.StartsWith("N", InvariantCultureIgnoreCase)) { return false; }
if (response.StartsWith("N", InvariantCultureIgnoreCase)) { return; }
// The original code does not deduct $50 from the player
Balance += 50;
Table.Human.ReceiveWatch();
return true;
IsBroke = true;
}
public void CheckFunds() { IsBroke = Balance <= Table.Ante; }
public override void TakeWinnings()
{
_io.WriteLine("I win.");

View File

@@ -30,18 +30,18 @@ internal class Human : Player
_io.Write(Hand);
}
public bool IsBroke()
public void RaiseFunds()
{
_io.WriteLine();
_io.WriteLine("You can't bet with what you haven't got.");
if (Table.Computer.TryBuyWatch()) { return false; }
if (Table.Computer.TryBuyWatch()) { return; }
// The original program had some code about selling a tie tack, but due to a fault
// in the logic the code was unreachable. I've omitted it in this port.
_io.WriteLine("Your wad is shot. So long, sucker!");
return true;
IsBroke = true;
}
public void ReceiveWatch()

View File

@@ -18,6 +18,7 @@ internal abstract class Player
public bool HasBet { get; set; }
public int Bet { get; set; }
public bool HasFolded => _hasFolded;
public bool IsBroke { get; protected set; }
protected Table Table =>
_table ?? throw new InvalidOperationException("The player must be sitting at the table.");

View File

@@ -2,6 +2,7 @@ namespace Poker.Strategies;
internal abstract class Strategy
{
public static Strategy None = new None();
public static Strategy Fold = new Fold();
public static Strategy Check = new Check();
public static Strategy Raise = new Raise();

View File

@@ -79,6 +79,8 @@ internal class Table
return true;
}
public bool SomeoneIsBroke() => Human.IsBroke || Computer.IsBroke;
public Player? GetWinner()
{
_io.WriteLine();
@@ -94,4 +96,22 @@ internal class Table
_io.WriteLine($"All $ {Pot} remains in the pot.");
return null;
}
internal bool IsGameOver()
{
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");
}
}