由于原始图像的某些部分丢失,难以解决移相器滑动难题

Difficult to solve the phaser sliding puzzle as some parts of the original image is missing

我正在尝试创建移相器示例游戏滑动拼图

Live example is demonstrated here

但在输出游戏中,原始图像的某些部分丢失了。所以很难解开这个谜题。 我怀疑裁剪图片的算法不正确。
件的代码是,

function prepareBoard() {

    var piecesIndex = 0,
        i, j,
        piece;

    BOARD_COLS = Math.floor(game.world.width / PIECE_WIDTH);
    BOARD_ROWS = Math.floor(game.world.height / PIECE_HEIGHT);

    piecesAmount = BOARD_COLS * BOARD_ROWS;

    shuffledIndexArray = createShuffledIndexArray();

    piecesGroup = game.add.group();

    for (i = 0; i < BOARD_ROWS; i++)
    {
        for (j = 0; j < BOARD_COLS; j++)
        {
            if (shuffledIndexArray[piecesIndex]) {
                piece = piecesGroup.create(j * PIECE_WIDTH, i * PIECE_HEIGHT, "background", shuffledIndexArray[piecesIndex]);
            }
            else { //initial position of black piece
                piece = piecesGroup.create(j * PIECE_WIDTH, i * PIECE_HEIGHT);
                piece.black = true;
            }
            piece.name = 'piece' + i.toString() + 'x' + j.toString();
            piece.currentIndex = piecesIndex;
            piece.destIndex = shuffledIndexArray[piecesIndex];
            piece.inputEnabled = true;
            piece.events.onInputDown.add(selectPiece, this);
            piece.posX = j;
            piece.posY = i;
            piecesIndex++;
        }
    }

}

function createShuffledIndexArray() {

    var indexArray = [];

    for (var i = 0; i < piecesAmount; i++)
    {
        indexArray.push(i);
    }

    return shuffle(indexArray);

}

function shuffle(array) {

    var counter = array.length,
        temp,
        index;

    while (counter > 0)
    {
        index = Math.floor(Math.random() * counter);

        counter--;

        temp = array[counter];
        array[counter] = array[index];
        array[index] = temp;
    }

    return array;
    
}

请问有人知道吗?请分享任何正确切割碎片的算法。

提前致谢 iijb

这是经典的 15 拼图,因为它传统上有一个 4x4 网格,其中缺少 1 个方块(4x4-1=15 个方块)。然而,拼图实际上可以是任何网格大小(4x3、5x4、6x6 等)。

您正在使用 .destIndex 属性 来跟踪它们的位置,但您可以只给每个图块一个编号索引。我认为这样更容易,因为当所有的瓷砖都被排序时,难题就解决了,它也有助于检查是否可解决算法。

对于这种滑动拼图,有两点需要考虑,尤其是第二点:

  1. 总是缺少一个方块,因为那是玩家可以用来将方块滑入的空位。最常见的是,缺失的图块是图像右下角的图块。

在您的算法中,空白图块始终是图像左上角的图块。 这是不寻常的,玩家可能不会想到这一点,但理论上这并不重要,您可以通过这种方式制作一个可行的谜题。然后,您通过值 1(或者对于零索引可能为 0)跟踪代码中的空图块,因为它是第一个图块。

  1. 有些配置是无法解决的,即并非所有随机打乱的瓷砖情况都可以通过滑动瓷砖来解决。

当解题所需的反转(开关)次数为偶数而不是奇数时,该谜题是可解的。所以计算更大数字的对数 在一个较小的前面(=一个倒置)。例如,在缺少右下角拼图的 3x3 拼图中:

5 3 4
2 6 1
8 7

在数组中它看起来像这样 [5,3,4,2,6,1,8,7,9],所以数对是 5-3、5-4、5-2、5- 1、3-2、3-1、4-2、4-1、2-1、6-1、8-7。这等于 11 对,因此需要 11 次反转。这不是偶数,因此这个配置是无解的。顺便说一下,丢失的图块在内部具有最大可能的数字,在这种情况下为 9。

您可以使用此方法检测无法解决的谜题。要使其再次可解,您需要做的就是切换任意两个图块,例如最上面的前两个图块(示例中为 5 和 3)。当需要的开关数为偶数时,就已经可以求解了,什么都不用做。

我做过类似的益智游戏,你可以在这里查看源代码,看看它是如何工作的:

Photoscramble v2 (download incl Delphi source)
Photoscramble v1 (download incl BlitzBasic source)