Add Card, Rank and Suit types

This commit is contained in:
Andrew Cooper
2022-05-17 19:17:13 +10:00
parent 7773d82833
commit 078ea428c5
2 changed files with 118 additions and 45 deletions
+117 -45
View File
@@ -1,29 +1,32 @@
using Poker.Resources;
using static System.StringComparison;
using static Poker.Rank;
namespace Poker;
internal class Game
{
private readonly IReadWrite _io;
private readonly IRandom _random;
private class FloatArray
private class CardArray
{
private float[] _values;
private Card[] _values;
public FloatArray(float[] values)
public CardArray(Card[] values)
{
_values = values;
}
public float this[float index]
public Card this[float index]
{
get => _values[(int)index];
set => _values[(int)index] = value;
}
}
private readonly FloatArray _cards = new(new float[51]);
private readonly FloatArray _cardRanks = new(new float[16]);
private readonly CardArray _cards = new(new Card[51]);
private readonly CardArray _cardRanks = new(new Card[16]);
private bool _hasWatch;
private float _computerBalance;
private float _playerBalance;
@@ -61,6 +64,8 @@ internal class Game
internal void Play()
{
var deck = new Deck();
_io.Write(Resource.Streams.Title);
_io.Write(Resource.Streams.Instructions);
@@ -68,10 +73,13 @@ internal class Game
_computerBalance = 200;
_playerBalance = 200;
while(PlayHand());
do
{
deck.Shuffle(_random);
} while (PlayHand(deck));
}
internal bool PlayHand()
internal bool PlayHand(Deck deck)
{
_pot=0;
while(true)
@@ -248,23 +256,7 @@ _1460: _io.WriteLine();
void DealCard(int index, int indexToReplace = 0)
{
while(true)
{
_cards[index]=100*_random.Next(4) + _random.Next(100);
if (GetSuit(_cards[index]) > 3) { continue; }
if (GetRank(_cards[index]) > 12) { continue; }
if (index==1) { break; }
var matchFound = false;
for (var i=1; i <= index-1; i++)
{
if (_cards[index]==_cards[i])
{
matchFound = true;
break;
}
}
if (!matchFound) { break; }
}
_cards[index] = deck.Deal();
if (index > 10)
{
(_cards[indexToReplace], _cards[index]) = (_cards[index], _cards[indexToReplace]);
@@ -276,11 +268,7 @@ _1460: _io.WriteLine();
{
for (Z = firstCard; Z <= firstCard+4; Z++)
{
var card = _cards[Z];
_io.Write($"{Z}-- ");
_io.Write(GetRankName(GetRank(card)));
_io.Write(" of");
_io.Write(GetSuitName(GetSuit(card)));
_io.Write($"{Z}-- {_cards[Z]}");
if (Z % 2 == 0)
{
_io.WriteLine();
@@ -312,35 +300,33 @@ _1460: _io.WriteLine();
var suitMatchCount = 0;
for (var i = firstCard; i <= firstCard+4; i++)
{
_cardRanks[i]=GetRank(_cards[i]);
if (i < firstCard+4 && GetSuit(_cards[i]) == GetSuit(_cards[i+1]))
if (i < firstCard+4 && _cards[i].Suit == _cards[i+1].Suit)
{
suitMatchCount++;
}
}
if (suitMatchCount == 4)
{
return (15, "A Flus", "h in", _cards[firstCard], 11111);
return (15, "A Flus", "h in", _cards[firstCard].Value, 11111);
}
for (var i = firstCard; i <= firstCard+3; i++)
{
for (var j = i+1; j <= firstCard+4; j++)
{
if (_cardRanks[i] > _cardRanks[j])
if (_cards[i].Rank > _cards[j].Rank)
{
(_cards[i], _cards[j]) = (_cards[j], _cards[i]);
(_cardRanks[i], _cardRanks[j]) = (_cardRanks[j], _cardRanks[i]);
}
}
}
var handRank = 0;
var keepMask = 0;
var highCard = 0f;
Card highCard = default;
var handName1 = "";
var handName2 = "";
for (var i = firstCard; i <= firstCard+3; i++)
{
if (_cardRanks[i] == _cardRanks[i+1])
if (_cards[i].Rank == _cards[i+1].Rank)
{
keepMask += 11*(int)Math.Pow(10, i-firstCard);
highCard = _cards[i];
@@ -349,16 +335,16 @@ _1460: _io.WriteLine();
}
if (keepMask == 0)
{
if (_cardRanks[firstCard]+3 == _cardRanks[firstCard+3])
if (_cards[firstCard].Rank.Value + 3 == _cards[firstCard+3].Rank.Value)
{
keepMask=1111;
handRank=10;
}
if (_cardRanks[firstCard+1]+3 == _cardRanks[firstCard+4])
if (_cards[firstCard+1].Rank.Value + 3 == _cards[firstCard+4].Rank.Value)
{
if (handRank == 10)
{
return (14, "Straig", "ht", _cards[firstCard+4], 11111);
return (14, "Straig", "ht", _cards[firstCard+4].Value, 11111);
}
handRank=10;
keepMask=11110;
@@ -367,21 +353,21 @@ _1460: _io.WriteLine();
if (handRank < 10)
{
I = 6;
return (9, "Schmal", "tz, ", _cards[firstCard+4], 11000);
return (9, "Schmal", "tz, ", _cards[firstCard+4].Value, 11000);
}
else if (handRank == 10)
{
if (I == 1) { I = 6; }
}
else if (handRank <= 12 && GetRank(highCard) <= 6)
else if (handRank <= 12 && highCard.Rank <= 6)
{
I = 6;
}
return (handRank, handName1, handName2, highCard, keepMask);
return (handRank, handName1, handName2, highCard.Value, keepMask);
}
(int, string, string) AnalyzeMultiples(int handStrength, int index) =>
(handStrength, _cardRanks[index] == _cardRanks[index - 1]) switch
(handStrength, _cards[index].Rank == _cards[index - 1].Rank) switch
{
(<11, _) => (11, "A Pair", " of "),
(11, true) => (13, "Three", " "),
@@ -509,6 +495,7 @@ _3340: return false;
{
_io.WriteLine();
_io.WriteLine("You can't bet with what you haven't got.");
if (_hasWatch)
{
var response = _io.ReadString("Would you like to sell your watch");
@@ -529,19 +516,104 @@ _3340: return false;
}
}
// 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;
}
}
}
internal enum Suit
{
Clubs,
Diamonds,
Hearts,
Spades
}
internal class Deck
{
private readonly Card[] _cards;
private int _nextCard;
public Deck()
{
_cards = Ranks.SelectMany(r => Enum.GetValues<Suit>().Select(s => new Card(r, s))).ToArray();
}
public void Shuffle(IRandom _random)
{
for (int i = 0; i < _cards.Length; i++)
{
var j = _random.Next(_cards.Length);
(_cards[i], _cards[j]) = (_cards[j], _cards[i]);
}
}
public Card Deal() => _cards[_nextCard++];
}
internal record struct Card (Rank Rank, Suit Suit)
{
public float Value => Rank.Value + (int)Suit * 100;
public override string ToString() => $"{Rank} of {Suit}";
public static bool operator <(Card x, Card y) => x.Rank < y.Rank;
public static bool operator >(Card x, Card y) => x.Rank > y.Rank;
}
internal struct Rank
{
public static IEnumerable<Rank> Ranks => new[]
{
Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace
};
public static Rank Two = new Rank(2);
public static Rank Three = new Rank(3);
public static Rank Four = new Rank(4);
public static Rank Five = new Rank(5);
public static Rank Six = new Rank(6);
public static Rank Seven = new Rank(7);
public static Rank Eight = new Rank(8);
public static Rank Nine = new Rank(9);
public static Rank Ten = new Rank(10);
public static Rank Jack = new Rank(11, "Jack");
public static Rank Queen = new Rank(12, "Queen");
public static Rank King = new Rank(13, "King");
public static Rank Ace = new Rank(14, "Ace");
private readonly int _value;
private readonly string _name;
private Rank(int value, string? name = null)
{
_value = value;
_name = name ?? $" {value} ";
}
public int Value => _value - 2;
public override string ToString() => _name;
public static bool operator <(Rank x, Rank y) => x._value < y._value;
public static bool operator >(Rank x, Rank y) => x._value > y._value;
public static bool operator ==(Rank x, Rank y) => x._value == y._value;
public static bool operator !=(Rank x, Rank y) => x._value != y._value;
public static bool operator <=(Rank rank, int value) => rank._value <= value;
public static bool operator >=(Rank rank, int value) => rank._value >= value;
}
internal static class IReadWriteExtensions
{
internal static bool ReadYesNo(this IReadWrite io, string prompt)
{
while (true)
{
var response = io.ReadString("Do you wish to continue");
var response = io.ReadString(prompt);
if (response.Equals("YES", InvariantCultureIgnoreCase)) { return true; }
if (response.Equals("NO", InvariantCultureIgnoreCase)) { return false; }
io.WriteLine("Answer Yes or No, please.");
+1
View File
@@ -1,4 +1,5 @@
global using Games.Common.IO;
global using Games.Common.Randomness;
global using Poker;
new Game(new ConsoleIO(), new RandomNumberGenerator()).Play();