C++自動(dòng)生成迷宮游戲
本文實(shí)例為大家分享了C++實(shí)現(xiàn)迷宮游戲的具體代碼,供大家參考,具體內(nèi)容如下
運(yùn)用并查集自動(dòng)生成迷宮地圖,并運(yùn)用隊(duì)列和棧尋找迷宮通路并打印出來(lái)
#include<stdlib.h>
#include<iostream>
#include<time.h>
#include<queue>
#include<stack>
using namespace std;
using std::queue;
using std::stack;
typedef struct Point
{
int x;
int y;
int d;//方向 若方向?yàn)?1,則表示起點(diǎn)
}Point;
queue<Point> mqueue;
stack<Point> mstack;
Point pos, pos1;
int m, n;//迷宮行(tm-1)/2和列(tn-1)/2
int tm, tn;//實(shí)際作圖
int x, y, tx1, tx2, ty1, ty2;//點(diǎn)坐標(biāo)
int d;
int s[10000000];
int maze[1000][1000], mark[1000][1000];//最大迷宮
int sign[4][2] = { { -1,0 },{ 1,0 },{ 0,-1 },{ 0,1 } };//上下左右四個(gè)方向 0上 1下 2上 3下
Point start;
int Find_x(int x);
void unionSets(int node1, int node2);
void Init();
int getAdd(int x, int y);
void foundpath();
void fixmaze();
int connected(int node1, int node2);
void Findpath();
void changemaze();
int main()
{
Init();
cout << "請(qǐng)輸入迷宮規(guī)模2x-1,2y-1:(x y)" << endl;
cin >> m >> n;
tm = m * 2 + 1;
tn = n * 2 + 1;
start.x = 1;
start.y = 1;
start.d = -1;
mqueue.push(start);
for (int i = 0; i < tm; i++)
{
for (int j = 0; j < tn; j++)
{
maze[i][j] = 1;
mark[i][j] = 0;
}
}
for (int i = 1; i < tm - 1; i += 2)
{
for (int j = 1; j < tn - 1; j += 2)
maze[i][j] = 0;
}
srand(time(NULL));
foundpath();
fixmaze();
cout << "迷宮全圖:" << endl;
for (int i = 0; i < tm; i++)
{
for (int j = 0; j < tn; j++)
{
if (maze[i][j] == 1)
cout << "▇";
else if (maze[i][j] == 0) cout << "□";
}
cout << endl;
}
Findpath();
changemaze();
cout << "找到的通路:“..”表示:" << endl;
for (int i = 0; i < tm; i++)
{
for (int j = 0; j < tn; j++)
{
if (maze[i][j] == 1)
cout << "▇";
else if (maze[i][j] == 0) cout << "□";
else if (maze[i][j] == -1) cout << "..";
}
cout << endl;
}
system("pause");
return 0;
}
int connected(int node1, int node2)
{
return Find_x(node1) == Find_x(node2);
}
int Find_x(int x)
{
if (s[x] < 0)
return x;
else
return Find_x(s[x]);
};
void unionSets(int node1, int node2)
{
int root1 = Find_x(node1);
int root2 = Find_x(node2);
if (root1 == root2)
return;
if (s[root2] < s[root1])
s[root1] = root2;
else {
if (s[root1] == s[root2])
s[root1]--;
s[root2] = root1;
}
};
int getAdd(int x, int y)
{
return (x*tn + y);
};
void Init()
{
for (int i = 0; i < 10000000; ++i)
s[i] = -1;
};
void foundpath()
{
while (connected(getAdd(1, 1), getAdd(tm - 2, tn - 2)) != 1)
{
do
{
x = rand() % (tm - 2) + 1;
y = rand() % (tn - 2) + 1;
} while (maze[x][y] == 0);
d = x % 2;
if (d == 0)
{
tx1 = x + 1;
ty1 = y;
tx2 = x - 1;
ty2 = y;
if (connected(getAdd(tx1, ty1), getAdd(tx2, ty2)) != 1)
{
maze[x][y] = 0;
unionSets(Find_x(getAdd(tx1, ty1)), Find_x(getAdd(tx2, ty2)));
}
}
else if (d == 1)
{
tx1 = x;
ty1 = y + 1;
tx2 = x;
ty2 = y - 1;
if (connected(getAdd(tx1, ty1), getAdd(tx2, ty2)) != 1)
{
maze[x][y] = 0;
unionSets(Find_x(getAdd(tx1, ty1)), Find_x(getAdd(tx2, ty2)));
}
}
}
}
void fixmaze()
{
for (int i = 1; i < tm - 1; i++)
{
for (int j = 1; j < tn - 1; j++)
{
if (maze[i - 1][j] == 1 && maze[i + 1][j] == 1 && maze[i][j + 1] == 1 && maze[i][j - 1] == 1)
{
maze[i][j] = 1;
}
}
}
for (int i = 1; i < tm - 1; i++)
{
for (int j = 1; j < tn - 1; j++)
{
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 1 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 1 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 1 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 1 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 1 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 1 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 1 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 1 && maze[i + 1][j + 1] == 0)
{
maze[i][j] = 1;
}
if (maze[i - 1][j - 1] == 0 && maze[i - 1][j] == 0 && maze[i - 1][j + 1] == 0 && maze[i][j - 1] == 0 && maze[i][j] == 0 && maze[i][j + 1] == 0 && maze[i + 1][j - 1] == 0 && maze[i + 1][j] == 0 && maze[i + 1][j + 1] == 1)
{
maze[i][j] = 1;
}
}
}//局部?jī)?yōu)化,防止出現(xiàn)大面積通路
}
void Findpath()
{
int flag = 0;
int i, j;
while (!mqueue.empty())
{
i = mqueue.front().x;
j = mqueue.front().y;
mark[i][j] = 1;
for (int k = 0; k < 4; k++)
{
if (mark[i + sign[k][0]][j + sign[k][1]] == 0 && maze[i + sign[k][0]][j + sign[k][1]] == 0)
{
pos.x = i + sign[k][0];
pos.y = j + sign[k][1];
pos.d = k;
mark[pos.x][pos.y] = 1;
mqueue.push(pos);
if (mqueue.back().x == tm - 2 && mqueue.back().y == tn - 2)
{
mstack.push(mqueue.front());
mstack.push(mqueue.back());
flag = 1;
break;
}
}
}
if (flag) break;
mstack.push(mqueue.front());
if (!mqueue.empty())
mqueue.pop();
}
}
void changemaze()
{
int i, j, k;
i = mstack.top().x;
j = mstack.top().y;
k = mstack.top().d;
maze[i][j] = -1;
while (mstack.size()>0)
{
if (mstack.top().x == i - sign[k][0] && mstack.top().y == j - sign[k][1])
{
i = i - sign[k][0];
j = j - sign[k][1];
k = mstack.top().d;
maze[i][j] = -1;
if (!mstack.empty())
mstack.pop();
}
else if (!mstack.empty())
mstack.pop();
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
使用C語(yǔ)言遞歸與非遞歸實(shí)現(xiàn)字符串反轉(zhuǎn)函數(shù)char *reverse(char *str)的方法
本篇文章是對(duì)使用C語(yǔ)言遞歸與非遞歸實(shí)現(xiàn)字符串反轉(zhuǎn)函數(shù)char *reverse(char *str)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
OpenCV實(shí)現(xiàn)圖像的直線檢測(cè)
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像直線檢測(cè)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
C++標(biāo)準(zhǔn)模板庫(kù)函數(shù)sort的那些事兒
sort函數(shù)是標(biāo)準(zhǔn)模板庫(kù)的函數(shù),已知開(kāi)始和結(jié)束的地址即可進(jìn)行排序,可以用于比較任何容器(必須滿足隨機(jī)迭代器),任何元素,任何條件,執(zhí)行速度一般比qsort要快2013-09-09
C語(yǔ)言實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
編譯錯(cuò)誤error: stray ‘\343’in program的解決方法
以下是對(duì)編譯錯(cuò)誤error: stray ‘\343’in program的解決方法進(jìn)行了詳細(xì)的分析介紹,如遇此問(wèn)題的朋友們可以過(guò)來(lái)參考下2013-07-07
OpenCV基于稠密光流實(shí)現(xiàn)視頻跟蹤詳解
這篇文章主要為大家詳細(xì)介紹了OpenCV如何基于稠密光流實(shí)現(xiàn)視頻跟蹤功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2023-02-02
C語(yǔ)言小項(xiàng)目實(shí)戰(zhàn)之通訊錄功能
這篇文章主要介紹了如何設(shè)計(jì)和實(shí)現(xiàn)一個(gè)簡(jiǎn)單的通訊錄管理系統(tǒng),包括聯(lián)系人信息的存儲(chǔ)、增加、刪除、查找、修改和排序等功能,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01

