首頁 > 軟體

基於C語言實現迷宮遊戲的範例程式碼

2022-05-27 14:04:06

C語言迷宮遊戲

這篇文章是給學完並學懂了C語言的分支(選擇和迴圈)結構和二維陣列的朋友看的。

要做一個遊戲或者程式先要想好有那些要求,以下是我認為一個迷宮必帶的要求: 

  • 迷宮要先列印出來(要設定牆、空氣、小球的起點),是牆就不能,是空氣就可以走。
  • 每次輸入'w'、'a'、's'、'd'為上、左、下、右,並每次輸入後,不用按回車或任意鍵繼續就能輸出,每次走一步(按鍵盤的鍵走)後,先清屏再輸出現在迷宮以及小球現在在哪裡。
  • 要有起點和終點的X、Y軸,如果小球與終點的位置相同了,就提示勝利並退出遊戲。 

定義地圖

首先我們要列印出地圖,因為地圖有長和寬的長度,所以我們要用二維陣列來定義一個地圖,程式碼如下:

    char map[50][50]={
                    "######",//申請50*50的二維字串當迷宮地圖,但這裡是6*6的地圖
                    "#O #  ",//'#'是牆(不可以走的地方)
                    "# ## #",//'O'是起點(可控制)
                    "#  # #",//' '是空氣(可以走的地方)
                    "##   #",
                    "######",//橫豎都是012345,012345(陣列下標從0開始)
                    };

列印地圖方法一

定義完二維陣列,就要把它列印出來,程式碼如下:

int i,j;
for(i=0;i<6;i++)//i迴圈用來控制列印地圖的行數
{
    for(j=0;j<6;j++)//j迴圈用來控制列印地圖的列數
    {
        printf("%c",map[i][j]);//列印每次i和j的行數和列數
    }
    printf("n");//一行列印完畢需要換行
}

列印地圖方法二

上面這段程式碼是通過雙重回圈列印出地圖的每行每列。

如果學過puts函數來輸出字元陣列的朋友可以這樣寫,程式碼如下:

int i;
for(i=0;i<6;i++)//從0到5,共進行了6次迴圈,依次輸出迷宮的第0至5行
    puts(map[i]);//表示輸出每一行的字串

是不是簡單了許多,不懂puts函數的朋友也沒關係,你用第一種方法就行,對於puts函數你只需要知道:

  • 使用 puts() 顯示字串時,系統會自動在其後新增一個換行符。
  • 只有遇到 '' 也就是字串結束標誌符才會停止。

定義起點和終點位置

然後再定義起點和終點的X、Y軸位置(當然上面定義二維陣列時已經看得出來了),程式碼如下:

​int x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 
            //p,q為空白(終點" ")結束位置豎橫軸
x=1;y=1;//x為豎軸初始位置為1,y為初始橫軸位置為1
p=1;q=5;//p為豎軸結束位置為1,q為結束橫軸位置為5

總結以上程式碼

目前為止,我們做了定義地圖、列印地圖、定義起點終點的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(陣列下標從0開始)
                        };
    int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 
                  //p,q為空白(終點" ")結束位置豎橫軸
    int ch;//申請需要輸入的字元(名稱是ch),當移動(w,a,s,d)
    x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1
                    //p為豎軸結束位置為1,q為結束橫軸位置為5
    for(i=0;i<6;i++)//從0到5,共進行了6次迴圈,依次輸出迷宮的第0至5行
        puts(map[i]);//表示輸出每一行的字串
    Sleep(5000);//上面程式碼全部執行完畢後過五秒自動關閉程式
    return 0;
}

現在我們就要想辦法控制小球了,這裡利用鍵盤上的'w''s''a''d'四個鍵來控制這個小球進行上、下、左、右移動,當然你如果喜歡,也可以用別的按鍵。

第一步:先來控制小球向下移動,也就是當你按下's'鍵時,小球向下移動一步。

那麼如何獲得's'這個按鍵呢,換句話說:當你按下's'鍵時,我們的程式怎樣知道你按的是's'鍵呢?

實現讀取按鍵

很簡單,因為你按下's'鍵時,本質上是輸入了1個字元's',我們只需要讀取這個字元's'就可以了,讀取一個字元有4種方法:

char ch;
scanf("%c",&ch);//讀取一個字元,輸入後等待使用者按"Enter"鍵結束(帶回顯)
ch=getchar;//讀取一個字元,輸入後等待使用者按"Enter"鍵結束(帶回顯)
ch=getche;//讀取一個字元,輸入後立即獲取字元,不用按"Enter"鍵結束(帶回顯)
ch=getch;//讀取一個字元,輸入後立即獲取字元,不用按"Enter"鍵結束(不帶回顯)

