初期入力:
H 0 0 0 0 0 0 0 0 0 0 0 0 0
C 1 0 0 0 0 0 0 0 0 0 0 0 0
D 1 0 0 0 0 0 0 0 0 0 0 0 0
S 1 1 0 0 0 0 0 0 0 0 0 0 0
+ A 2 3 4 5 6 7 8 9 T J Q K
ステップ1:使用される最高ランク以上のランクごとに、そのランクのすべてのスーツを0に設定します。低い組み合わせは低い開始点によってチェックされるため、高いカードをチェックするだけで逃げることができます。
H 0 0 0 0 0 0 0 0 0 0 0 0 0
C 1 0 0 0 0 0 0 0 0 0 0 0 0
D 1 0 0 0 0 0 0 0 0 0 0 0 0
S 1 0 0 0 0 0 0 0 0 0 0 0 0
+ A 2 3 4 5 6 7 8 9 T J Q K
ステップ2:個別の行に折りたたむ
0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0
A 2 3 4 5 6 7 8 9 T J Q K
ステップ3:戻って、それぞれの個別の行に一致する最初のスーツを決定し、個別の行に一致するスーツを選択します(*で識別)
H 0 * 0 0 0 0 0 0 0 0 0 0 0
C 1 0 0 0 0 0 0 0 0 0 0 0 0
D 1 * 0 0 0 0 0 0 0 0 0 0 0
S 1 1 0 0 0 0 0 0 0 0 0 0 0
+ A 2 3 4 5 6 7 8 9 T J Q K
ランク3のリピートを表示しています
H 0 0 0 0 0 0 0 0 0 0 0 0 0
C 1 0 0 0 0 0 0 0 0 0 0 0 0
D 1 0 0 0 0 0 0 0 0 0 0 0 0
S 1 1 0 0 0 0 0 0 0 0 0 0 0
+ A 2 3 4 5 6 7 8 9 T J Q K
0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0
A 2 3 4 5 6 7 8 9 T J Q K
H 0 0 * 0 0 0 0 0 0 0 0 0 0
C 1 0 0 0 0 0 0 0 0 0 0 0 0
D 1 0 * 0 0 0 0 0 0 0 0 0 0
S 1 1 * 0 0 0 0 0 0 0 0 0 0
+ A 2 3 4 5 6 7 8 9 T J Q K
ステップ4:5つのセルが1に設定されたら、可能なスーツの抽象化されたハンドの総数を1ずつ増やし、繰り返します。
可能なスーツ抽象化ハンドの総数は134,459です。これは私がそれをテストするために書いたコードです:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication20
{
struct Card
{
public int Suit { get; set; }
public int Rank { get; set; }
}
class Program
{
static int ranks = 13;
static int suits = 4;
static int cardsInHand = 5;
static void Main(string[] args)
{
List<Card> cards = new List<Card>();
//cards.Add(new Card() { Rank = 0, Suit = 0 });
int numHands = GenerateAllHands(cards);
Console.WriteLine(numHands);
Console.ReadLine();
}
static int GenerateAllHands(List<Card> cards)
{
if (cards.Count == cardsInHand) return 1;
List<Card> possibleNextCards = GetPossibleNextCards(cards);
int numSubHands = 0;
foreach (Card card in possibleNextCards)
{
List<Card> possibleNextHand = cards.ToList(); // copy list
possibleNextHand.Add(card);
numSubHands += GenerateAllHands(possibleNextHand);
}
return numSubHands;
}
static List<Card> GetPossibleNextCards(List<Card> hand)
{
int maxRank = hand.Max(x => x.Rank);
List<Card> result = new List<Card>();
// only use ranks >= max
for (int rank = maxRank; rank < ranks; rank++)
{
List<int> suits = GetPossibleSuitsForRank(hand, rank);
var possibleNextCards = suits.Select(x => new Card { Rank = rank, Suit = x });
result.AddRange(possibleNextCards);
}
return result;
}
static List<int> GetPossibleSuitsForRank(List<Card> hand, int rank)
{
int maxSuit = hand.Max(x => x.Suit);
// select number of ranks of different suits
int[][] card = GetArray(hand, rank);
for (int i = 0; i < suits; i++)
{
card[i][rank] = 0;
}
int[][] handRep = GetArray(hand, rank);
// get distinct rank sets, then find which ranks they correspond to
IEnumerable<int[]> distincts = card.Distinct(new IntArrayComparer());
List<int> possibleSuits = new List<int>();
foreach (int[] row in distincts)
{
for (int i = 0; i < suits; i++)
{
if (IntArrayComparer.Compare(row, handRep[i]))
{
possibleSuits.Add(i);
break;
}
}
}
return possibleSuits;
}
class IntArrayComparer : IEqualityComparer<int[]>
{
#region IEqualityComparer<int[]> Members
public static bool Compare(int[] x, int[] y)
{
for (int i = 0; i < x.Length; i++)
{
if (x[i] != y[i]) return false;
}
return true;
}
public bool Equals(int[] x, int[] y)
{
return Compare(x, y);
}
public int GetHashCode(int[] obj)
{
return 0;
}
#endregion
}
static int[][] GetArray(List<Card> hand, int rank)
{
int[][] cards = new int[suits][];
for (int i = 0; i < suits; i++)
{
cards[i] = new int[ranks];
}
foreach (Card card in hand)
{
cards[card.Suit][card.Rank] = 1;
}
return cards;
}
}
}
うまくいけば、それは簡単に理解できるように十分に分割されています。