從前有座山,山上有座廟,廟裏有個老和尚給小和尚講故事:從前有座山,山上有座廟,廟裏有個老和尚給小和尚講故事 ~ ~ ~ 一張黃圖的故事
故事起因:網課上的暈的厲害,無意間掃描桌面上壁紙,看到了它,
這是啥啊?Ps?軟件元老了,下載上就沒用過,哦不,是不會用,網課越聽越暈,反正老師看不到,點開Ps,看看這玩意咋玩
點開以後,憑藉着我多年的遊戲經驗,像穿越火線啊,飛車啊,夢三啊,都是曾經的元老級別菜鳥,在30分鐘的精心亂點之下,我的一幅作品問世了,長這樣
於是就在羣裏開始了炫耀
隨後,隊友一波噴。。。
感覺還行啊 嗚嗚嗚~
太不開心了,打開4399來波拳皇,突然,看到一個迷宮類遊戲,正好上課時間太難熬了,於是,我就點開打算來消遣一下
就這個,點開後連通5關,絲毫不在話下,玩着玩着,這迷宮的通路跟我的圖片顏色差不多呀,於是,一個念頭就產生了,我能不能也做一個這個遊戲呢?
事實證明,我根本不會,這地圖是咋生成的?一臉懵逼。。。
晚上沒事幹,就當做好學生的樣子,百度了一下迷宮地圖生成算法,還看到一個有價值的東西,
我看第一種最簡單,就試着寫了一下,我終於體會到了腦子和手的差別,就如同CPU和硬盤的差別一樣,腦子感覺So easy,手感覺no Pa PA,不會寫啊,本想放棄,但後來不知道一種什麼神奇的力量推動着我,我還是再看一會吧,哦,後來才知道,那種力量是我實在不想看電工了,經過三個小時的奮鬥,看出來了一點意思,也不晚了,就睡着了,第二天醒來,上課聽老師那熟悉的魔幻的催眠曲暈的厲害,害,不聽了,搞我的迷宮吧,就這樣,經過兩天的奮鬥,我看懂了,慢慢的,也寫出來了,
當然,行數和列數都是可以變化的,臉上有了一絲欣慰,這麼複雜,我玩不了,搞了一個簡單的,就通關了
感覺還行吧,後面會實現一個DFS和BFS的自動探路算法,後序有時間再寫吧,我把源碼奉上,有興趣的小夥伴可以一起交流哦!
#include "acllib.h"
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#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