public class CardUtility // Kártya osztályhoz tartozó segédmetódusok:
{
static readonly CardValue[] allValues =
(CardValue[])System.Enum.GetValues(typeof(CardValue));
static readonly CardColor[] allColors =
(CardColor[])System.Enum.GetValues(typeof(CardValue));
// A feladatban leírt függvény:
public static void FillDeck(List<Card> deck)
{
foreach (CardColor c in allColors)
{
foreach (CardValue v in allValues)
{
deck.Add(new Card() { value = v, color = c });
}
}
}
}
// Card típuson belül:
public override string ToString()
{
char colorChar = color switch
{
CardColor.Spades => '♠',
CardColor.Hearts => '♥',
CardColor.Clubs => '♣',
CardColor.Diamonds => '♦',
_ => '?'
};
string valueString = value switch
{
CardValue._2 => "2",
CardValue._3 => "3",
CardValue._4 => "4",
CardValue._5 => "5",
CardValue._6 => "6",
CardValue._7 => "7",
CardValue._8 => "8",
CardValue._9 => "9",
CardValue._10 => "10",
CardValue.J => "J",
CardValue.Q => "Q",
CardValue.K => "K",
CardValue.A => "A",
_ => "?"
};
return valueString + colorChar;
}
public static bool IsRoyalFlush(List<Card> hand)
{
return IsStraightFlush(hand) && hand[0].value == CardValue._10;
}
public static bool IsStraightFlush(List<Card> hand)
{
return IsStraight(hand) && IsFlush(hand); // Lapok egyszínűek-e?
}
public static bool IsStraight(List<Card> hand)
{
int lastValue = (int)hand[0].value;
for (int i = 1; i < hand.Count; i++)
{
int currentValue = (int)hand[i].value;
if (currentValue != lastValue + 1) return false;
lastValue = currentValue;
}
return true;
}
public static bool IsFlush(List<Card> hand)
{
CardColor firstColor = hand[0].color;
for (int i = 1; i < hand.Count; i++)
{
if (hand[i].color != firstColor)
return false;
}
return true;
}
// Ez a függvény megnézi sorban a lapokat és visszaadja, hogy
// - Van-e legalább 2 azonos értékű lap egymás után, (return)
// - mi a legnagyobb azonos értékű lapok száma egymás után, (out)
// - hány pár van a kézben. (out)
static bool CardsInRowTest(List<Card> hand,
out int longestInRow, out int numberOfPairs)
{
// Felételezem, hogy a bemenet egy sorba rendezett lista,
// így elölről haladok végig.
longestInRow = 0; // Sorban a legtöbb azonos értékű lap
numberOfPairs = 0; // Párok száma.
// Végig lépegetek az összes lapon:
for (int i = 0; i < hand.Count;) // (Ciklusváltozót most nem itt növelem!)
{
int sameValueCount = 1; // Zsinórban azonos értékű lapok száma.
// Végig nézem a következő lapokat.
for (int j = i + 1; j < hand.Count; j++)
{
if (hand[i].value == hand[j].value) // Ha azonos értékűek,
sameValueCount++; // akkor növelem a számlálót.
else // Egyébként
break; // kilépek a ciklusból.
}
// Ha ez eddig a a leghosszabb azonos értékű sorozat, ...
if (sameValueCount > longestInRow)
longestInRow = sameValueCount; // akkor elteszem ezt a maximumnak
// Ha a zsinórban azonos értékű lapok száma 2, ....
if (sameValueCount == 2)
numberOfPairs++; // akkor növelem a párok számát.
i += sameValueCount; // Növelem a ciklusváltozót annyival,
// amennyi azonos értékű lap volt sorban.
}
// Visszatérek egy bool értékkel:
return longestInRow > 1; // A leghosszabb sorozat legalább 2 lapból áll.
}
// Ha legnagyobb azonos értékű lapok száma 4, akkor póker.
public static bool IsPoker(List<Card> hand) =>
CardsInRowTest(hand, out int longestInRow, out int _) &&
longestInRow == 4;
// Ha a legnagyobb azonos értékű lapok száma 3,
// és van egy párom is, akkor full house.
public static bool IsFullHouse(List<Card> hand) =>
CardsInRowTest(hand, out int longestInRow, out int numberOfPairs) &&
longestInRow == 3 &&
numberOfPairs == 1;
// Ha a legnagyobb azonos értékű lapok száma 3,
// és nincs párom, akkor drill.
public static bool IsDrill(List<Card> hand) =>
CardsInRowTest(hand, out int longestInRow, out int numberOfPairs) &&
longestInRow == 3 &&
numberOfPairs == 0;
// Ha a legnagyobb azonos értékű lapok száma 2
// és csak egy párom, akkor pár.
public static bool IsPair(List<Card> hand) =>
CardsInRowTest(hand, out int longestInRow, out int numberOfPairs) &&
longestInRow == 2 &&
numberOfPairs == 1;
// Ha a legnagyobb azonos értékű lapok száma 2,
// és két párom van, akkor két pár.
public static bool IsTwoPairs(List<Card> hand) =>
CardsInRowTest(hand, out int longestInRow, out int numberOfPairs) &&
longestInRow == 2 &&
numberOfPairs == 2;
void SortToCompare(List<Card> cardsSorted)
{
if (PokerUtility.IsFlush(cardsSorted)) // Speciális eset: Flush (Színsor)
{
cardsSorted.Sort((x, y) => y.value.CompareTo(x.value));
return;
}
Dictionary<CardValue, List<Card>> cardsOfTheSameValue = new();
foreach (Card card in cardsSorted)
{
CardValue value = card.value;
if (!cardsOfTheSameValue.ContainsKey(value))
cardsOfTheSameValue.Add(value, new List<Card>());
cardsOfTheSameValue[value].Add(card);
}
List<List<Card>> cardsOfTheSameValueSorted = new();
foreach (KeyValuePair<CardValue, List<Card>> pair in cardsOfTheSameValue)
{
List<Card> cards = pair.Value;
cardsOfTheSameValueSorted.Add(cards);
}
cardsOfTheSameValueSorted.Sort(SortByLengthOfTheList);
cardsSorted.Clear();
foreach (List<Card> cards in cardsOfTheSameValueSorted)
cardsSorted.AddRange(cards);
}
// -1 : Az első paraméterben megadott lista kerül előrébb
// 0: A két kéz egyforma erős
// 1: A második paraméterben megadott lista kerül előrébb
int SortByLengthOfTheList(List<Card> x, List<Card> y)
{
int byLength = y.Count.CompareTo(x.Count);
if (byLength != 0)
return byLength;
return y[0].value.CompareTo(x[0].value);
}
public class PokerHand
{
public readonly string playerName;
public readonly PokerCombination pokerCombination;
public readonly List<Card> cardsSortedToCompare;
public PokerHand(string playerName, List<Card> hand)
{
this.playerName = playerName;
if(hand.Count != 5)
Debug.LogError("This constructor works only with 5 card!");
List<Card> sorted = new();
sorted.AddRange(hand);
CardUtility.SortByValue(sorted);
pokerCombination = PokerUtility.GetPokerCombination(sorted);
SortToCompare(sorted);
cardsSortedToCompare = sorted;
}
}
// -1 : Az első paraméterben megadott kéz erősebb
// 0: A két kéz egyforma erős
// 1: A második paraméterben megadott kéz erősebb
public static int CompareHands(PokerHand a, PokerHand b)
{
// Ha a két kéz különböző kombinációval rendelkezik, akkor a magasabb kombináció nyer.
int compareByCombination = b.pokerCombination.CompareTo(a.pokerCombination);
if (compareByCombination != 0)
return compareByCombination;
// Ha a két kéz ugyanazzal a kombinációval rendelkezik, akkor a kártyák értékei döntenek.
for (int i = 0; i < a.cardsSortedToCompare.Count; i++)
{
int compareByValue = a.cardsSortedToCompare[i].value.CompareTo(b.cardsSortedToCompare[i].value);
if (compareByValue != 0)
return compareByValue;
}
// Ha a két kéz ugyanazzal a kombinációval és ugyanazokkal az értékekkel rendelkezik, akkor döntetlen.
return 0;
}
void PlayPokerMatch(List<string>playerNames)
{
List<Card> deck = new(); // Kártyapakli létrehozása,
CardUtility.FillDeck(deck); // feltöltése
CardUtility.ShuffleDeck(deck); // és megkeverése
List<PokerHand> players = new(); // Játékosok listája.
for (int i = 0; i < playerCount; i++) // Minden játékos...
{
List<Card> cards = new();
for (int j = 0; j < 5; j++) // kap öt lapot...
{
if (deck.Count == 0)
return;
cards.Add(deck[0]); // a pakli tetejéről.
deck.RemoveAt(0); // (Ne felejtsük el kivenni a lapokat a pakliból)
}
PokerHand hand = new(cards); // Létrehozzuk a kezet.
players.Add(hand);
}
// Sorbarendezzüka játékosokat a kezeik erőssége szerint
players.Sort(PokerHand.CompareHands);
// Majd ebben a sorrenben kiíratjuk őket (Legerősebbel kezdünk)
for (int i = players.Count - 1; i >= 0; i--)
Debug.Log(players[i]);
}