实现方法:
c++游戏小技巧6:rand()+随机迷宫(3写法:BFS,DFS,并查集)_L('ω')┘脏脏包└('ω')」的博客-CSDN博客
总而言之,把三种代码生成编到了一起,加上拿手的主页面及优化
1.0版本就做好了
(注意,关于普通模式,请自备心梗的药)
1.0版本支持:
简单模式:DFS生成,岔路小,看得见全图,地图也比较小
普通模式:BFS生成,岔路多,看得见部分图,地图中等
双人模式:就双人
直接给代码吧······
#include<conio.h>
#include<windows.h>
#include<bits/stdc++.h>
using namespace std;
#define kd(VK_NONAME) ((GetAsyncKeyState(VK_NONAME)&0x8000)?1:0)
//地图基操
int m,n;//大小
char player='1',wall='%',End='O',play2='2';//内饰
bool shuang=false;
int x,y,xx,yy;//起点
#define kong ' ' //路
#define down 1 //向下
#define right 2 //向右
#define left 4 //向左
#define up 8 //向下
#define WALL -1 //墙
#define KONG 2 //路
#define Player 11//van家
#define Play2 114//van家2
#define END 191810//
#define Hash(a,b) (a-1)*n+b//二维bcj基本操作
//结构体
struct qiang{int x,y,f;qiang(int xx,int yy,int ff){x=xx,y=yy,f=ff;}};//墙
struct play_er{int x,y;}start,start2,end;//角色
struct obstacle{int fx,fy,sx,sy;}zmx;
//变量
vector<qiang> where;//bfs记录
vector<obstacle> b;//并查集记录
int x_p,y_p;//起点
int dt[1010][1010];//地图
int fx[5][5]={{2,0},{-2,0},{0,2},{0,-2}};//间隔一面墙的方向
int zj[5][5]={{1,0},{-1,0},{0,1},{0,-1}};//不间隔的方向
bool v[1010][1010]={0};//dfs记录是否走过
bool sy[1010][1010]={0};//视野
int fa[244140725],mp[125][125][125][125];//并查集的集合
int dx[2]={0,1},dy[2]={1,0};//并差集的方向
//系统函数
void gotoxy(int,int);
void color(int);
void hidecur();
void print(string,int,int,int);
void noedit();
//bfs函数
void put_wall();//bfs入vector
void b_init();//bfs初始化
void bfs();//生成
void v_init();//调整视野
void bfs_print();//打印
//dfs函数
void d_init();//dfs初始化
void dfs(int,int);//深搜生成
void dfs_print();//输出
//bcj函数
int find(int);//并查集 查找+路径压缩
void merge(obstacle);//合并
bool judge(obstacle);//判断是否在一起
void bcj_init();//初始化
void vec_to_int();//把vector与mp里面的值转移到 dt里面,方便后期操作
void bcj_inint();//生成
void bcj_print();//输出
//游戏主函数
void easy();
void mmid();
//系统函数
void gotoxy(int x,int y)//覆盖清屏 ,从指定行列覆盖
{
COORD pos={x,y};
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut,pos);
return;
}
void color(int a)
{
/*亮白*/ if(a==0) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
/*蓝色*/ if(a==1) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
/*绿色*/ if(a==2) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
/*紫色*/ if(a==3) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);
/*红色*/ if(a==4) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
/*黄色*/ if(a==5) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);
/*深蓝色*/ if(a==6) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_BLUE);
/*土黄色or金黄色*/ if(a==7) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN);
/*灰色接近白*/ if(a==8) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
}
void print(string s,int c1,int sl)
{
color(c1);
for(int i=0;i<s.size();i++) cout<<s[i],Sleep(sl);
color(0);
}
void hidecur()//隐藏光标
{
CONSOLE_CURSOR_INFO cur={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cur);
}
void noedit()
{
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式
mode &= ~ENABLE_INSERT_MODE; //移除插入模式
mode &= ~ENABLE_MOUSE_INPUT;
SetConsoleMode(hStdin, mode);
}
//BFS
void put_wall()//bfs入vector
{
if(x_p+1<=m&&dt[x_p+1][y_p]==WALL) where.push_back(qiang(x_p+1,y_p,down));//下墙
if(y_p+1<=n&&dt[x_p][y_p+1]==WALL) where.push_back(qiang(x_p,y_p+1,right));//右墙
if(x_p-1>=1&&dt[x_p-1][y_p]==WALL) where.push_back(qiang(x_p-1,y_p,up));//上墙
if(y_p-1>=1&&dt[x_p][y_p-1]==WALL) where.push_back(qiang(x_p,y_p-1,left));//左墙
}
void b_init()//bfs初始化
{
srand(time(NULL));//随机数种子
x_p=x,y_p=y;//记录起点
start.x=x,start.y=y;//记录起点
start2.x=xx,start2.y=yy;
memset(dt,WALL,sizeof(dt));//地图初始化
dt[x][y]=KONG;//起点为空
put_wall();//起点初始化
//bfs生成的基本思想就是从一个空开始,四周入队
//再随机选择队中的一个,重复上一次操作
}
void bfs()
{
while(where.size())
{
int r=rand()%(where.size());//随机选择
qiang what=where[r];//取出
x_p=what.x;//维护
y_p=what.y;//维护
switch(what.f)//走一步
{
case down:{x_p++;break;}//下
case right:{y_p++;break;}//右
case left:{y_p--;break;}//左
case up:{x_p--;break;}//上
}
if(dt[x_p][y_p]==WALL) dt[what.x][what.y]=dt[x_p][y_p]=KONG,put_wall();//入队
where.erase(where.begin()+r);//删掉
}
}
void v_init()
{
for(int i=0;i<=m+1;i++)
for(int j=0;j<=n+1;j++)
if(sy[i][j]==1) gotoxy(i,j),printf(" ");
gotoxy(0,0);
memset(sy,0,sizeof sy);
for(int i=x-3;i<=x+3;i++)
{
for(int j=y-3;j<=y+3;j++)
{
if(i<0||j<0||i>m+1||j>n+1) continue;
sy[i][j]=1;
}
}
if(!shuang) return ;
for(int i=xx-3;i<=xx+3;i++)
{
for(int j=yy-3;j<=yy+3;j++)
{
if(i<0||j<0||i>m+1||j>n+1) continue;
sy[i][j]=1;
}
}
}
void bfs_print()//打印
{
dt[x][y]=Player;
if(shuang)dt[xx][yy]=Play2;
dt[m][n]=END;
//bfs会有原点,是从原点 洪水式填充,所以建议 中等难度
v_init();
// for(int i=0;i<=m+1;i++)
// {
// for(int j=0;j<=n+1;j++) printf(" ");
// printf("\n");
// }
for(int i=0;i<=m+1;i++)
{
for(int j=0;j<=n+1;j++)
{
if(dt[i][j]==Player) printf("%c",player);
else if(dt[i][j]==KONG&&sy[i][j]) printf("%c",kong);
else if(dt[i][j]==KONG&&!sy[i][j]) printf(" ");
else if(dt[i][j]==Play2&&shuang) printf("%c",play2);
else if(dt[i][j]==WALL&&sy[i][j]) printf("%c",wall);
else if(dt[i][j]==WALL&&!sy[i][j]) printf(" ");
else if(dt[i][j]==END&&!sy[i][j]) printf(" ");
else if(dt[i][j]==END&&sy[i][j]) printf("%c",End);
}
printf("\n");
}
}
//DFS
void d_init()//dfs初始化
{
memset(v,false,sizeof v);
srand(time(NULL));//老规矩
start.x=xx,start.y=yy;
start.x=x,start.y=y;//初始化
memset(dt,WALL,sizeof dt);//同上
for(int i=1;i<=n;i++)//可以去看一看我配的图片,就能懂了
{
for(int j=1;j<=m;j++)
{
if(i==1||i==n||j==1||j==m) dt[i][j]=WALL;
if(i%2==0&&j%2==0) dt[i][j]=KONG;
else dt[i][j]=WALL;
}
}
dt[x][y]=KONG;//起点开始
}
void dfs(int x,int y)
{
bool f[5]={0};//当时,本蒟蒻把这一排放进了while内部,然后因为无法跳出循环调了一个小时······
while(1)
{
if(f[0]&&f[1]&&f[2]&&f[3]) return ;//四个方向搜索完了
int r=rand()%4;
int nx=fx[r][0],ny=fx[r][1],zx=zj[r][0],zy=zj[r][1];
if(x+nx<1||x+nx>n||y+ny<1||y+ny>m) {f[r]=1;continue;}//当时,我把continue写成了return 0···
if(dt[x+zx][y+zy]!=WALL||v[x+zx][y+zy]||v[x+nx][y+ny]) {f[r]=1;continue;}
f[r]=1;//这个方向走了
dt[x+zx][y+zy]=KONG;//打通
v[x+zx][y+zy]=v[x+nx][y+ny]=1;//标记,注意,不更新x+nx,y+ny会有回路
dfs(x+nx,y+ny);//继续深搜
}
return ;
}
void dfs_print()//输出
{
dt[n-1][m-1]=END;
dt[x][y]=Player;
dt[xx][yy]=Play2;
//因为dfs是一条路走到底,所以主路会很明显,副路的主路也很明显,建议作为简单难度食用
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
if(dt[i][j]==Player) printf("%c",player);
else if(dt[i][j]==Play2) printf("%c",play2);
else if(dt[i][j]==KONG) printf("%c",kong);
else if(dt[i][j]==WALL) printf("%c",wall);
else printf("%c",End);
}
printf("\n");
}
}
//BCJ
int find(int f){return fa[f]==f?f:fa[f]=find(fa[f]);}//并查集 查找+路径压缩
void merge(obstacle zmx){fa[find(Hash(zmx.fx,zmx.fy))]=find(Hash(zmx.sx,zmx.sy));}//合并
bool judge(obstacle zmx){return find(Hash(zmx.fx,zmx.fy))==find(Hash(zmx.sx,zmx.sy));}//判断是否在一起
void bcj_init()//初始化
{
srand((unsigned int)time(NULL));//随机数种子
for(int i=1;i<=n*n;i++) fa[i]=i;//自定义
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i+1<=n) b.push_back((obstacle){i,j,i+1,j});//连接
if(j+1<=n) b.push_back((obstacle){i,j,i,j+1});//连接
}
}
void vec_to_int()//把vector与mp里面的值转移到 dt里面,方便后期操作
{
int idx=1,jdx=0;
for(int i=1;i<=2*n+1;i++) dt[1][i]=WALL;
for(int i=1;i<=n;i++)
{
dt[i+idx][1]=WALL;
jdx=1;
for(int j=1;j<=n+1;j++) dt[i+idx][j+jdx]=KONG,((j!=n)&&(mp[i][j][i][j+1]==KONG))?dt[i+idx][j+(++jdx)]=KONG:dt[i+idx][j+(++jdx)]=WALL;
//连接
idx++,jdx=1;
for(int j=1;j<=n+1;j++) dt[i+idx][j+jdx]=WALL,((i!=n)&&(mp[i][j][i+1][j]==KONG))?dt[i+idx][j+(++jdx)]=KONG:dt[i+idx][j+(++jdx)]=WALL;
//连接
//当时少打+1,调错一上午
dt[2*n+1][2*n+1]=WALL;
}
dt[x][y]=Player;
}
void bcj_inint()//生成
{
while(!b.empty())
{
int r=rand()%b.size();
if(!judge(b[r])) merge(b[r]),mp[b[r].fx][b[r].fy][b[r].sx][b[r].sy]=KONG;//合并
b.erase(b.begin()+r);//出去!
}
}
void bcj_print()
{
for(int i=1;i<=2*n+1;i++)
{
for(int j=1;j<=2*n+2;j++)
{
if(dt[i][j]==WALL) cout<<wall;
if(dt[i][j]==KONG) cout<<kong;
if(dt[i][j]==Player) cout<<player;
}
cout<<endl;
}
}
void mmid()
{
int who=0;
system("mode con cols=62 lines=32");
system("cls");
n=59,m=29;
x=y=1;
if(shuang) xx=yy=1;
b_init();
bfs();
bfs_print();
while(1)
{
gotoxy(0,0);
bfs_print();
if(dt[x-1][y]==END||dt[x+1][y]==END||dt[x][y+1]==END||dt[x][y-1]==END) {who=1;break;}
if(dt[xx-1][yy]==END||dt[xx+1][yy]==END||dt[xx][yy+1]==END||dt[xx][yy-1]==END) {who=2;break;}
if(kd('W')&&dt[x-1][y]!=WALL) dt[x][y]=KONG,dt[x-1][y]=Player,x--;
if(kd('A')&&dt[x][y-1]!=WALL) dt[x][y]=KONG,dt[x][y-1]=Player,y--;
if(kd('S')&&dt[x+1][y]!=WALL) dt[x][y]=KONG,dt[x+1][y]=Player,x++;
if(kd('D')&&dt[x][y+1]!=WALL) dt[x][y]=KONG,dt[x][y+1]=Player,y++;
Sleep(13);
if(!shuang) continue;
if(kd(VK_UP)&&dt[xx-1][yy]!=WALL) dt[xx][yy]=KONG,dt[xx-1][yy]=Play2,xx--;
if(kd(VK_LEFT)&&dt[xx][yy-1]!=WALL) dt[xx][yy]=KONG,dt[xx][yy-1]=Play2,yy--;
if(kd(VK_DOWN)&&dt[xx+1][yy]!=WALL) dt[xx][yy]=KONG,dt[xx+1][yy]=Play2,xx++;
if(kd(VK_RIGHT)&&dt[xx][yy+1]!=WALL) dt[xx][yy]=KONG,dt[xx][yy+1]=Play2,yy++;
}
system("cls");
if(!shuang) print("oh,you win!",4,75);
else if(who==1) print("oh,player 1 was win!",4,75);
else print("oh,player 2 was win!",4,75);
system("title 按任意键继续");
Sleep(1000);
system("pause");
system("cls");
}
void easy()
{
int who=0;
system("cls");
n=21,m=2*n+5;
x=y=2;
if(shuang)xx=yy=2;
d_init();
dfs(x,y);
dfs_print();
while(1)
{
gotoxy(0,0);
dfs_print();
if(dt[x-1][y]==END||dt[x+1][y]==END||dt[x][y+1]==END||dt[x][y-1]==END) {who=1;break;}
if(dt[xx-1][yy]==END||dt[xx+1][yy]==END||dt[xx][yy+1]==END||dt[xx][yy-1]==END) {who=2;break;}
if(kd('W')&&dt[x-1][y]!=WALL) dt[x][y]=KONG,dt[x-1][y]=Player,x--;
if(kd('A')&&dt[x][y-1]!=WALL) dt[x][y]=KONG,dt[x][y-1]=Player,y--;
if(kd('S')&&dt[x+1][y]!=WALL) dt[x][y]=KONG,dt[x+1][y]=Player,x++;
if(kd('D')&&dt[x][y+1]!=WALL) dt[x][y]=KONG,dt[x][y+1]=Player,y++;
Sleep(23);
if(!shuang) continue;
if(kd(VK_UP)&&dt[xx-1][yy]!=WALL) dt[xx][yy]=KONG,dt[xx-1][yy]=Play2,xx--;
if(kd(VK_LEFT)&&dt[xx][yy-1]!=WALL) dt[xx][yy]=KONG,dt[xx][yy-1]=Play2,yy--;
if(kd(VK_DOWN)&&dt[xx+1][yy]!=WALL) dt[xx][yy]=KONG,dt[xx+1][yy]=Play2,xx++;
if(kd(VK_RIGHT)&&dt[xx][yy+1]!=WALL) dt[xx][yy]=KONG,dt[xx][yy+1]=Play2,yy++;
}
system("cls");
if(!shuang) print("oh,you win!",4,75);
else if(who==1) print("oh,player 1 was win!",4,75);
else print("oh,player 2 was win!",4,75);
system("title 按任意键继续");
Sleep(1000);
system("pause");
system("cls");
return ;
}
void prinft()
{
system("title choose");//改标题
system("mode con cols=50 lines=22");//改窗口大小
gotoxy(21,3);
print("随机迷宫",5,30);
gotoxy(21,8);
print("1.简单",5,30);
gotoxy(21,9);
print("2.普通",5,30);
gotoxy(21,10);
print("3.坤难",5,30);
shuang=0;
gotoxy(21,11);
print("4.双人",5,30);
gotoxy(21,12);
print("5.设置",5,30);
gotoxy(21,13);
print("6.介绍",5,30);
while(1)
{
system("title choose");
system("mode con cols=50 lines=22");
gotoxy(21,3);
print("随机迷宫",5,0);
gotoxy(21,8);
print("1.简单",5,0);
gotoxy(21,9);
print("2.普通",5,0);
gotoxy(21,10);
print("3.坤难(未完成)",5,0);
gotoxy(21,11);
if(!shuang) print("4.双人",5,0);
else print("4.单人",5,0);
gotoxy(21,12);
print("5.设置(未完成)",5,0);
gotoxy(21,13);
print("6.介绍(未完成)",5,0);
if(kd(VK_NUMPAD1)||(kd('1'))) easy();
if(kd(VK_NUMPAD2)||(kd('2'))) mmid();
// if(kd(VK_NUMPAD3)||(kd('3'))){what=3;break;}
if(kd(VK_NUMPAD4)||(kd('4'))) shuang=!shuang;
Sleep(75);
}
}
int main()
{
hidecur();
noedit();
prinft();
return 0;
}
/*
//bfs生成方法
b_init();//bfs初始化
bfs();//生成
bfs_print();//打印
//dfs生成方法:
d_init();//dfs初始化
dfs(x,y);//深搜生成
dfs_print();//输出
//bcj生成方法:
bcj_init();//初始化
bcj_inint();//生成
vec_to_int();//换类型
bcj_print();//输出
*/
(看到这里,对【c++小游戏】谁与争锋1.0.2.2_L('ω')┘脏脏包└('ω')」的博客-CSDN博客的更新就不用多说了吧!)文章来源:https://www.toymoban.com/news/detail-599672.html
下期见!文章来源地址https://www.toymoban.com/news/detail-599672.html
到了这里,关于c++小游戏:随机迷宫的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!