C# 生成一手扑克牌的所有不同的7张牌组合?
我正在尝试生成扑克牌的所有不同组合,如下所述: 但我总是被卡住。在上面的URL尝试NickLarsen的C#答案时,我在第49行得到一个未处理的异常错误。() 我想要的是非常简单的:生成所有卡片组合,并在一个简单的.txt文件中一次打印一行 另外,我实际上想要所有7种卡片组合(而不是5种)。 例如,前两行可能如下所示: 2c2d2h2s3c3d3hC# 生成一手扑克牌的所有不同的7张牌组合?,c#,combinations,permutation,poker,C#,Combinations,Permutation,Poker,我正在尝试生成扑克牌的所有不同组合,如下所述: 但我总是被卡住。在上面的URL尝试NickLarsen的C#答案时,我在第49行得到一个未处理的异常错误。() 我想要的是非常简单的:生成所有卡片组合,并在一个简单的.txt文件中一次打印一行 另外,我实际上想要所有7种卡片组合(而不是5种)。 例如,前两行可能如下所示: 2c2d2h2s3c3d3h 2c2d2h2s3c3d3s 我如何做到这一点?速度并不是那么重要 以下是NickLarsen(经我修改)的失败代码: using System;
2c2d2h2s3c3d3s 我如何做到这一点?速度并不是那么重要 以下是NickLarsen(经我修改)的失败代码:
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 = 7;
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;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间控制台应用程序20
{
结构卡
{
公共整数{get;set;}
公共整数秩{get;set;}
}
班级计划
{
静态整数秩=13;
静态int=4;
静态int cardsInHand=7;
静态void Main(字符串[]参数)
{
列表卡=新列表();
//添加(新卡(){Rank=0,Suit=0});
int numHands=GenerateAllHands(卡片);
控制台写入线(numHands);
Console.ReadLine();
}
静态int GENERATEALHANDS(列表卡)
{
如果(cards.Count==cardsInHand)返回1;
List possibleNextCards=GetPossibleNextCards(卡片);
int numSubHands=0;
foreach(可能的ExtCards中的卡片)
{
List possibleNextHand=cards.ToList();//复制列表
可能额外添加(卡片);
numSubHands+=生成的左手(可能是右手);
}
返回numSubHands;
}
静态列表GetPossibleNextCards(列表手)
{
int maxRank=hand.Max(x=>x.Rank);
列表结果=新列表();
//仅使用等级>=最大值
for(int-rank=maxRank;ranknewcard{Rank=Rank,suite=x});
结果.AddRange(可能是ExtCards);
}
返回结果;
}
静态列表GetPossibleSuitsForRank(列表手,整数秩)
{
int maxSuit=hand.Max(x=>x.Suit);
//选择不同西装的等级数
int[][]卡=GetArray(手牌,等级);
for(int i=0;i这是因为您已注释掉了//cards.Add(new Card(){Rank=0,Suit=0})代码>。您的卡
列表为空,您的代码找不到空数组的最大值
——这是可以预测的。我参加聚会有点晚,但有同样的需要(5张牌)。在另一个线程上,同样使用Nick Larsen的答案(似乎不完美,因为我也得到了错误的号码),只需添加一个方法来获取卡片的名称(我相信有人可以更优雅地完成此操作,但它是有效的):
然后,在for循环中使用它,以便您可以打印出它或您需要的任何内容:
static void Main(string[] args)
{
List<Card> cards = new List<Card>();
cards.Add(new Card() { Rank = 0, Suit = 0 });
int numHands = GenerateAllHands(cards);
int counter = 0;
Console.WriteLine(numHands);
Console.WriteLine(possibleHands.Count);
foreach (Hand hand in possibleHands)
{
counter += 1;
foreach (Card card in hand.Cards)
{
hand.HandString += GetCardName(card) + " ";
}
hand.HandString = hand.HandString.Trim();
}
Console.ReadLine();
}
static void Main(字符串[]args)
{
列表卡=新列表();
添加(新卡(){Rank=0,Suit=0});
int numHands=GenerateAllHands(卡片);
int计数器=0;
控制台写入线(numHands);
Console.WriteLine(可能的hands.Count);
foreach(手牵手可能的手)
{
计数器+=1;
foreach(手中的卡片。卡片)
{
hand.HandString+=GetCardName(card)+;
}
hand.HandString=hand.HandString.Trim();
}
Console.ReadLine();
}
此操作大约在3秒钟内运行
为什么要将它们写入文本文件
生成它们的速度比从文件读取要快
public void PokerHands7from52()
{
for (byte i = 0; i < 52; i++)
Debug.WriteLine("rank " + i % 13 + " suite " + i / 13);
Stopwatch sw = new Stopwatch();
sw.Start();
int counter = 0;
for (int i = 51; i >= 6; i--)
{
for (int j = i - 1; j >= 5; j--)
{
for (int k = j - 1; k >= 4; k--)
{
for (int m = k - 1; m >= 3; m--)
{
for (int n = m - 1; n >= 2; n--)
{
for (int p = n - 1; p >= 1; p--)
{
for (int q = p - 1; q >= 0; q--)
{
// the 7 card are i, j, k, m, n, p, q
counter++;
if (counter % 10000000 == 0)
Debug.WriteLine(counter.ToString("N0") + " " + sw.ElapsedMilliseconds.ToString("N0"));
}
}
}
}
}
}
}
sw.Stop();
System.Diagnostics.Debug.WriteLine("counter " + counter.ToString("N0") + " should be 133,784,560");
System.Diagnostics.Debug.WriteLine("sw " + sw.ElapsedMilliseconds.ToString("N0"));
}
}
public void-7 from52()
{
用于(字节i=0;i<52;i++)
Debug.WriteLine(“秩”+i%13+“套件”+i/13);
秒表sw=新秒表();
sw.Start();
int计数器=0;
对于(int i=51;i>=6;i--)
{
对于(int j=i-1;j>=5;j--)
{
对于(int k=j-1;k>=4;k--)
{
对于(int m=k-1;m>=3;m--)
{
对于(int n=m-1;n>=2;n--)
{
对于(int p=n-1;p>=1;p--)
{
public void PokerHands7from52()
{
for (byte i = 0; i < 52; i++)
Debug.WriteLine("rank " + i % 13 + " suite " + i / 13);
Stopwatch sw = new Stopwatch();
sw.Start();
int counter = 0;
for (int i = 51; i >= 6; i--)
{
for (int j = i - 1; j >= 5; j--)
{
for (int k = j - 1; k >= 4; k--)
{
for (int m = k - 1; m >= 3; m--)
{
for (int n = m - 1; n >= 2; n--)
{
for (int p = n - 1; p >= 1; p--)
{
for (int q = p - 1; q >= 0; q--)
{
// the 7 card are i, j, k, m, n, p, q
counter++;
if (counter % 10000000 == 0)
Debug.WriteLine(counter.ToString("N0") + " " + sw.ElapsedMilliseconds.ToString("N0"));
}
}
}
}
}
}
}
sw.Stop();
System.Diagnostics.Debug.WriteLine("counter " + counter.ToString("N0") + " should be 133,784,560");
System.Diagnostics.Debug.WriteLine("sw " + sw.ElapsedMilliseconds.ToString("N0"));
}
}