从前有座山,山上有座庙,庙里有个老和尚给小和尚讲故事:从前有座山,山上有座庙,庙里有个老和尚给小和尚讲故事 ~ ~ ~ 一张黄图的故事
故事起因:网课上的晕的厉害,无意间扫描桌面上壁纸,看到了它,
这是啥啊?Ps?软件元老了,下载上就没用过,哦不,是不会用,网课越听越晕,反正老师看不到,点开Ps,看看这玩意咋玩
点开以后,凭借着我多年的游戏经验,像穿越火线啊,飞车啊,梦三啊,都是曾经的元老级别菜鸟,在30分钟的精心乱点之下,我的一幅作品问世了,长这样
于是就在群里开始了炫耀
随后,队友一波喷。。。
感觉还行啊 呜呜呜~
太不开心了,打开4399来波拳皇,突然,看到一个迷宫类游戏,正好上课时间太难熬了,于是,我就点开打算来消遣一下
就这个,点开后连通5关,丝毫不在话下,玩着玩着,这迷宫的通路跟我的图片颜色差不多呀,于是,一个念头就产生了,我能不能也做一个这个游戏呢?
事实证明,我根本不会,这地图是咋生成的?一脸懵逼。。。
晚上没事干,就当做好学生的样子,百度了一下迷宫地图生成算法,还看到一个有价值的东西,
我看第一种最简单,就试着写了一下,我终于体会到了脑子和手的差别,就如同CPU和硬盘的差别一样,脑子感觉So easy,手感觉no Pa PA,不会写啊,本想放弃,但后来不知道一种什么神奇的力量推动着我,我还是再看一会吧,哦,后来才知道,那种力量是我实在不想看电工了,经过三个小时的奋斗,看出来了一点意思,也不晚了,就睡着了,第二天醒来,上课听老师那熟悉的魔幻的催眠曲晕的厉害,害,不听了,搞我的迷宫吧,就这样,经过两天的奋斗,我看懂了,慢慢的,也写出来了,
当然,行数和列数都是可以变化的,脸上有了一丝欣慰,这么复杂,我玩不了,搞了一个简单的,就通关了
感觉还行吧,后面会实现一个DFS和BFS的自动探路算法,后序有时间再写吧,我把源码奉上,有兴趣的小伙伴可以一起交流哦!
#include "acllib.h"
#include
#include
#include
#define LENGTH 40 //图片规格
#define MAP_WIDTH_NUM 10//地图宽
#define MAP_HEIGHT_NUM 10//地图高
#define STACK_MAX_NUM (MAP_WIDTH_NUM*MAP_HEIGHT_NUM)/4
int row = MAP_HEIGHT_NUM%2==0 ? MAP_HEIGHT_NUM+1 : MAP_HEIGHT_NUM;
int column = MAP_WIDTH_NUM%2==0 ? MAP_WIDTH_NUM+1 : MAP_WIDTH_NUM;
int WindowWidth = column*LENGTH;//窗口宽
int WindowHeight = row*LENGTH;//窗口高
const char * WindowTitle = "一枚の黄色図の物語";//窗口标题
ACL_Image road;//图片->路
ACL_Image wall;//图片->墙
ACL_Image people;//图片->人
ACL_Image destination;//目的地
ACL_Image success;//到达终点
struct Point{//坐标
int x;
int y;
};
Point StartPoint;//始点
Point EndPoint;//终点
Point CurrentPoint;//当前坐标点
typedef struct //栈
{
int top;//栈顶指针
Point data[STACK_MAX_NUM];//栈元素
}Stack;
int directed[4][2]={{-2,0},{0,2},{2,0},{0,-2}};//方向数组
int fill[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//填充方向
void keyEvent(int key,int e); //键盘事件
int ** map;//地图
//入栈
void Push(Stack *s,Point elem)
{
if(s->top<STACK_MAX_NUM-1){
s->data[++(s->top)]=elem;
}else{
puts("栈溢出");
}
}
//出栈
Point Pop(Stack *s)
{
if(s->top>-1){
return s->data[(s->top)--];
}else{
Point error;
error.x=-1;
error.y=-1;
return error;
}
}
int getAroundEffectiveNum(Point point,int ** visited)
{
int num=0;
point.x = point.x+1;
point.y=point.y+1;
for(int i=0;i<4;i++){
if(visited[point.x+directed[i][0]][point.y+directed[i][1]]==1){
num++;
}
}
return num;
}
void InitMap()//地图初始化 0表示墙 1表示路
{
map = (int**)malloc(row * sizeof(int *));//分配地图空间 0表示墙 1表示陆地 2表示人 3表示目的地
int ** visited = (int**)malloc((row+2) * sizeof(int *));//访问标记 0表示访问过 1表示未被访问
int i,j;
//地图初始化
for(i=0;i<row;i++){
map[i]=(int *)malloc(column * sizeof(int));
}
for(i=0;i<row+2;i++){
visited[i]=(int *)malloc((column+2) * sizeof(int));
}
for(i=0;i<column;i++){
map[0][i]=map[row-1][i]=0;
}
for(i=0;i<column+2;i++){
visited[0][i]=visited[1][i]=visited[row][i]=visited[row+1][i]=0;
}
for(i=0;i<row;i++){
map[i][0]=map[i][column-1]=0;
}
for(i=0;i<row+2;i++){
visited[i][0]=visited[i][1]=visited[i][column]=visited[i][column+1]=0;
}
for(i=1;i<row-1;i++){
for(j=1;j<column-1;j++){
if(i%2==1 && j%2==1){
map[i][j]=1;
visited[i+1][j+1]=1;
}else{
map[i][j]=0;
visited[i+1][j+1]=0;
}
}
}
//生成地图
srand((unsigned)time(NULL));
int StartPoint_flag = rand()%4+1;
if(StartPoint_flag==1){//上
StartPoint.x = 1;
do{
StartPoint.y = rand()%(column-2)+1;
}while(map[StartPoint.x][StartPoint.y]==0);
}else if(StartPoint_flag==2){//右
StartPoint.y = column-2;
do{
StartPoint.x = rand()%(row-2)+1;
}while(map[StartPoint.x][StartPoint.y]==0);
}else if(StartPoint_flag==3){//下
StartPoint.x = row-2;
do{
StartPoint.y = rand()%(column-2)+1;
}while(map[StartPoint.x][StartPoint.y]==0);
}else if(StartPoint_flag==4){//左
StartPoint.y = 1;
do{
StartPoint.x = rand()%(row-2)+1;
}while(map[StartPoint.x][StartPoint.y]==0);
}
map[StartPoint.x][StartPoint.y]=2;
//地图随机生成
CurrentPoint.x=StartPoint.x;
CurrentPoint.y=StartPoint.y;
Stack S;
S.top=-1;
int directed_flag;
int EndPoint_flag=0;
while(S.top!=-1 || getAroundEffectiveNum(CurrentPoint,visited)>0)
{
while(getAroundEffectiveNum(CurrentPoint,visited)>0){
directed_flag = rand()%4;//产生四个方向的随机数
if(visited[CurrentPoint.x+1+directed[directed_flag][0]][CurrentPoint.y+1+directed[directed_flag][1]]==0){
do{
directed_flag++;
directed_flag=directed_flag%4;
}while(visited[CurrentPoint.x+1+directed[directed_flag][0]][CurrentPoint.y+1+directed[directed_flag][1]]==0);
}
visited[CurrentPoint.x+1][CurrentPoint.y+1]=0;
map[CurrentPoint.x+fill[directed_flag][0]][CurrentPoint.y+fill[directed_flag][1]]=1;
Push(&S,CurrentPoint);
CurrentPoint.x=CurrentPoint.x+directed[directed_flag][0];
CurrentPoint.y=CurrentPoint.y+directed[directed_flag][1];
visited[CurrentPoint.x+1][CurrentPoint.y+1]=0;
//map[CurrentPoint.x+fill[directed_flag][0]][CurrentPoint.y+fill[directed_flag][1]]=1;
if(S.top>EndPoint_flag){
EndPoint_flag=S.top;
EndPoint = CurrentPoint;
}
}
if(S.top!=-1){
CurrentPoint=Pop(&S);
}
}
map[EndPoint.x][EndPoint.y]=3;
}
void PrintMap()
{
beginPaint();
int i,j;
if( map[EndPoint.x][EndPoint.y]==5){
putImageScale(&success,0,0,WindowWidth,WindowHeight);
}else{
for(i=0;i<row;i++){
for (j=0;j<column;j++){
if(map[i][j]==0){//墙
putImageScale(&wall,i*LENGTH,j*LENGTH,LENGTH,LENGTH);
}else if(map[i][j]==1){//路
putImageScale(&road,i*LENGTH,j*LENGTH,LENGTH,LENGTH);
}
else if(map[i][j]==2){//人
putImageScale(&people,i*LENGTH,j*LENGTH,LENGTH,LENGTH);
}else if(map[i][j]==3){//目的地
putImageScale(&destination,i*LENGTH,j*LENGTH,LENGTH,LENGTH);
}
}
}
}
endPaint();
}
int Setup()
{
initWindow(WindowTitle,DEFAULT,DEFAULT,WindowWidth,WindowHeight);
loadImage("road.gif",&road);//加载图片road.gif
loadImage("wall.gif",&wall);//加载图片wall.gif
loadImage("people.gif",&people);//加载图片people.gif
loadImage("destination.gif",&destination);//加载图片people.gif
loadImage("success.gif",&success);//加载成功
InitMap();
registerKeyboardEvent(keyEvent);
PrintMap();
return 0;
}
void keyEvent(int key,int e){
if(e!=KEY_DOWN) return;
switch (key)
{
case VK_UP:{//上
if(map[StartPoint.x][StartPoint.y-1]==1){
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.y-=1;
map[StartPoint.x][StartPoint.y]+=1;
}else if(map[StartPoint.x][StartPoint.y-1]==3){
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.y-=1;
map[StartPoint.x][StartPoint.y]+=2;
}
break;
}
case VK_DOWN:{
if(map[StartPoint.x][StartPoint.y+1]==1){
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.y+=1;
map[StartPoint.x][StartPoint.y]+=1;
}else if(map[StartPoint.x][StartPoint.y+1]==3){
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.y+=1;
map[StartPoint.x][StartPoint.y]+=2;
}
break;
}
case VK_LEFT:{
if(map[StartPoint.x-1][StartPoint.y]==1){
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.x-=1;
map[StartPoint.x][StartPoint.y]+=1;
}else if(map[StartPoint.x-1][StartPoint.y]==3)
{
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.x-=1;
map[StartPoint.x][StartPoint.y]+=2;
}
break;
}
case VK_RIGHT:{
if(map[StartPoint.x+1][StartPoint.y]==1){
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.x+=1;
map[StartPoint.x][StartPoint.y]+=1;
}else if(map[StartPoint.x+1][StartPoint.y]==3)
{
map[StartPoint.x][StartPoint.y]-=1;
StartPoint.x+=1;
map[StartPoint.x][StartPoint.y]+=2;
}
break;
}
}
PrintMap();
}
//BFS
//DFS