我正在开发N-Puzzle游戏(也称为15-puzzle ...),你可以在正方形网格上分割图像,移除一个图像并随机播放。我对解谜的解决方案不太感兴趣,因为这取决于用户。但我想伪随机地洗牌。
我知道所有可能的洗牌中有一半会让董事会无法解决。假设我有一些rand() - esc函数并且我知道电路板的大小,是否有一种简单的伪随机方法来生成一个混洗状态?
我在内存中有一个游戏板,一个多维的整数数组。 我的方法只是将图像按相反的顺序放置,在偶数板上用倒数第二个图像切换最后一个图像。 我当前的功能如下,我正在使用Java。
private void shuffle()
{
gameState = new int[difficulty][difficulty];
int i = 0, N = (difficulty * difficulty) -1;
while (i < N)
gameState[(int)(i / difficulty)][i % difficulty] = N - ++i;
gameState[difficulty-1][difficulty-1] = N;
// N id even when the remainder of N/2 is 0
if ((difficulty % 2) == 0)
{
// swap 2nd to last and 3rd to last element
int tmpEl = gameState[difficulty-1][difficulty-2];
if (difficulty == 2)
{
gameState[1][0] = gameState[0][1];
gameState[0][1] = tmpEl;
}
else
{
gameState[difficulty-1][difficulty-2] = gameState[difficulty-1][difficulty-3];
gameState[difficulty-1][difficulty-3] = tmpEl;
}
}
}
答案 0 :(得分:6)
这个问题基本上归结为做一个小扭曲的标准shuffle算法。
关键的观察结果是,对于可以解决的15-puzzle,排列的奇偶性和空白方块的奇偶性必须相同。
首先使用标准算法为此目的创建随机排列。例如Knuth shuffle算法:Random Permutations
使用Knuth的shuffle(或Fisher-Yates shuffle)的优势在于它涉及交换数字,因此您可以轻松跟踪排列的奇偶校验。每次交换都保持奇偶校验(如果您交换1和3),或更改奇偶校验(如果您交换1和2)。
将空白方块放在与排列奇偶校验相同的奇偶校验上,然后就完成了。 如果置换具有奇数奇偶校验,则将空白放置为奇数平方(1,3,5,......随机选择)。如果排列具有偶数奇偶校验,则将空白放在偶数平方上。
答案 1 :(得分:3)
我的建议是跟踪阵列中的空方块(您已移除的部分) 然后,选择这个空方块的随机边(确保进行必要的边界检查)并将那边的那块用空方块“交换”。这模拟了玩家可以做的滑动动作 多次重复此操作(设置简单难度 - 难度设置您进行的迭代次数),每次在整个数组中“滑动”空方块。
使用这种方法,您只需跟踪空方块的位置,然后选择一个随机边移动。
希望这会对你有所帮助 - 我这里没有提供任何代码,只是一个简单的算法供你使用。
答案 2 :(得分:2)
只需生成随机谜题,直到您生成具有偶数奇偶校验的谜题。 http://heuristicswiki.wikispaces.com/N+-+Puzzle