c++华容道拼图

黄锭宪 2019-11-07 11:36:50
#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 那个大佬能调试一下吗?成
...全文
168 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
黄锭宪 2019-11-07
  • 打赏
  • 举报
回复
不用了,好像是越界了
黄锭宪 2019-11-07
  • 打赏
  • 举报
回复
不用了,好像是越界了

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