而我們並不想顯示輸入的字元,並且希望輸入的字元可以立即被程式獲得,而不用在敲擊一個字元后再敲擊一個"Enter"鍵。

因此我們選用最後一個語句ch=getch();。

實現小球下向下移動一步

接下來,我們要把在鍵盤上敲擊的字元儲存在字元變數ch中,再接下來實現當敲擊's'時。讓小球向下移動一步,程式碼如下:

​if(ch=='s')//判斷你是否輸入(按)'s'這個字元
{
    if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執行[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不變,但是小球已經不在剛才那一豎列了,而在右邊的一個豎列,因此y需要加1。

總結小球移動規律

  • 向下移動是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]=' ';(注意此處兩個單引號之間中間有一個空格)就是讓小球的當前位置變為空格,

第二句:x++;這句話非常重要,它表示更改小球的位置,因為小球向下運動只需要x++就可以了,y不變。

第三句:a[x][y]='O';語句就是將小球新位置上的內容替換為小球'O'。

請注意上面一個程式碼,可不能寫成:

map[x][y]=' ';           
map[x+1][y]='O';

至於為什麼,大家自己去想想吧!

實現重新列印地圖

因為小球的位置有了變化,因此還需要將新迷宮的狀態重新列印一次,在列印之前記得要將之前的螢幕清屏,程式碼如下:

int i;
system("cls");//每次移動了小球就清屏一次
for(i=0;i<6;i++)//清屏了再次迴圈輸出新的地圖
    puts(map[i]);//清屏了再次輸出新的地圖

總結以上程式碼

​#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(陣列下標從0開始)
                        };
    int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 
                  //p,q為空白(終點" ")結束位置豎橫軸
    int ch;//申請需要輸入的字元(名稱是ch),當移動(w,a,s,d)
    x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1
                    //p為豎軸結束位置為1,q為結束橫軸位置為5
    for(i=0;i<6;i++)//從0到5,共進行了6次迴圈,依次輸出迷宮的第0至5行
        puts(map[i]);//表示輸出每一行的字串
    ch=getch();//這語句表示給ch變數輸入的字元可以立即被程式獲取(不用按任意鍵繼續),也不會回顯
    if (ch=='s')//判斷你是否輸入(按)'s'這個字元
    {
        if (map[x+1][y]!='#')//確認輸入(按)的是's'時,就執行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(牆)
        {                       
            map[x][y]=' ';//確認往下走不是牆時,把當前的'O'輸出成' '
            x++;//為向下走
            map[x][y]='O';//確認往下走不是牆時,把下一步的' '輸出成'O'
        }
    }
    system("cls");//每次移動了小球就清屏一次
    for(i=0;i<6;i++)//清屏了再次迴圈輸出新的地圖
       puts(map[i]);//清屏了再次輸出新的地圖
    Sleep(5000);//上面程式碼全部執行完畢後過五秒自動關閉程式
    return 0;
}

執行一下,然後按一下's'鍵,是不是已經可以看到小球向下移動了一步了呢?

但是你只能移動一步,如何實現連續移動呢?

實現連續移動

很簡單,實現連續移動我們可以通過while迴圈來解決問題:

#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(陣列下標從0開始)
                        };
    int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 
                  //p,q為空白(終點" ")結束位置豎橫軸
    int ch;//申請需要輸入的字元(名稱是ch),當移動(w,a,s,d)
    x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1
                    //p為豎軸結束位置為1,q為結束橫軸位置為5
    for(i=0;i<6;i++)//從0到5,共進行了6次迴圈,依次輸出迷宮的第0至5行
        puts(map[i]);//表示輸出每一行的字串
    while(1)//暫時無限迴圈
    {
        ch=getch();//這語句表示給ch變數輸入的字元可以立即被程式獲取(不用按任意鍵繼續),也不會回顯
        if(ch=='s')//判斷你是否輸入(按)'s'這個字元
        {
            if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執行[x+1][y](往下走,x為豎軸,+1為往下,y不變),提前是還要判斷往下走是否為'#'(牆)
            {                       
                map[x][y]=' ';//確認往下走不是牆時,把當前的'O'輸出成' '
                x++;//為向下走
                map[x][y]='O';//確認往下走不是牆時,把下一步的' '輸出成'O'
            }
        }
        system("cls");//每次移動了小球就清屏一次
        for(i=0;i<6;i++)//清屏了再次迴圈輸出新的地圖
           puts(map[i]);//清屏了再次輸出新的地圖
    }
    Sleep(5000);//上面程式碼全部執行完畢後過五秒自動關閉程式
    return 0;
}

