独立钻石棋也叫独立钻石
独立钻石源于18世纪法国的宫廷贵族,是一种自我挑战的单人棋游戏,可以锻炼逻辑思维能力。游戏玩法似中国跳棋,但不能走步,只能跳。棋子只能跳过相邻的柜子到空位上,并且把被跳过的柜子吃掉。棋子可以沿格线横、纵方向跳,但是不能斜跳,剩下越少棋子越好。它与中国人发明的“华容道”,匈牙利人发明的“魔方”并称智力游戏界的三大不可思议之一。独立钻石的棋盘有很多种变形,这个棋盘就是最初的样子,走法就是按照跳棋的走法,但是被跳过的棋子全部被吃掉,这样每跳一下棋盘上的棋子就会少一颗,而如果像跳棋那样连跳,每步就可能吃掉很多颗棋子。游戏的目的是要使棋盘上留下来的棋子越少越好。如果最后剩一子,而且正好位于棋盘正中心的第44号洞孔上,那就是最好的结果。此种局势称为“独立(粒)钻石”。之所以把这种游戏取上这一名称,是因为人们喜爱“金鸡独立”,视为祥瑞之故。
APK下载:点击打开链接
代码:
#include<iostream> using namespace std; int sum(int list[][7]) //sum函数用来返回最后剩余多少个棋子 { int sum = 0; for (int i = 0; i < 7; i++)for (int j = 0; j < 7; j++)sum += list[i][j]; return sum - 33; } void up(int list[][7], int i, int j) //跳过(i,j)往上跳 { list[i - 1][j] ++; list[i][j] --; list[i + 1][j] --; } void down(int list[][7], int i, int j) //跳过(i,j)往下跳 { list[i + 1][j] ++; list[i][j] --; list[i - 1][j] --; } void left(int list[][7], int i, int j) //跳过(i,j)往左跳 { list[i][j - 1] ++; list[i][j] --; list[i][j + 1] --; } void right(int list[][7], int i, int j) //跳过(i,j)往右跳 { list[i][j + 1] ++; list[i][j] --; list[i][j - 1] --; } bool move(int list[][7]) //找出任何可以跳的一步,并跳,跳完之后递归调用move(),直到不能再跳 { if (sum(list) < 4)return true; //当得到一种只剩下3颗棋子的方法,程序结束 for (int i = 1; i < 6; i++)for (int j = 0; j<7; j++) { if ((i == 3 || j>1 && j < 5) && list[i][j] == 2) { if (list[i - 1][j] == 1 && list[i + 1][j] == 2) //满足往上跳的条件 { up(list, i, j); if (move(list)) { cout << i << j << "up "; return true; } down(list, i, j); //恢复list和result list[i][j] += 2; } else if (list[i - 1][j] == 2 && list[i + 1][j] == 1)//满足往下跳的条件 { down(list, i, j); if (move(list)) { cout << i << j << "down "; return true; } up(list, i, j); list[i][j] += 2; } } } for (int i = 0; i < 7; i++)for (int j = 1; j < 6; j++) { if ((j == 3 || i>1 && i < 5) && list[i][j] == 2) { if (list[i][j - 1] == 1 && list[i][j + 1] == 2)//满足往左跳的条件 { left(list, i, j); if (move(list)) { cout << i << j << "left "; return true; } right(list, i, j); list[i][j] += 2; } else if (list[i][j - 1] == 2 && list[i][j + 1] == 1)//满足往右跳的条件 { right(list, i, j); if (move(list)) { cout << i << j << "right "; return true; } left(list, i, j); list[i][j] += 2; } } } return false; } int main() { int list[7][7]; //list用来表示状态,1表示空格,2表示有棋子,0表示角上的无效格子 for (int i = 0; i < 7; i++)for (int j = 0; j < 7; j++) { list[i][j] = 0; if (i == 2 || i == 3 || i == 4 || j == 2 || j == 3 || j == 4)list[i][j] = 2; } list[3][3] = 1; //初始化list move(list); cout << endl << "注意,输出的顺序是反着的"; system("pause>nul"); return 0; }
输出:
41right 42left 44left 30down 41right 43right 12down 13left 24up 25left 24right 44up 36up 14down 24up 25left 22right 24down 23up 34left 52up 32up 13down 23up 22down 32right 53up 33up 23down
注意,输出的顺序是反着的
对应的结果:
最后还剩下3个子。
程序如果改成求只剩下2个子的方案,理论上是求的出来的,不过时间估计会很长,反正我运行了10分钟还没有答案输出。
其实,要想最后只剩一个棋子,而且还在最中间,这并不难。
只要自己凭感觉,就能找出一个方案,比如我的方案:独立钻石棋详解
但是独立钻石棋真正难的是,如何在最少的步数达到这一要求。
关于步数,需要解释一下。
并不是所有的方案都需要31步,和跳棋一样,有连跳的现象存在。
实际上,最少的步数是18步。