我正在写一个Cribbage统计计算器。首先,我计算了每张可能的5张牌的分值,然后对wikipedia进行了检查,直到我的数字与他们的数字相同为止。
现在我计算每一对双手(你的手和婴儿床),大约2.3万亿组合,所以优化是关键。
所有卡都被分配了0到51之间的数字。Hand
构造函数的长度为int[]
,并假设最后一张卡是启动卡。既然已经完成了所有的点计算代码,我想优化手牌号码生成过程。
现在我有:
private static IEnumerable<Tuple<int[], int[]>> GetTwoHands()
{
bool[] avail = new bool[52];
for (int i = 0; i < 52; i++)
{
avail[i] = true;
}
// hand 1 cards
for (int i = 0; i < 52; i++)
{
avail[i] = false;
for (int j = i + 1; j < 52; j++)
{
avail[j] = false;
for (int k = j + 1; k < 52; k++)
{
avail[k] = false;
for (int l = k + 1; l < 52; l++)
{
avail[l] = false;
// hand 2 (crib) cards
for (int i2 = 0; i2 < 52; i2++)
{
if (!avail[i2])
{
continue;
}
avail[i2] = false;
for (int j2 = i2 + 1; j2 < 52; j2++)
{
if (!avail[j2])
{
continue;
}
avail[j2] = false;
for (int k2 = j2 + 1; k2 < 52; k2++)
{
if (!avail[k2])
{
continue;
}
avail[k2] = false;
for (int l2 = k2 + 1; l2 < 52; l2++)
{
if (!avail[l2])
{
continue;
}
avail[l2] = false;
// shared starter card
for (int m = 0; m < 52; m++)
{
if (!avail[m])
{
continue;
}
yield return Tuple.Create(new int[] { i, j, k, l, m }, new int[] { i2, j2, k2, l2, m });
}
avail[l2] = true;
}
avail[k2] = true;
}
avail[j2] = true;
}
avail[i2] = true;
}
avail[l] = true;
}
avail[k] = true;
}
avail[j] = true;
}
avail[i] = true;
}
}
其中i
到l
是第一手牌的号码,i2
到l2
是第二个号码, m
是入门卡的卡号。显然手中不能有重复的卡片,所以对于秒针,我确保每个卡号都不在手中。
我使用C#的IEnumerable<T>.AsParallel().ForAll(action)
来使用我的所有处理器内核,因此Hand(int[])
在操作中发生,而不是同步的GetTwoHands()
。
答案 0 :(得分:1)
我很晚才进来,但是因为我从7岁开始玩Cribbage(我52岁),我可能会有所帮助。
看起来在其他帖子中有一些递归的暗示。当你谈论大数字时,你也可能是迭代和战略性的。
我知道它可以发布URI,但是......它会节省很多时间。
如果你去http://www.cribbagematch.com/,你可以从2000年创建的Cribbage软件包中找到Tim Schempp的皇家婴儿床重启,目前处于测试阶段。有一个电子邮件地址可以联系到他。前几天我和他说话,他说他用ca.重新测试他的代码。他做出改变的1k游戏。
短篇小说长篇大论是他在2000年整理了几个文档,这些文档为你正在研究的统计数据以及基础算法提供了很多见解。他在2000年使用过。只是准备好看很多西格玛。两份PDF文档大约只有40多页。问他一份副本,因为他已经分享了很多年了。他的一些作品跑了好几天(记得,这是14年前的事了)。
如果您想要播放的数字不符合所提供的信息,那么就足以向您展示如何进行一些自己的特殊计算。例如投掷后,单人牌的四张牌手可以像这样分解:
4种...................... 13
总计................................. 1&#39; 820总组合
那么为什么蛮力和过滤器重复?
e.g。在玩家与玩家的游戏过程中,共有18个&#39; 395六张牌组合(一个玩家),3&#39; 274&375组合4张牌。 Tim指出The Play(4x4)的组合数量在1&#802;平方的1%之内。
如果您在方法论上更具战略性,我认为您会发现其中有超过2.3T的独特序列:您是否正在考虑处理同花顺?如果没有,那么你不需要担心52张牌,只有13张,有4次出现。将52改为13,看看这些数字是如何变得可管理的。如果你正在生成一个计算器,你仍然可以考虑刷新,这方面的数学计算要简单得多,而不是将其拖到你正在进行的计算的中间。
如果不出意外:查看Martin Broadhurst的网站(它的同名)并查看&#34; Combinatorial Algorithms&#34; (它在C中非常甜蜜)这将大大减少你的数字 - 使得管理所有各种组合/排列/等成为可能。您将使用几个不同的来获取所需的数据。它还可以让您的生活更轻松,确保您使用正确的算法。其中大多数允许您指定映射到字符,因此您可以替换&#34; T&#34;为了使对齐更容易,因为所有将显示的将是单个字符。
即使您使用Martin的库,也可以在不简化流程的情况下制作出一整套数据。
我不想责备你做家庭作业 - 我真的很好奇为什么你会产生如此多的原始Cribbage数据(它不常作为休闲运动)
我很久以前就已经碰到了很多论文(在500多个课程中,或在会议上介绍了Cribbage),他们只是在战略上产生了手中的东西。与随机投掷,与人工神经网络。他们正在关注游戏的一小部分(有时,代码是不对的!)。对于那个级别的课程,我很惊讶他们能够偷偷溜过他们的赞助商。 (如果只有他们知道的话。)即使对The Play应用人工神经网络也会更有趣,更复杂,而且非常有趣。
最后一个想法 - 这是大多数人都不会想到的东西 - 除了保留你手中的积分之外的东西:
&#34;您是经销商,已发卡(随机)&lt; 1&gt;,&lt; 2&gt;,&lt; 3&gt;,&lt; 4&gt;,&lt; 5&gt;&lt; 5&gt;&lt; 6&gt; ;。你需要5分才能盯住,pone需要7分。因为pone会打第一张牌并且会先计算他们的手牌,那么这六张牌的最佳投掷/保持策略是什么?&#34; (然后提供分析,看看你是否可以自己提出一两条规则)。
怎么样:&#34;如果你是经销商并有19分的得分手,那么你的婴儿床中你有19分的几率是多少?&#34;这些是让游戏变得有趣的见解类型。