8跳棋(1)90跳棋(2)240跳棋(3)
【摘要】
智力游戏
跳棋(1)非常简单,我是自己随便搞搞就过了。
跳棋(2)把70改成了54,我就开始编程了。
代码:
#include<iostream>
using namespace std;
int number = 54; //number是剩余次数
//flag是上一次的运动方向,有8种:0开始,1上移,2下...
跳棋(1)非常简单,我是自己随便搞搞就过了。
跳棋(2)把70改成了54,我就开始编程了。
代码:
#include<iostream>
using namespace std;
int number = 54; //number是剩余次数
//flag是上一次的运动方向,有8种:0开始,1上移,2下移,3上跳,4下跳,5左移,6右移,7左跳,8右跳
bool move(int list[][5],int mi,int mj,int flag) //(i,j)是空格
{
int save_number = number;
if (number <= 0)//判断是不是已经成功了
{
for (int i = 0; i < 5; i++)for (int j = 0; j < 5; j++)
if ((i<2 || j<2) && (list[i][j] == 1 || list[i][j] == 0))return false;
else if ((i>2 || j>2 ) && list[i][j] %2 == 0)return false;
return true;
}
number--;
int ii, jj; //要移动的格子相对于空格的位移
for (int f = 1; f <= 8; f++) //8种flag
{
//防止无意义的死循环
if (flag + f == 3)continue; //1、2
else if (flag == 3 && f == 4)continue; //3、4
else if (flag == 4 && f == 3)continue;
else if (flag * f == 30)continue; //5、6
else if (flag + f == 15)continue; //7、8
if (f <= 4) //确定ii和jj
{
jj = 0;
if (f == 1)ii = 1;
else if (f == 2)ii = -1;
else if (f == 3)ii = 2;
else ii = -2;
}
else
{
ii = 0;
if (f == 5)jj = 1;
else if (f == 6)jj = -1;
else if (f == 7)jj = 2;
else jj = -2;
}
if (mi + ii >= 0 && mi + ii < 5 && mj + jj >= 0 && mj + jj < 5 )
{
if (list[mi + ii][mj + jj] == 1 && f % 2 == 0 || list[mi + ii][mj + jj] == 2 && f % 2 != 0)///这一步对于减少工作量至关重要
{
list[mi][mj] = list[mi + ii][mj + jj]; //移动或者跳动
list[mi + ii][mj + jj] = 0;
bool b = move(list, mi + ii, mj + jj, f);
list[mi + ii][mj + jj] = list[mi][mj];
list[mi][mj] = 0;
if (b)
{
cout << endl<<endl;
if (f == 1)cout << "往上移动";
if (f == 2)cout << "往下移动";
if (f == 3)cout << "往上跳";
if (f == 4)cout << "往下跳";
if (f == 5)cout << "往左移动";
if (f == 6)cout << "往右移动";
if (f == 7)cout << "往左跳";
if (f == 8)cout << "往右跳";
for (int i = 0; i < 5; i++)
{
cout << endl;
for (int j = 0; j < 5; j++)
{
if (list[i][j] == 1)cout << "○";
else if (list[i][j] == 2)cout << "●";
else cout << " ";
}
}
return true;
}
}
}
}
number = save_number;
return false;
}
int main()
{
int list[5][5]; //list用来表示状态,0表示空格,1表示白子,2表示黑子,-1表示无效的8个格子
for (int i = 0; i < 5; i++) //初始化list
{
for (int j = 0; j < 5; j++)
{
if (i<3 && j<3)list[i][j] = 1;
else if (i>1 && j>1)list[i][j] = 2;
else list[i][j] = -1;
}
}
list[2][2] = 0;
move(list,2,2,0);
cout << endl << endl << "注意,输出的顺序是反着的";
system("pause>nul");
return 0;
}
其中,
if (list[mi + ii][mj + jj] == 1 && f % 2 == 0 || list[mi + ii][mj + jj] == 2 && f % 2 != 0)
这句话是使得黑子只能往上或者往左移动,白子只能往下或者往右移动。
这样做一定可以减掉大量的枝,节省大量时间,但是能不能找到需要的解反而不清楚,要看运行结果才知道。
事实证明,用这个剪枝之后可以得到最优解,而且很快就得到了。
运行结果:
跳棋(3)又把54改成了46
只需要修改全局变量 int number = 46; 即可
运行时间:大约40秒。
运行结果:
往左移动
●●●
●●●
● ●○○
○○○
○○○
往右跳
●●●
●●●
●○● ○
○○○
○○○
往右移动
●●●
●●●
●○●○
○○○
○○○
往左跳
●●●
●●●
●○ ○●
○○○
○○○
往上移动
●●●
●●
●○●○●
○○○
○○○
往下跳
●●●
●●○
●○●○●
○○
○○○
往下移动
●●●
●●○
●○●○●
○○○
○○
往上跳
●●●
●●○
●○ ○●
○○○
●○○
往左跳
●●●
●●○
○●○●
○○○
●○○
往上移动
●●●
●○
●○●○●
○○○
●○○
往右跳
●●●
○●
●○●○●
○○○
●○○
往下跳
●●●
○●○
●○●○●
○○
●○○
往上移动
●●●
○●○
●○ ○●
●○○
●○○
往左跳
●●●
○●○
○●○●
●○○
●○○
往右移动
●●●
○●○
○ ●○●
●○○
●○○
往右跳
●●●
○●○
○○● ●
●○○
●○○
往下跳
●●●
○●○
○○●○●
●○○
● ○
往左移动
●●●
○●○
○○●○●
●○○
●○
往右跳
●●●
○●○
○○●○●
●○○
○●
往上跳
●●●
○●○
○○●○
●○○
○●●
往左跳
●●●
○●○
○○ ○●
●○○
○●●
往上跳
●●
○●○
○○●○●
●○○
○●●
往左移动
● ●
○●○
○○●○●
●○○
○●●
往下跳
●○●
○●○
○ ●○●
●○○
○●●
往右跳
●○●
○●○
○○● ●
●○○
○●●
往下移动
●○●
○●○
○○●○●
● ○
○●●
往左移动
●○●
○●○
○○●○●
●○
○●●
往右跳
●○●
○●○
○○●○●
○●
○●●
往上移动
●○●
○●○
○○●○
○●●
○●●
往左跳
●○●
○●○
○○ ○●
○●●
○●●
往上跳
●○
○●○
○○●○●
○●●
○●●
往左跳
○●
○●○
○○●○●
○●●
○●●
往下移动
○○●
●○
○○●○●
○●●
○●●
往右跳
○○●
○●
○○●○●
○●●
○●●
往下跳
○○●
○●○
○○●○●
●●
○●●
往下移动
○○●
○●○
○○●○●
○●●
●●
往上跳
○○●
○●○
○○ ○●
○●●
●●●
往上跳
○○
○●○
○○●○●
○●●
●●●
往下移动
○○○
○●
○○●○●
○●●
●●●
往左移动
○○○
○ ●
○○●○●
○●●
●●●
往下移动
○○○
○○●
○ ●○●
○●●
●●●
往右跳
○○○
○○●
○○● ●
○●●
●●●
往左移动
○○○
○○●
○○ ●●
○●●
●●●
往上移动
○○○
○○
○○●●●
○●●
●●●
往下跳
○○○
○○○
○○●●●
●●
●●●
往上移动
○○○
○○○
○○ ●●
●●●
●●●
注意,输出的顺序是反着的
文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/nameofcsdn/article/details/52745351
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)