由于原始图像的某些部分丢失,难以解决相位滑动的难题[英] Difficult to solve the phaser sliding puzzle as some parts of the original image is missing

问题描述

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

这里演示了现场示例

但在输出游戏中,原始图像的某些部分丢失了.所以很难解决这个难题.我怀疑将图像切割成碎片的算法不正确.
片段的代码是,

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

推荐答案

这是经典的15puzzle,因为它通常有一个 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(下载包含 Delphi 源代码)
Photoscramble v1(下载包括 BlitzBasic 源代码)

本文地址:https://www.itbaoku.cn/post/1740219.html