基于C語言實現(xiàn)迷宮游戲的示例代碼
C語言迷宮游戲
這篇文章是給學完并學懂了C語言的分支(選擇和循環(huán))結(jié)構(gòu)和二維數(shù)組的朋友看的。
要做一個游戲或者程序先要想好有那些要求,以下是我認為一個迷宮必帶的要求:
- 迷宮要先打印出來(要設置墻、空氣、小球的起點),是墻就不能,是空氣就可以走。
- 每次輸入'w'、'a'、's'、'd'為上、左、下、右,并每次輸入后,不用按回車或任意鍵繼續(xù)就能輸出,每次走一步(按鍵盤的鍵走)后,先清屏再輸出現(xiàn)在迷宮以及小球現(xiàn)在在哪里。
- 要有起點和終點的X、Y軸,如果小球與終點的位置相同了,就提示勝利并退出游戲。
定義地圖
首先我們要打印出地圖,因為地圖有長和寬的長度,所以我們要用二維數(shù)組來定義一個地圖,代碼如下:
char map[50][50]={ "######",//申請50*50的二維字符串當迷宮地圖,但這里是6*6的地圖 "#O # ",//'#'是墻(不可以走的地方) "# ## #",//'O'是起點(可控制) "# # #",//' '是空氣(可以走的地方) "## #", "######",//橫豎都是012345,012345(數(shù)組下標從0開始) };
打印地圖方法一
定義完二維數(shù)組,就要把它打印出來,代碼如下:
int i,j; for(i=0;i<6;i++)//i循環(huán)用來控制打印地圖的行數(shù) { for(j=0;j<6;j++)//j循環(huán)用來控制打印地圖的列數(shù) { printf("%c",map[i][j]);//打印每次i和j的行數(shù)和列數(shù) } printf("\n");//一行打印完畢需要換行 }
打印地圖方法二
上面這段代碼是通過雙重循環(huán)打印出地圖的每行每列。
如果學過puts函數(shù)來輸出字符數(shù)組的朋友可以這樣寫,代碼如下:
int i; for(i=0;i<6;i++)//從0到5,共進行了6次循環(huán),依次輸出迷宮的第0至5行 puts(map[i]);//表示輸出每一行的字符串
是不是簡單了許多,不懂puts函數(shù)的朋友也沒關系,你用第一種方法就行,對于puts函數(shù)你只需要知道:
- 使用 puts() 顯示字符串時,系統(tǒng)會自動在其后添加一個換行符。
- 只有遇到 '\0' 也就是字符串結(jié)束標志符才會停止。
定義起點和終點位置
然后再定義起點和終點的X、Y軸位置(當然上面定義二維數(shù)組時已經(jīng)看得出來了),代碼如下:
?int x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 //p,q為空白(終點" ")結(jié)束位置豎橫軸 x=1;y=1;//x為豎軸初始位置為1,y為初始橫軸位置為1 p=1;q=5;//p為豎軸結(jié)束位置為1,q為結(jié)束橫軸位置為5
總結(jié)以上代碼
目前為止,我們做了定義地圖、打印地圖、定義起點終點的X、Y軸,目前全部代碼如下:
#include<stdio.h>//printf("");的頭文件 #include<stdlib.h>//system("");的頭文件 #include<Windows.h>//Sleep();的頭文件 int m1ain(void) { char map[50][50]={ "######",//申請50*50的二維字符串當迷宮地圖,但這里是6*6的地圖 "#O # ",//'#'是墻(不可以走的地方) "# ## #",//'O'是起點(可控制) "# # #",//' '是空氣(可以走的地方) "## #", "######",//橫豎都是012345,012345(數(shù)組下標從0開始) }; int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 //p,q為空白(終點" ")結(jié)束位置豎橫軸 int ch;//申請需要輸入的字符(名稱是ch),當移動(w,a,s,d) x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1 //p為豎軸結(jié)束位置為1,q為結(jié)束橫軸位置為5 for(i=0;i<6;i++)//從0到5,共進行了6次循環(huán),依次輸出迷宮的第0至5行 puts(map[i]);//表示輸出每一行的字符串 Sleep(5000);//上面代碼全部執(zhí)行完畢后過五秒自動關閉程序 return 0; }
現(xiàn)在我們就要想辦法控制小球了,這里利用鍵盤上的'w''s''a''d'四個鍵來控制這個小球進行上、下、左、右移動,當然你如果喜歡,也可以用別的按鍵。
第一步:先來控制小球向下移動,也就是當你按下's'鍵時,小球向下移動一步。
那么如何獲得's'這個按鍵呢,換句話說:當你按下's'鍵時,我們的程序怎樣知道你按的是's'鍵呢?
實現(xiàn)讀取按鍵
很簡單,因為你按下's'鍵時,本質(zhì)上是輸入了1個字符's',我們只需要讀取這個字符's'就可以了,讀取一個字符有4種方法:
char ch; scanf("%c",&ch);//讀取一個字符,輸入后等待用戶按"Enter"鍵結(jié)束(帶回顯) ch=getchar;//讀取一個字符,輸入后等待用戶按"Enter"鍵結(jié)束(帶回顯) ch=getche;//讀取一個字符,輸入后立即獲取字符,不用按"Enter"鍵結(jié)束(帶回顯) ch=getch;//讀取一個字符,輸入后立即獲取字符,不用按"Enter"鍵結(jié)束(不帶回顯)
而我們并不想顯示輸入的字符,并且希望輸入的字符可以立即被程序獲得,而不用在敲擊一個字符后再敲擊一個"Enter"鍵。
因此我們選用最后一個語句ch=getch();。
實現(xiàn)小球下向下移動一步
接下來,我們要把在鍵盤上敲擊的字符存儲在字符變量ch中,再接下來實現(xiàn)當敲擊's'時。讓小球向下移動一步,代碼如下:
?if(ch=='s')//判斷你是否輸入(按)'s'這個字符 { if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執(zhí)行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往下走不是墻時,把當前的'O'輸出成' ' x++;//為向下走 map[x][y]='O';//確認往下走不是墻時,把下一步的' '輸出成'O' } }
在上面代碼中,我們通過if語句來判斷敲擊的字符是否是字符's',如果是字符's',我們就讓小球向下移動一步,但在小球向下移動之前,需要首先判斷下面一步是否能移動,只有下一步不是墻'#'時小球才能移動。
也就是說當if(map[x+1][y]!='#')條件成立時,就表示下一步不是墻,小球可以移動。
可能有些朋友會問:為什么[x+1][y]就表示向下走一部的格子呢?
其實很簡單:向下移動時,小球當然還在當前這個列,不過不在這一行,而是在下一行,因此向下移動是y不變,x加1。
如果是向右邊移動,很顯然還是在同一行,所以x不變,但是小球已經(jīng)不在剛才那一豎列了,而在右邊的一個豎列,因此y需要加1。
總結(jié)小球移動規(guī)律
- 向下移動是y不變,x加1。
- 向上移動是y不變,x減1。
- 向左移動是x不變,y減1。
- 向右移動是x不變,y加1。
接下來我們來講解下面這3句話的意思:
map[x][y]=' ';//確認往下走不是墻時,把當前的'O'輸出成' ' x++;//為向下走 map[x][y]='O';//確認往下走不是墻時,把下一步的' '輸出成'O'
讓小球向下移動,就是讓小球原本位置上的'O'變成空格,而讓下一個空格變成'O'。
第一句:map[x][y]=' ';(注意此處兩個單引號之間中間有一個空格)就是讓小球的當前位置變?yōu)榭崭瘢?/p>
第二句:x++;這句話非常重要,它表示更改小球的位置,因為小球向下運動只需要x++就可以了,y不變。
第三句:a[x][y]='O';語句就是將小球新位置上的內(nèi)容替換為小球'O'。
請注意上面一個代碼,可不能寫成:
map[x][y]=' '; map[x+1][y]='O';
至于為什么,大家自己去想想吧!
實現(xiàn)重新打印地圖
因為小球的位置有了變化,因此還需要將新迷宮的狀態(tài)重新打印一次,在打印之前記得要將之前的屏幕清屏,代碼如下:
int i; system("cls");//每次移動了小球就清屏一次 for(i=0;i<6;i++)//清屏了再次循環(huán)輸出新的地圖 puts(map[i]);//清屏了再次輸出新的地圖
總結(jié)以上代碼
?#include<stdio.h>//printf("");的頭文件 #include<stdlib.h>//system("");的頭文件 #include<Windows.h>//Sleep();的頭文件 #include<conio.h>//getch();的頭文件 int main(void) { char map[50][50]={ "######",//申請50*50的二維字符串當迷宮地圖,但這里是6*6的地圖 "#O # ",//'#'是墻(不可以走的地方) "# ## #",//'O'是起點(可控制) "# # #",//' '是空氣(可以走的地方) "## #", "######",//橫豎都是012345,012345(數(shù)組下標從0開始) }; int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 //p,q為空白(終點" ")結(jié)束位置豎橫軸 int ch;//申請需要輸入的字符(名稱是ch),當移動(w,a,s,d) x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1 //p為豎軸結(jié)束位置為1,q為結(jié)束橫軸位置為5 for(i=0;i<6;i++)//從0到5,共進行了6次循環(huán),依次輸出迷宮的第0至5行 puts(map[i]);//表示輸出每一行的字符串 ch=getch();//這語句表示給ch變量輸入的字符可以立即被程序獲取(不用按任意鍵繼續(xù)),也不會回顯 if (ch=='s')//判斷你是否輸入(按)'s'這個字符 { if (map[x+1][y]!='#')//確認輸入(按)的是's'時,就執(zhí)行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往下走不是墻時,把當前的'O'輸出成' ' x++;//為向下走 map[x][y]='O';//確認往下走不是墻時,把下一步的' '輸出成'O' } } system("cls");//每次移動了小球就清屏一次 for(i=0;i<6;i++)//清屏了再次循環(huán)輸出新的地圖 puts(map[i]);//清屏了再次輸出新的地圖 Sleep(5000);//上面代碼全部執(zhí)行完畢后過五秒自動關閉程序 return 0; }
運行一下,然后按一下's'鍵,是不是已經(jīng)可以看到小球向下移動了一步了呢?
但是你只能移動一步,如何實現(xiàn)連續(xù)移動呢?
實現(xiàn)連續(xù)移動
很簡單,實現(xiàn)連續(xù)移動我們可以通過while循環(huán)來解決問題:
#include<stdio.h>//printf("");的頭文件 #include<stdlib.h>//system("");的頭文件 #include<Windows.h>//Sleep();的頭文件 #include<conio.h>//getch();的頭文件 int m1ain(void) { char map[50][50]={ "######",//申請50*50的二維字符串當迷宮地圖,但這里是6*6的地圖 "#O # ",//'#'是墻(不可以走的地方) "# ## #",//'O'是起點(可控制) "# # #",//' '是空氣(可以走的地方) "## #", "######",//橫豎都是012345,012345(數(shù)組下標從0開始) }; int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 //p,q為空白(終點" ")結(jié)束位置豎橫軸 int ch;//申請需要輸入的字符(名稱是ch),當移動(w,a,s,d) x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1 //p為豎軸結(jié)束位置為1,q為結(jié)束橫軸位置為5 for(i=0;i<6;i++)//從0到5,共進行了6次循環(huán),依次輸出迷宮的第0至5行 puts(map[i]);//表示輸出每一行的字符串 while(1)//暫時無限循環(huán) { ch=getch();//這語句表示給ch變量輸入的字符可以立即被程序獲取(不用按任意鍵繼續(xù)),也不會回顯 if(ch=='s')//判斷你是否輸入(按)'s'這個字符 { if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執(zhí)行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往下走不是墻時,把當前的'O'輸出成' ' x++;//為向下走 map[x][y]='O';//確認往下走不是墻時,把下一步的' '輸出成'O' } } system("cls");//每次移動了小球就清屏一次 for(i=0;i<6;i++)//清屏了再次循環(huán)輸出新的地圖 puts(map[i]);//清屏了再次輸出新的地圖 } Sleep(5000);//上面代碼全部執(zhí)行完畢后過五秒自動關閉程序 return 0; }
暫時先使用while(1)無限循環(huán)來解決這個問題,好了,運行一下吧。
此時小球是不是可以連續(xù)移動了?
當然,目前小球還只能朝一個方向運動,接下來我們來實現(xiàn)小球向其它3個方向的運動。
實現(xiàn)小球下向上下左右移動
向其它3個方向移動其實和"向下移動"是差不多的,只要注意是x在變化還是y在變化,是加1還是減1就可以了。無限移動4個方向代碼如下:
#include<stdio.h>//printf("");的頭文件 #include<stdlib.h>//system("");的頭文件 #include<Windows.h>//Sleep();的頭文件 #include<conio.h>//getch();的頭文件 int m1ain(void) { char map[50][50]={ "######",//申請50*50的二維字符串當迷宮地圖,但這里是6*6的地圖 "#O # ",//'#'是墻(不可以走的地方) "# ## #",//'O'是起點(可控制) "# # #",//' '是空氣(可以走的地方) "## #", "######",//橫豎都是012345,012345(數(shù)組下標從0開始) }; int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 //p,q為空白(終點" ")結(jié)束位置豎橫軸 int ch;//申請需要輸入的字符(名稱是ch),當移動(w,a,s,d) x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1 //p為豎軸結(jié)束位置為1,q為結(jié)束橫軸位置為5 for (i=0;i<6;i++)//從0到5,共進行了6次循環(huán),依次輸出迷宮的第0至5行 puts(map[i]);//表示輸出每一行的字符串 while(1)//暫時無限循環(huán) { ch=getch();//這語句表示給ch變量輸入的字符可以立即被程序獲取(不用按任意鍵繼續(xù)),也不會回顯 if(ch=='s')//判斷你是否輸入(按)'s'這個字符 { if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執(zhí)行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往下走不是墻時,把當前的'O'輸出成' ' x++;//為向下走 map[x][y]='O';//確認往下走不是墻時,把下一步的' '輸出成'O' } } if(ch=='w')//判斷你是否輸入(按)'w'這個字符 { if(map[x-1][y]!='#')//確認輸入(按)的是'w'時,就執(zhí)行[x-1][y](往上走,x為豎軸,-1為往上,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往上走不是墻時,把當前的'O'輸出成' ' x--;//為向上走 map[x][y]='O';//確認往上走不是墻時,把下一步的' '輸出成'O' } } if(ch=='a')//判斷你是否輸入(按)'a'這個字符 { if(map[x][y-1]!='#')//確認輸入(按)的是'a'時,就執(zhí)行[x][y-1](往左走,y為橫軸,-1為往左,x不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往左走不是墻時,把當前的'O'輸出成' ' y--;//為向左走 map[x][y]='O';//確認往左走不是墻時,把下一步的' '輸出成'O' } } if(ch=='d')//判斷你是否輸入(按)'d'這個字符 { if(map[x][y+1]!='#')//確認輸入(按)的是'd'時,就執(zhí)行[x][y-1](往右走,y為橫軸,+1為往右,x不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往右走不是墻時,把當前的'O'輸出成' ' y++;//為向右走 map[x][y]='O';//確認往右走不是墻時,把下一步的' '輸出成'O' } } system("cls");//每次移動了小球就清屏一次 for(i=0;i<6;i++)//清屏了再次循環(huán)輸出新的地圖 puts(map[i]);//清屏了再次輸出新的地圖 } Sleep(5000);//上面代碼全部執(zhí)行完畢后過五秒自動關閉程序 return 0; }
好了,你是不是已經(jīng)成功走出了迷宮?
可是貌似程序并沒有讓你很驚喜,因為沒有判定你已經(jīng)成功走出迷宮。
最后我們來寫一個"獲勝"的檢測部分,其實只需要將我們之前寫的while(1)改為while(x!=p||y!=q)就可以了。
實現(xiàn)小球走到終點就勝利
還記得嗎,之前我們用p和q分別存儲了迷宮出口的坐標位置,當然了,在最后我們需要打印"你獲勝了"。完整代碼如下:
#include<stdio.h>//printf("");的頭文件 #include<stdlib.h>//system("");的頭文件 #include<Windows.h>//Sleep();的頭文件 #include<conio.h>//getch();的頭文件 int m1ain(void) { printf("歡迎來到迷宮小游戲\n");//介紹這個迷宮游戲 printf("操作方式:\nw為往上走\ns為往下走\na為往左走\nd為往右走\n");//介紹操作方式 char map[50][50]={ "######",//申請50*50的二維字符串當迷宮地圖,但這里是6*6的地圖 "#O # ",//'#'是墻(不可以走的地方) "# ## #",//'O'是起點(可控制) "# # #",//' '是空氣(可以走的地方) "## #", "######",//橫豎都是012345,012345(數(shù)組下標從0開始) }; int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 //p,q為空白(終點" ")結(jié)束位置豎橫軸 int ch;//申請需要輸入的字符(名稱是ch),當移動(w,a,s,d) x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1 //p為豎軸結(jié)束位置為1,q為結(jié)束橫軸位置為5 for(i=0;i<6;i++)//從0到5,共進行了6次循環(huán),依次輸出迷宮的第0至5行 puts(map[i]);//表示輸出每一行的字符串 while (x!=p||y!=q)//只要x的值不等p或y的值不等q就無限循環(huán) { ch=getch();//這語句表示給ch變量輸入的字符可以立即被程序獲取(不用按任意鍵繼續(xù)),也不會回顯 if(ch=='s')//判斷你是否輸入(按)'s'這個字符 { if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執(zhí)行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往下走不是墻時,把當前的'O'輸出成' ' x++;//為向下走 map[x][y]='O';//確認往下走不是墻時,把下一步的' '輸出成'O' } } if(ch=='w')//判斷你是否輸入(按)'w'這個字符 { if(map[x-1][y]!='#')//確認輸入(按)的是'w'時,就執(zhí)行[x-1][y](往上走,x為豎軸,-1為往上,y不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往上走不是墻時,把當前的'O'輸出成' ' x--;//為向上走 map[x][y]='O';//確認往上走不是墻時,把下一步的' '輸出成'O' } } if(ch=='a')//判斷你是否輸入(按)'a'這個字符 { if(map[x][y-1]!='#')//確認輸入(按)的是'a'時,就執(zhí)行[x][y-1](往左走,y為橫軸,-1為往左,x不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往左走不是墻時,把當前的'O'輸出成' ' y--;//為向左走 map[x][y]='O';//確認往左走不是墻時,把下一步的' '輸出成'O' } } if(ch=='d')//判斷你是否輸入(按)'d'這個字符 { if(map[x][y+1]!='#')//確認輸入(按)的是'd'時,就執(zhí)行[x][y-1](往右走,y為橫軸,+1為往右,x不變),提前是還要判斷往下走是否為'#'(墻) { map[x][y]=' ';//確認往右走不是墻時,把當前的'O'輸出成' ' y++;//為向右走 map[x][y]='O';//確認往右走不是墻時,把下一步的' '輸出成'O' } } system("cls");//每次移動了小球就清屏一次 for(i=0;i<6;i++)//清屏了再次循環(huán)輸出新的地圖 puts(map[i]);//清屏了再次輸出新的地圖 } system("cls");//最后通關后清屏 printf("恭喜你贏了!\n");//最后通關后提示輸出語句 Sleep(5000);//上面代碼全部執(zhí)行完畢后過五秒自動關閉程序 return 0; }
以上就是基于C語言實現(xiàn)迷宮游戲的示例代碼的詳細內(nèi)容,更多關于C語言迷宮游戲的資料請關注腳本之家其它相關文章!
相關文章
C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結(jié)
這篇文章主要介紹了C++中調(diào)用復制(拷貝)函數(shù)的三種情況總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11