8跳棋(1)90跳棋(2)221跳棋(3)

智力游戏

8跳棋(1)90跳棋(2)221跳棋(3)_第1张图片




跳棋(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)

这句话是使得黑子只能往上或者往左移动,白子只能往下或者往右移动。

这样做一定可以减掉大量的枝,节省大量时间,但是能不能找到需要的解反而不清楚,要看运行结果才知道。

事实证明,用这个剪枝之后可以得到最优解,而且很快就得到了。

运行结果:

8跳棋(1)90跳棋(2)221跳棋(3)_第2张图片


跳棋(3)又把54改成了46

只需要修改全局变量  int number = 46;  即可


运行时间:大约40秒。

运行结果:

往左移动
●●●
●●●
●  ●○○
    ○○○
    ○○○


往右跳
●●●
●●●
●○●  ○
    ○○○
    ○○○


往右移动
●●●
●●●
●○●○
    ○○○
    ○○○


往左跳
●●●
●●●
●○  ○●
    ○○○
    ○○○


往上移动
●●●
●●
●○●○●
    ○○○
    ○○○


往下跳
●●●
●●○
●○●○●
      ○○
    ○○○


往下移动
●●●
●●○
●○●○●
    ○○○
      ○○


往上跳
●●●
●●○
●○  ○●
    ○○○
    ●○○


往左跳
●●●
●●○
  ○●○●
    ○○○
    ●○○


往上移动
●●●
  ●○
●○●○●
    ○○○
    ●○○


往右跳
●●●
○●
●○●○●
    ○○○
    ●○○


往下跳
●●●
○●○
●○●○●
      ○○
    ●○○


往上移动
●●●
○●○
●○  ○●
    ●○○
    ●○○


往左跳
●●●
○●○
  ○●○●
    ●○○
    ●○○


往右移动
●●●
○●○
○  ●○●
    ●○○
    ●○○


往右跳
●●●
○●○
○○●  ●
    ●○○
    ●○○


往下跳
●●●
○●○
○○●○●
    ●○○
    ●  ○


往左移动
●●●
○●○
○○●○●
    ●○○
      ●○


往右跳
●●●
○●○
○○●○●
    ●○○
    ○●


往上跳
●●●
○●○
○○●○
    ●○○
    ○●●


往左跳
●●●
○●○
○○  ○●
    ●○○
    ○●●


往上跳
●●
○●○
○○●○●
    ●○○
    ○●●


往左移动
●  ●
○●○
○○●○●
    ●○○
    ○●●


往下跳
●○●
○●○
○  ●○●
    ●○○
    ○●●


往右跳
●○●
○●○
○○●  ●
    ●○○
    ○●●


往下移动
●○●
○●○
○○●○●
    ●  ○
    ○●●


往左移动
●○●
○●○
○○●○●
      ●○
    ○●●


往右跳
●○●
○●○
○○●○●
    ○●
    ○●●


往上移动
●○●
○●○
○○●○
    ○●●
    ○●●


往左跳
●○●
○●○
○○  ○●
    ○●●
    ○●●


往上跳
●○
○●○
○○●○●
    ○●●
    ○●●


往左跳
  ○●
○●○
○○●○●
    ○●●
    ○●●


往下移动
○○●
  ●○
○○●○●
    ○●●
    ○●●


往右跳
○○●
○●
○○●○●
    ○●●
    ○●●


往下跳
○○●
○●○
○○●○●
      ●●
    ○●●


往下移动
○○●
○●○
○○●○●
    ○●●
      ●●


往上跳
○○●
○●○
○○  ○●
    ○●●
    ●●●


往上跳
○○
○●○
○○●○●
    ○●●
    ●●●


往下移动
○○○
○●
○○●○●
    ○●●
    ●●●


往左移动
○○○
○  ●
○○●○●
    ○●●
    ●●●


往下移动
○○○
○○●
○  ●○●
    ○●●
    ●●●


往右跳
○○○
○○●
○○●  ●
    ○●●
    ●●●


往左移动
○○○
○○●
○○  ●●
    ○●●
    ●●●


往上移动
○○○
○○
○○●●●
    ○●●
    ●●●


往下跳
○○○
○○○
○○●●●
      ●●
    ●●●


往上移动
○○○
○○○
○○  ●●
    ●●●
    ●●●


注意,输出的顺序是反着的

你可能感兴趣的:(8跳棋(1)90跳棋(2)221跳棋(3))