第一次写这么长的代码。。。
代码
#include#include #include #include #include #include #include #include #include #define N 101 using namespace std; char map[N][N]; char YON; int show, judge, boom, ph, addb, endgame; int stax, stay, boxx, boxy, endx, endy, addbx, addby; int vis[N][N][4], flag[N][N]; // vis用来保存箱子和人的状态 int i, j, step, n, m, showtime, cnt; int dir[4][2]={-1,0,1,0,0,-1,0,1}; char P[4]= {'W','S','A','D'}; // w,a,s,d分别对应键盘是的按键 char M[4]= {'w','s','a','d'}; string temp, res; struct Node { int x,y; int px,py; string ans; }; int check(int x,int y) // 边界检查 { if(x < 1 || x > n || y < 1 || y > n || map[x][y] == 5) return 0; return 1; } queue q; queue que; /* 用嵌套BFS,外层BFS是找从箱子到终点找一条箱子移动的路径,用内层BFS来判断人能否从上一个点走到这一个点 . 箱子是可以经过一个点多次的,但是同一个点移动往同一个方向只能一次 */ int bfs_person(Node a,Node c) // 搜索人的位置 { memset(flag,0,sizeof(flag)); Node next,b; b.x=a.px, b.y=a.py; b.ans=""; while(!q.empty()) // 清空队列 q.pop(); q.push(b); flag[b.x][b.y]=1; while(!q.empty()) { Node now=q.front(); q.pop(); if(now.x==a.x&&now.y==a.y) { temp=now.ans; return 1; } for(int i=0; i<4; i++) // 搜索玩家的4个方向 { next=now; next.x+=dir[i][0]; next.y+=dir[i][1]; if(!check(next.x,next.y)||(next.x==c.x&&next.y==c.y)) continue; if(flag[next.x][next.y]) continue; flag[next.x][next.y]=1; next.ans=now.ans+M[i]; // 如果是可行解则把M中的方向键加入字符串中 q.push(next); } } return 0; } string bfs_box() // 搜索箱子的位置 { Node next,pre; Node st; memset(vis,0,sizeof(vis)); st.ans = ""; st.px = stax; // 玩家位置 st.py = stay; st.x = boxx; // 箱子位置 st.y = boxy; while(!que.empty()) // 清空队列 que.pop(); que.push(st); while(!que.empty()) { Node now = que.front(); que.pop(); if(map[now.x][now.y] == 4) // 当箱子到达终点时 return now.ans; for(i=0; i < 4; i++) // 搜索箱子的4个方向 { next = now; next.x += dir[i][0]; next.y += dir[i][1]; if(!check(next.x, next.y) || vis[next.x][next.y][i]) continue; pre=now; if(i == 0) pre.x = pre.x + 1; else if(i == 1) pre.x = pre.x - 1; else if(i == 2) pre.y = pre.y + 1; else if(i == 3) pre.y = pre.y - 1; if(!check(pre.px, pre.py) || !bfs_person(pre, now)) continue; vis[next.x][next.y][i] = 1; next.ans = now.ans + temp; next.ans = next.ans + P[i]; // 如果是可行解则把P中的方向键加入字符串中 next.px = now.x; next.py = now.y; que.push(next); } } return "-1"; // 无解返回-1 } void gotoxy(int x,int y) // 将光标移动到指定坐标 { COORD pos = {x,y}; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hOut,pos); } void color(int x) // 给文字上色 { if(x >= 0 && x <= 15) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x); else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7); } void createmap() // 随机生成地图 { int wall[N][N]; srand(time(NULL)); for(i=0;i > n; if(n > 100) cout << "输入错误请重新输入:"; }while(n > 100); cout << "请输入一个数来决定障碍物密度(输入的数字越小,障碍物越多,n>=4):"; do { cin >> m; if(m < 4) cout << "输入错误请重新输入:"; }while(m < 4); cout << "请输入一个数来决定地图中炸弹补给点的个数(n<=5):"; do { cin >> addb; if(addb > 5) cout << "输入错误请重新输入:"; }while(addb > 5); cout << "地图太大,地图生成的速度可能会很慢"; } void tips() // 提示栏 { gotoxy(n+2,0); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,1); color(2); printf("'%c'为小人(玩家可以通过键盘的w,s,a,d控制)",1); gotoxy(n+2,2); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,3); color(2); printf("'%c'为箱子(玩家可以推动,但不可以拉)",3); gotoxy(n+2,4); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,5); color(2); printf("'%c'为墙体(玩家和箱子都不可以穿过)",5); gotoxy(n+2,6); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,7); color(2); printf("'%c'为炸弹补给点,到达该地方炸弹数量+2",6); gotoxy(n+2,8); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,9); color(2); printf("'.'为自动寻路时玩家和箱子的路径"); gotoxy(n+2,10); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,11); color(2); printf("' '为玩家和箱子都可以通过的地方"); gotoxy(n+2,12); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,13); color(2); cout << "按下h自动寻路"; gotoxy(n+2,14); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,15); color(2); cout << "按下p判断当前是否有解"; gotoxy(n+2,16); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,17); color(2); cout << "按下b破坏周围墙体"; gotoxy(n+2,18); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; gotoxy(n+2,19); color(2); cout << "按下q提前结束游戏"; gotoxy(n+2,20); color(3); cout << "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-"; } void ismap() // 地图一定有解 { do // 用do--while可以先随机生成一次地图,如果不符合则继续生成 { createmap(); createbox(); addboom(); cnt++; res = bfs_box(); if(res == "-1") { for(i=0;i 0) { map[stax-1][stay] = 0; map[stax+1][stay] = 0; map[stax][stay-1] = 0; map[stax][stay+1] = 0; map[stax-1][stay-1] = 0; map[stax+1][stay-1] = 0; map[stax-1][stay+1] = 0; map[stax+1][stay+1] = 0; boom--; } else { gotoxy(n+2,21); color(4); cout << "你的炸弹用完了,输入任意键继续游戏......"; getch(); } } int main() { while(1) { system("cls"); // 如果开始游戏则清屏 // 各个变量初始化 endgame = 0; ph = 0; judge = 0; show = 0; cnt = 0; stax = 1; stay = 1; showtime = 100; res = ""; memset(map,0,sizeof(map)); menu(); ismap(); while(1) // 游戏主题部分 { system("cls"); color(8); drawmap(); // 打印地图 tips(); gotoxy(stay,stax); // 打印玩家符号 color(5); printf("%c",1); gotoxy(boxy,boxx); // 打印箱子符号 color(4); printf("%c",3); // 以下是打印一些游戏提示 gotoxy(0,n+1); color(7); cout << "当前移动步数:" << step; gotoxy(0,n+2); color(7); cout << "当前玩家坐标:" << '(' << stax << ',' << stay << ')'; gotoxy(0,n+3); color(7); cout << "生成地图数:" << cnt << endl; gotoxy(0,n+4); color(7); cout << "炸弹剩余数:"; for(i=0;i > showtime; automove(res); // 初始化 showtime = 100; show = 0; } gotoxy(0,n+8); // 判断游戏胜利或者失败 if(res == "-1") { cout << "你失败了,是否开始新的游戏Y/N?"; cin >> YON ; YON = tolower(YON); break; } if(boxx == endx && boxy == endy) { cout << "你赢了,是否开始新的游戏Y/N?"; cin >> YON; YON = tolower(YON); break; } if(endgame == 1) { cout << "你提前结束了游戏,是否开始新的游戏Y/N?"; cin >> YON; YON = tolower(YON); break; } } if(YON == 'n') // 判断是否需要开始新的游戏 break; if(YON == 'y') continue; } }
Comments | NOTHING