0

我已经制作了一个 5 骰子 yahtzee 游戏,我正在尝试让它也适用于 6 骰子,你能帮助这两个函数更通用我的代码到现在 :)

我已经在列表中准备了骰子值,int[] i 并且我用这个非常简单的方法检测到了 fullHouse:

 Array.Sort(i);

 if( ((i[0] == i[1]) && (i[1] == i[2]) && (i[3] == i[4]))
  {
    ... sum it up
  }
 else if((i[0] == i[1]) && (i[2] == i[3]) && (i[3] == i[4]))
  {
     ... sum it up
  }

我用这种非常简单的方法直接检测到

 Array.Sort(i);

  if( ((i[0] == 1) &&
       (i[1] == 2) &&
       (i[2] == 3) &&
       (i[3] == 4) &&
       (i[4] == 5)) ||
      ((i[0] == 2) &&
       (i[1] == 3) &&
       (i[2] == 4) &&
       (i[3] == 5) &&
       (i[4] == 6)) )
  {
    ... sum it up
  }

提前谢谢

4

2 回答 2

1

像这样完全手动编写逻辑会产生笨拙且难以扩展的代码。用 LINQ 抽象一些东西会有很大帮助。

要检测满屋,请按值分组掷骰并检查每组的基数(我使用i掷骰数组来遵循原始代码,但这对于数组来说是个坏名字):

var groups = i.GroupBy(i => i);

然后你可以很容易地检查满屋:

var hasFullHouse = groups.Any(g1 => 
    g1.Count >= 3 && groups.Except(g1).Any(g2 => g2.Count >= 2)
);

“如果有任何组至少有 3 个骰子,而另一个组至少有 2 个骰子,那么你就有了满堂彩。”

要检查直线,请按顺序遍历组。对于每一个,检查代表前一个骰子的组是否存在。如果它确实增加了一个计数器,否则重置计数器。如果计数器达到 5,则为顺子:

var runLength = 0;
var map = groups.ToDictionary(g => g.Key, g => g.Count);
foreach (var roll in map.Keys.OrderBy(k => k))
{
    var runLength = map.Contains(roll - 1) ? runLength + 1 : 0;
    if (runLength == 5)
    {
        // straight detected
    }
}

无论游戏中的骰子数量如何,这两种方法都将起作用。

于 2013-10-21T08:37:02.260 回答
1

如果你有整数列表,你可以检查它们是否是连续值(直线)

bool isfullhouse = !list.Select((i,j) => i-j).Distinct().Skip(1).Any();
return isfullhouse;

您可以通过以下方式使您的数组成为列表:

var list = yourArray.ToList();

第二个可以修改为:

var list = yourArray.ToList().Skip(2);
if(yourArray[0]==yourArray[1]) // checks XX
{
    var distincted = list.Distinct(); 
    if(distincted.Count()==1) // checks if other values are equal
    {
       if(distincted[0]!=yourArray[0]) // checks if not XXXXXX
             return true; 
    }
}
return false;

它会检查是否有像 XX YYYY 这样的满屋(它可以有任意数量的 Y)

于 2013-10-21T08:04:33.997 回答