gpt4 book ai didi

卡片拼图的算法解法

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:00:11 26 4
gpt4 key购买 nike

Given 是一款有九张方形卡片的益智游戏。
每张卡片上都有 4 张图片,分别是顶部、右侧、底部和左侧。
卡片上的每张图片都描绘了动物(鳄鱼)的前半部分或后半部分。每张图片有 5 种颜色中的一种。

目标:将九张卡片布置在 3x3 的网格中,使所有“内部”(完整的)鳄鱼与相邻的卡片正确组合,即具有前端和后端以及匹配的颜色。

为了直观地理解这个问题,这里有一张拼图图片:

我亲手找到了描述的解决方案。
尽管这个拼图乍一看很简单,但考虑到您可以用 4 种不同的方式旋转每个拼图,所以组合的数量非常多。

现在的问题是,我想要一个生成所有可能的 3x3 布局的算法,以便检查所有可能的解决方案(如果还有其他解决方案)。最好使用 Processing/Java。

到目前为止的想法:
我的方法是用一个由 4 个整数组成的数组来表示 9 个棋子中的每一个,代表棋子的 4 种旋转状态。然后生成这 9 个片段的所有可能排列,从片段数组中选择 4 个旋转状态中的 1 个。然后,函数 isValidSolution() 可以检查解决方案是否违反约束(颜色匹配和前后匹配)。

关于如何实现这个的任何想法?

最佳答案

有可能找到所有解,尽量不探索搜索树的所有不成功路径。下面的 C++ 代码,没有高度优化,在我的电脑上几乎立即找到了总共 2 个解决方案(结果是相同的唯一解决方案,因为有一个重复的瓷砖,正确答案?)。

此处避免探索所有可能性的技巧是在我们仍在放置图 block (该函数处理空图 block )时调用函数 isValidSolution()。另外,为了加快这个过程,我按照给定的顺序放置瓷砖,从中间开始,然后是左、右、上和下围绕它的十字,然后是左上角、右上角、下角——左边和右下角。其他组合可能会提供更快的执行速度。

当然可以优化这个,因为这个谜题中的特殊模式分布(带有字母的模式只接受一个可能的匹配),但这超出了我的回答范围。

#include<iostream>

// possible pattern pairs (head, body)
#define PINK 1
#define YELLOW 2
#define BLUE 3
#define GREEN 4
#define LACOSTE 5

typedef int8_t pattern_t; // a pattern is a possible color, positive for head, and negative for body
typedef struct {
pattern_t p[4]; // four patterns per piece: top, right, bottom, left
} piece_t;

unsigned long long int solutionsCounter = 0;

piece_t emptyPiece = {.p = {0, 0, 0, 0} };

piece_t board[3][3] = {
{ emptyPiece, emptyPiece, emptyPiece},
{ emptyPiece, emptyPiece, emptyPiece},
{ emptyPiece, emptyPiece, emptyPiece},
};

inline bool isEmpty(const piece_t& piece) {
bool result = (piece.p[0] == 0);
return result;
}

// check current solution
bool isValidSolution() {
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
if (!isEmpty(board[i][j]) && !isEmpty(board[i+1][j]) && (board[i][j].p[1] != -board[i+1][j].p[3])) {
return false;
}
}
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
if (!isEmpty(board[i][j]) && !isEmpty(board[i][j+1]) && (board[i][j].p[2] != -board[i][j+1].p[0])) {
return false;
}
}
}
return true;
}

// rotate piece
void rotatePiece(piece_t& piece) {
pattern_t paux = piece.p[0];
piece.p[0] = piece.p[1];
piece.p[1] = piece.p[2];
piece.p[2] = piece.p[3];
piece.p[3] = paux;
}

void printSolution() {
printf("Solution:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("\t %2i ", (int) board[j][i].p[0]);
}
printf("\n");
for (int j = 0; j < 3; j++) {
printf("\t%2i %2i", (int) board[j][i].p[3], (int) board[j][i].p[1]);
}
printf("\n");
for (int j = 0; j < 3; j++) {
printf("\t %2i ", (int) board[j][i].p[2]);
}
printf("\n");
}
printf("\n");
}

bool usedPiece[9] = { false, false, false, false, false, false, false, false, false };
int colocationOrder[9] = { 4, 3, 5, 1, 7, 0, 2, 6, 8 };

void putNextPiece(piece_t pieces[9], int pieceNumber) {

if (pieceNumber == 9) {
if (isValidSolution()) {
solutionsCounter++;
printSolution();
}
} else {
int nextPosition = colocationOrder[pieceNumber];
int maxRotations = (pieceNumber == 0) ? 1 : 4; // avoids rotation symmetries.
for (int pieceIndex = 0; pieceIndex < 9; pieceIndex++) {
if (!usedPiece[pieceIndex]) {
usedPiece[pieceIndex] = true;
for (int rotationIndex = 0; rotationIndex < maxRotations; rotationIndex++) {
((piece_t*) board)[nextPosition] = pieces[pieceIndex];
if (isValidSolution()) {
putNextPiece(pieces, pieceNumber + 1);
}
rotatePiece(pieces[pieceIndex]);
}
usedPiece[pieceIndex] = false;
((piece_t*) board)[nextPosition] = emptyPiece;
}
}
}
}

int main() {

// register all the pieces (already solved, scramble!)
piece_t pieces[9] = {
{.p = { -YELLOW, -BLUE, +GREEN, +PINK} },
{.p = { -YELLOW, -GREEN, +PINK, +BLUE} },
{.p = { -BLUE, -YELLOW, +PINK, +GREEN }},
{.p = { -GREEN, -BLUE, +PINK, +YELLOW }},
{.p = { -PINK, -LACOSTE, +GREEN, +BLUE }},
{.p = { -PINK, -BLUE, +GREEN, +LACOSTE }},
{.p = { -PINK, -BLUE, +PINK, +YELLOW }},
{.p = { -GREEN, -YELLOW, +GREEN, +BLUE }},
{.p = { -GREEN, -BLUE, +PINK, +YELLOW }}
};

putNextPiece(pieces, 0);

printf("found %llu solutions\n", solutionsCounter);

return 0;
}

关于卡片拼图的算法解法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22288734/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com