总结
新增功能,保存个人信息以及完成时间
1. 实现的功能
1.将迷宫通过可视化方法直观的显示出来,直观的显示路和墙的位置
void Create_graph()
{
initgraph(1280, 640);
setlinecolor(LIGHTGREEN);
//fillrectangle(100, 100, 200, 200);
for (int i = 0; i <= n + 2; i++)
{
for (int j = 0; j <= m + 2; j++)
{
if (i == 1 && j == 1)
{
setfillcolor(RED);
POINT start[] = { {1200, 530}, {1210, 530}, {1210, 540}, {1200, 540} };
fillpolygon(start, 4);
}
if (ma[i][j] == 0)
{
setfillcolor(LIGHTBLUE);
POINT pts[] = { {10 * i, 10 * j}, {10 * i, 10 + j * 10}, {10 + i * 10, 10 + j * 10}, {10 + i * 10, 10 * j} };
fillpolygon(pts, 4);
}
}
}
illustrate();
getimage(&img1, 1200, 530, 10, 10);
getimage(&img2, 1210, 540, 10, 10);
putimage(10, 10, &img1);
return;
}
2.随机生成迷宫, 采用Prime算法生成随机迷宫,保证了迷宫的随机性
void Reduce_wall()
{
srand((unsigned)time(NULL)); //随机数种子
Add_wall_to_wa();
while (!wa.empty())
{
int randnum = rand() % wa.size();
wall w = wa[randnum];
x_d = w.row;
y_d = w.colu;
switch (w.dir)
{
case 1:
y_d--;
break;
case 2:
x_d--;
break;
case 3:
y_d++;
break;
case 4:
x_d++;
break;
default:
break;
}
if (ma[x_d][y_d] == 0)
{
ma[w.row][w.colu] = ma[x_d][y_d] = 1;
Add_wall_to_wa();
}
wa.erase(wa.begin() + randnum);
}
}
3.玩家可以通过键盘上的方向键控制位置,直到走到终点
void op(IMAGE img1, IMAGE img2)
{
now_x = now_y = 1;
while (1)
{
int ch = _getch();
if (ch == 69)
return;
switch (ch)
{
cout << ch << endl;
case 72:
{
if (now_y - 1 >= 1 && ma[now_x][now_y - 1] == 1)
{
putimage(10 * now_x, 10 * now_y, &img2);
now_y--;
putimage(10 * now_x, 10 * now_y, &img1);
}
}
break;
case 75:
{
if (now_x - 1 >= 1 && ma[now_x - 1][now_y] == 1)
{
putimage(10 * now_x, 10 * now_y, &img2);
now_x--;
putimage(10 * now_x, 10 * now_y, &img1);
}
}
break;
case 77:
{
if (now_x + 1 <= n + 1 && ma[now_x + 1][now_y] == 1)
{
putimage(10 * now_x, 10 * now_y, &img2);
now_x++;
putimage(10 * now_x, 10 * now_y, &img1);
}
}
break;
case 80:
{
if (now_y + 1 <= m + 1 && ma[now_x][now_y + 1] == 1)
{
putimage(10 * now_x, 10 * now_y, &img2);
now_y++;
putimage(10 * now_x, 10 * now_y, &img1);
}
}
break;
case 68:
{
is_end = 0;
dfs(1, 1);
memset(vis, 0, sizeof(vis));
}; break;
case 66:
{
bfs(1, 1);
ve.push_back({ 1,1,-1 });
dfs_bfs(ed.x, ed.y);
for (int i = 0; i < ve.size(); i++) {
bfs_to[ve[i].x][ve[i].y] = 0;
}
for (int i = 1; i < n + 2; i++)
{
for (int j = 1; j < m + 2; j++) {
if (bfs_to[i][j])
{
Sleep(tim);
setfillcolor(BLACK);
POINT start2[] = { {10 * i, 10 * j}, {10 + 10 * i, 10 * j},
{10 + 10 * i, 10 + 10 * j}, {10 * i, 10 + 10 * j} };
fillpolygon(start2, 4);
}
}
}
memset(vis, 0, sizeof(vis));
}
break;
case 82:
{
Create_graph();
}; break;
default:
break;
}
if (now_x == ed.x && now_y == ed.y)
{
cout << "YOU WIN!" << endl;
return;
}
}
}
4.DFS寻找答案, 当玩家无法不知道从哪走的时候可以通过DFS寻找路径
void dfs(int x, int y)
{
if (x == ed.x && y == ed.y)
{
is_end = 1;
return;
};
for (int i = 0; i < 4; i++)
{
Sleep(tim);
if (in(x + xx[i], y + yy[i]) && vis[x + xx[i]][y + yy[i]] == 0 && ma[x + xx[i]][y + yy[i]])
{
vis[x + xx[i]][y + yy[i]] = 1;
setfillcolor(RED);
POINT start[] = { {10 * (x + xx[i]), 10 * (y + yy[i])}, {10 + 10 * (x + xx[i]), 10 * (y + yy[i])}, {10 + 10 * (x + xx[i]), 10 + 10 * (y + yy[i])}, {10 * (x + xx[i]), 10 + 10 * (y + yy[i])} };
fillpolygon(start, 4);
dfs(x + xx[i], y + yy[i]);
if (is_end)
return;
vis[x + xx[i]][y + yy[i]] = 0;
setfillcolor(BLACK);
POINT start2[] = { {10 * (x + xx[i]), 10 * (y + yy[i])}, {10 + 10 * (x + xx[i]), 10 * (y + yy[i])}, {10 + 10 * (x + xx[i]), 10 + 10 * (y + yy[i])}, {10 * (x + xx[i]), 10 + 10 * (y + yy[i])} };
fillpolygon(start2, 4);
}
}
}
5.BFS寻找答案, 当玩家无法不知道从哪走的时候也可以通过BFS寻找路径
void bfs(int x, int y)
{
vis[x][y] = 1;
node k;
k.x = x, k.y = y;
queue<node> q;
q.push(k);
while (!q.empty())
{
Sleep(tim);
node top = q.front();
setfillcolor(RED);
POINT start[] = { {10 * top.x, 10 * top.y},
{10 + 10 * top.x, 10 * top.y},
{10 + 10 * top.x, 10 + 10 * top.y},
{10 * top.x, 10 + 10 * top.y} };
fillpolygon(start, 4);
bfs_to[top.x][top.y] = 1; //标记走过的
if (top.x == ed.x && top.y == ed.y)
{
is_end = 1;
return;
}
q.pop();
for (int i = 0; i < 4; i++)
{
if (in(top.x + xx[i], top.y + yy[i]) && !vis[top.x + xx[i]][top.y + yy[i]] && ma[top.x + xx[i]][top.y + yy[i]])
{
node nxt = top;
nxt.x += xx[i];
nxt.y += yy[i];
dir[nxt.x][nxt.y].x = nxt.x;
dir[nxt.x][nxt.y].y = nxt.y;
dir[nxt.x][nxt.y].to = i;
vis[nxt.x][nxt.y] = 1;
q.push(nxt);
}
}
}
cout << "-1" << endl;
}
6.延时函数,直观的显示BFS和DFS的遍历过程
Sleep(tim);
7.清空答案,重新游玩
当知道下一步怎么走后,可以选择重新玩这个迷宫
详情在op函数中
2.遇到的问题
1. Prime算法生成迷宫
思路:
- 假设全部的格子都是墙,除了起点
- 将起点周围的墙加入容器,然后在容器中随机选一堵墙,如果墙另一边的格子与该格子没有相连,就打通这堵墙,将墙另一边的格子周围的墙加入到容器中,如果已经相连,则将该墙从容器中删除,再次随机找一堵墙。
2. 迷宫可视化操作,不知道如何将图数组转化成可视化迷宫
学习资料:EasyX文档
3. 键盘操作,如何通过键盘控制要移动的块
使用_getch()函数,同时通过每次输入的时候输出,找到要使用的键的对应的值,实现键盘控制要移动的方块