Bar*_*lom 5 language-agnostic algorithm
在 Rummikub 游戏中,对于那些不知道的人来说,您有 4 种颜色的图块,上面有 13 个不同的数字(因此 4 x 13 = 52 个独特的图块),您必须使用它们来分组。有两种组:
R1-B1-G1)G6-G7-G8)我正在编写获取图块列表并检查它是否是有效组合的代码。到目前为止,它有效并且非常简单。
当我们引入小丑牌时,事情就变得困难了。您可以将它们用作任何图块来完成组合(例如G6-R6-J),并且可以使用多个(例如R4-R5-J-J-R8)。
我想我应该分两步验证与小丑的组合:
现在,如何执行步骤 1?我认为如果每组只允许有一个小丑,那就相当简单了:
不幸的是,允许使用多个小丑,这使得问题变得更加复杂,并且我一直在思考如何解决这个问题。
小智 5
最近,我编写了一款 Android Rummikub 游戏,也许我的代码可以帮助您(或者可能为时已晚;但仍然可以帮助其他人)。我不确定其中是否存在错误。因为我还没有检查太多。
我假设数字0~105。
对应卡牌为黑红黄绿及鬼卡(B1~0、B13~12、R1~13...G13~51、B1~52...G13~103 GHOST1~104、GHOST2~105)
这是代码:
public boolean isLegal(List<Byte> cards)
{
byte ghostNum = 0;
byte ghostRemain = 0;
byte size = (byte) cards.size();
if (size == 0)
{
return true;
}
else if (size < 3)
{
return false;
}
//get the num of ghostcard
Collections.sort(cards);
if (cards.get(size - 1) >= 104)
{
ghostNum++;
if (cards.get(size - 2) >= 104)
{
ghostNum++;
}
}
ghostRemain = ghostNum;
byte[] a = new byte[size - ghostNum];
byte[] b = new byte[size - ghostNum];
for (byte i = 0; i < size - ghostNum; i++)
{
a[i] = (byte) (cards.get(i) % 13); // the num of the tiles 0~12
b[i] = (byte) ((cards.get(i) / 13) % 4); // the color of the tiles 0~3(B,R,Y,G)
}
Arrays.sort(a);
Arrays.sort(b);
// tiles seems in same color
if (b[0] == b[size - 1 - ghostNum])
{
for (int i = 0; i < size - 1 - ghostNum; i++)
{
if (a[i + 1] - a[i] != 1)
{
ghostRemain = (byte) (ghostRemain - a[i + 1] + a[i] + 1);
if (ghostRemain < 0)
{
return false;
}
}
if (b[i] != b[i + 1])
{
return false;
}
}
return true;
// tiles in different colors
}
else if (b[0] != b[1])
{
for (int i = 0; i < size - 1 - ghostNum; i++)
{
if (a[i] != a[i + 1])
{
return false;
}
if (b[i] == b[i + 1])
{
return false;
}
}
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果你坚持把第一步作为你做的第一件事,你就是在给自己找麻烦。从这个角度解决问题在计算上效率很低。使用这种方法,你最终要做的就是尝试小丑替身的所有组合。这是一个坏主意。
这是一种毫不费力的替代方法:
依次执行所有这些检查,您将发现一组棋子是否是有效的组。
对于第 3 步,您必须考虑某些序列可能是相反的,例如 (joker, 3, 2, 1)。要检测这种情况,您可以快速扫描非小丑,看看它们是递增还是递减,然后考虑到这一点(然后小丑的值将比前一个少一)。
请注意,只有在步骤 2 中颜色才有意义,并且只有在步骤 3 中数字才有意义。