#include<iostream>
#include <graphics.h>
#include <conio.h>
#include<math.h>
#include <windows.h>
using namespace std;
int examine(int a[]);//数组是否整齐;
int retemp(int x, int y);
int examine(int a[])
{
int i = 0;
for (i = 0; i < 10; i++)
{
if (a[i] != i)
return 0;
}
return 1;
}
int f[11] = { 1,1,2,6,24,120,720,5040,40320,362880,3628800 };
int current_kangtuo;
int kangtuo(int status[]);
typedef struct shuzu
{
int date;
struct shuzu *next;
}shuzu;
typedef struct node
{
int date;
struct node *next;
}node;
void pushshuzu(shuzu *shuzuhead, int n);
void pushshuzu(shuzu *shuzuhead, int n)
{
shuzu *s;
s = (shuzu *)malloc(sizeof(shuzu));
s->date = n;
s->next = shuzuhead->next;
shuzuhead->next = s;
}
void pushnode(node *head, int n);
void pushnode(node *head,int n)
{
node *s;
s = (node *)malloc(sizeof(node));
s->date = n;
s->next = head->next;
head->next = s;
}
int status[10] = {1,5,6,7,3,2,0,4,8,9};// {1, 0, 2, 3, 4, 5, 6, 7, 8, 9};
int coordinate[10][2] = { {1,-76},{0,0},{100,0},{200,0},{0,76},{100,76},{200,76},{0,152},{100,152},{200,152} };
int next_num[10][4] =
{ //左、上、右、下
{-1,-1,-1,1},
{-1,0,2,4},
{1,-1,3,5},
{2,-1,-1,6},
{-1,1,5,7},
{4,2,6,8},
{5,3,-1,9},
{-1,4,8,-1},
{7,5,9,-1},
{8,6,-1,-1}
};
void backward(node *head);
int forward(shuzu *shuzuhead, node *head);
void auto_deep_play(int current_status[], shuzu *shuzuhead, node *head);
int count1 = 0;
IMAGE image[10];//图片指针
TCHAR s[5];
void show();
int main()
{
shuzu *shuzuhead = (shuzu *)malloc(sizeof(shuzu));
shuzuhead->next = NULL;
MOUSEMSG m;//定义一个鼠标消息
node *head;
head = (node *)malloc(sizeof(node));
head->next = NULL;
loadimage(&image[0], _T("0.jpg"));
loadimage(&image[1], _T("1.jpg"));
loadimage(&image[2], _T("2.jpg"));
loadimage(&image[3], _T("3.jpg"));
loadimage(&image[4], _T("4.jpg"));
loadimage(&image[5], _T("5.jpg"));
loadimage(&image[6], _T("6.jpg"));
loadimage(&image[7], _T("7.jpg"));
loadimage(&image[8], _T("8.jpg"));
loadimage(&image[9], _T("9.jpg"));
int i = 0;
int temp;
int temp1=-1;
int temp2;
int choic;
cout << "请输入你选择的游戏模式";
cin >> choic;
initgraph(680, 680);// 初始化绘图窗口
setorigin(0, 76);//设置坐标原点
cleardevice();//清屏
////closegraph();
switch (choic)
{
case 1:
for (int i = 0; i <= 9; i++)
{
putimage(coordinate[i][0], coordinate[i][1], &image[status[i]]);
}
while (1)
{
m = GetMouseMsg();
if (m.uMsg == WM_LBUTTONDOWN)
{
temp2 = retemp(m.x, m.y);
if (temp2 == -1)
break;
for (i = 0; i < 4; i++)
{
if (status[next_num[temp2][i]] == 0)//第i号位置上下左右的status是否有等于0的;
{
swap(status[next_num[temp2][i]], status[temp2]);
count1++;
break;
}//返回几号位置上下左右的位置
}
//Sleep(10);
show();
temp = examine(status);//检查数组是否排序
if (temp == 1)
{
closegraph();
cout << "你走了" << count1 << endl;
break;
}
}
}
break;
case 2:
for (int i = 0; i <= 9; i++)
{
putimage(coordinate[i][0], coordinate[i][1], &image[status[i]]);
}
auto_deep_play(status, shuzuhead, head);
break;
}
system("pause");
}
void auto_deep_play(int current_status[],shuzu *shuzuhead,node *head)//深度优先自动运行模式
{
current_kangtuo = kangtuo(current_status);//求当前的康拓展开值
while (current_kangtuo != 1)//已整齐
{
if (current_status[0] != 0)//深度优先向前
{
forward(shuzuhead, head);
Sleep(300); //暂停显示
cleardevice();//清屏
for (int i = 0; i <= 9; i++)
{
putimage(coordinate[i][0], coordinate[i][1], &image[status[i]]);
}
_stprintf_s(s, _T("%d"), count1);
outtextxy(300, 400, s);
if (examine(status) == 1)//检测是否走整齐了
{
closegraph();
cout << "你走了" << count1 << endl;
break;
}
//向前(压栈、已走步数加1、刷新图片显示、更新当前状态、计算当前状态康拓展开值并设为已访问)
//如果当前状态为终止状态,游戏成功,结束。
}
else//向前失败,则回退
{
if (head->next != NULL)
{
backward(head);
cleardevice();//清屏
for (int i = 0; i <= 9; i++)
{
putimage(coordinate[i][0], coordinate[i][1], &image[status[i]]);
}
_stprintf_s(s, _T("%d"), count1);
outtextxy(300, 400, s);
}
else
{
// 栈已空的情况
closegraph();
cout << "游戏无解,结束" << endl;
}
}
}
}
void show()
{
cleardevice();//清屏
for (int i = 0; i <= 9; i++)
{
putimage(coordinate[i][0], coordinate[i][1], &image[status[i]]);
}
_stprintf_s(s, _T("%d"), count1);
outtextxy(300, 400, s);
}
int forward(shuzu *shuzuhead, node *head)//shuzu是用来记录康拓,head记录压栈
{
int i;
int temp=0;
shuzu *e;
e = (shuzu *)malloc(sizeof(shuzu));
for (i = 0; i < 10; i++)//根据当前状态,找到0号图片所在位置,并求出在d方向下的邻近位置;
{
if (status[i] == 0)
break;
}//0号图片所在的位置;
for (int d = 0; d < 4; d++) //在选择方向时,可以适当加入启发(例如选择更接近终止状态的方向前进),实现优化
{
//第i号位置的上下左右是否等于-1,不等于-1即可走;
if (status[next_num[i][d]]!=-1)//d方向是合法的图片位置,则尝试向前走
{
swap(status[next_num[i][d]], status[i]);// 尝试移动图片;
current_kangtuo = kangtuo(status);//移动后的康拓拓展
e = shuzuhead;
while (e->next != NULL)
{
if (e->date == current_kangtuo)
{
temp = -1;//如果这个数组里面有这个状态
break;
}
e = e->next;
}
Sleep(300);
show();
if (temp == -1)//这个状态已经遍历过,不能再遍历,换回来
{
swap(status[next_num[i][d]], status[i]); //还原状态,d方向不可走
temp = 0;
}
else//沿d方向向前,压栈
{
pushshuzu(shuzuhead, current_kangtuo);//保存这个temp,表示已经走过这个状态
pushnode(head, d);////d方向压栈
count1++;//已走步数加1
//更新当前0号图片位置,标志当前状态为已访问状态kangtuo_status[当前状态对应的康拓展开值]
temp = 0;
return 1;
}
}
}
return 0;//没有一个方向可走,前进失败
}
void backward(node *head)//后退
{
int i;
node *s = (node *)malloc(sizeof(node));
s = head->next;
int temp = s->date;
if (temp == 0)
temp = 2;
else if (temp == 1)
temp = 3;
else if (temp == 2)
temp = 0;
else
temp = 1;
for (i = 0; i < 10; i++)
{
if (status[i] == 0)
break;
}//0号图片所在的位置;
swap(status[next_num[i][temp]], status[i]);
head->next = s->next;
count1++;//根据当前状态以及d方向的方向,退回到上一个状态,已走步数加1
free(s);
}
int kangtuo(int status[])//求康拓展开值
{
int ans = 0;
int n = 10;
for (int i = 0; i < n + 1; i++)
{
int lessnum = 0;
for (int j = i + 1; j < n + 1; j++)
if (status[j] < status[i])
lessnum++;
ans += lessnum * f[n - i];
}
return ans + 1;
}
int retemp(int x, int y)//游戏模式
{
int temp2;
if (0 <= x && 100 > x && 0 <= y && 76 > y)
temp2 = 0;
else if (100 <= x && 200 > x && 76 <= y && 76 + 76 > y)
temp2 = 2;
else if (0 <= x && 100 > x && 76 + 76 <= y && 152 + 76 > y)
temp2 = 4;
else if (0 <= x && 100 > x && 0 + 76 <= y && 76 + 76 > y)
temp2 = 1;
else if (200 <= x && 300 > x && 0 + 76 <= y && 76 + 76 > y)
temp2 = 3;
else if (100 <= x && 200 > x && 76 + 76 <= y && 152 + 76 > y)
temp2 = 5;
else if (200 <= x && 300 > x && 76 + 76 <= y && 152 + 76 > y)
temp2 = 6;
else if (0 <= x && 100 > x && 152 + 76 <= y && 228 + 76 >= y)
temp2 = 7;
else if (100 <= x && 200 > x && 152 + 76 <= y && 228 + 76 >= y)
temp2 = 8;
else if (200 <= x && 300 > x && 152 + 76 <= y && 228 + 76 >= y)
temp2 = 9;
else
return -1;
return temp2;
}
华容道拼图
问题:为什么第三轮的时候 status[4]会变成 3266880
那个大佬能调试一下吗?成