暫時先使用while(1)無限迴圈來解決這個問題,好了,執行一下吧。

此時小球是不是可以連續移動了?

當然,目前小球還只能朝一個方向運動,接下來我們來實現小球向其它3個方向的運動。

實現小球下向上下左右移動

向其它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(陣列下標從0開始)
                        };
    int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 
                  //p,q為空白(終點" ")結束位置豎橫軸
    int ch;//申請需要輸入的字元(名稱是ch),當移動(w,a,s,d)
    x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1
                    //p為豎軸結束位置為1,q為結束橫軸位置為5
    for (i=0;i<6;i++)//從0到5,共進行了6次迴圈,依次輸出迷宮的第0至5行
        puts(map[i]);//表示輸出每一行的字串
    while(1)//暫時無限迴圈
    {
        ch=getch();//這語句表示給ch變數輸入的字元可以立即被程式獲取(不用按任意鍵繼續),也不會回顯
        if(ch=='s')//判斷你是否輸入(按)'s'這個字元
        {
            if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執行[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'時,就執行[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'時,就執行[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'時,就執行[x][y-1](往右走,y為橫軸,+1為往右,x不變),提前是還要判斷往下走是否為'#'(牆)
            {                       
                map[x][y]=' ';//確認往右走不是牆時,把當前的'O'輸出成' '
                y++;//為向右走
                map[x][y]='O';//確認往右走不是牆時,把下一步的' '輸出成'O'
            }
        }
        system("cls");//每次移動了小球就清屏一次
        for(i=0;i<6;i++)//清屏了再次迴圈輸出新的地圖
           puts(map[i]);//清屏了再次輸出新的地圖
    }
    Sleep(5000);//上面程式碼全部執行完畢後過五秒自動關閉程式
    return 0;
}

好了,你是不是已經成功走出了迷宮?

可是貌似程式並沒有讓你很驚喜,因為沒有判定你已經成功走出迷宮。

最後我們來寫一個"獲勝"的檢測部分,其實只需要將我們之前寫的while(1)改為while(x!=p||y!=q)就可以了。

實現小球走到終點就勝利

還記得嗎,之前我們用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(陣列下標從0開始)
                        };
    int i,x,y,p,q;//x,y為小球(起點"O")初始位置豎橫軸 
                  //p,q為空白(終點" ")結束位置豎橫軸
    int ch;//申請需要輸入的字元(名稱是ch),當移動(w,a,s,d)
    x=1;y=1;p=1;q=5;//x為豎軸初始位置為1,y為初始橫軸位置為1
                    //p為豎軸結束位置為1,q為結束橫軸位置為5
    for(i=0;i<6;i++)//從0到5,共進行了6次迴圈,依次輸出迷宮的第0至5行
        puts(map[i]);//表示輸出每一行的字串
     while (x!=p||y!=q)//只要x的值不等p或y的值不等q就無限迴圈   
    {
        ch=getch();//這語句表示給ch變數輸入的字元可以立即被程式獲取(不用按任意鍵繼續),也不會回顯
        if(ch=='s')//判斷你是否輸入(按)'s'這個字元
        {
            if(map[x+1][y]!='#')//確認輸入(按)的是's'時,就執行[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'時,就執行[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'時,就執行[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'時,就執行[x][y-1](往右走,y為橫軸,+1為往右,x不變),提前是還要判斷往下走是否為'#'(牆)
            {                       
                map[x][y]=' ';//確認往右走不是牆時,把當前的'O'輸出成' '
                y++;//為向右走
                map[x][y]='O';//確認往右走不是牆時,把下一步的' '輸出成'O'
            }
        }
        system("cls");//每次移動了小球就清屏一次
        for(i=0;i<6;i++)//清屏了再次迴圈輸出新的地圖
           puts(map[i]);//清屏了再次輸出新的地圖
    }
    system("cls");//最後通關後清屏
    printf("恭喜你贏了!n");//最後通關後提示輸出語句
    Sleep(5000);//上面程式碼全部執行完畢後過五秒自動關閉程式
    return 0;
}

以上就是基於C語言實現迷宮遊戲的範例程式碼的詳細內容,更多關於C語言迷宮遊戲的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com