最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux下用C語(yǔ)言實(shí)現(xiàn)推箱子游戲

 更新時(shí)間:2020年07月17日 11:52:18   作者:IHAD alone  
這篇文章主要為大家詳細(xì)介紹了Linux下用C語(yǔ)言實(shí)現(xiàn)小老鼠推箱子的游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前面有Linux的常用命令和vim文本編輯器還沒(méi)有介紹,之后我會(huì)補(bǔ)上的。
今天來(lái)介紹如何用C語(yǔ)言寫一個(gè)簡(jiǎn)單的小游戲,叫做“小老鼠推箱子”。雖然游戲的編寫過(guò)程不復(fù)雜,但是我覺(jué)得能夠從中找到自己對(duì)于編程的不足和完善自己的編程思維是最重要的。游戲代碼不多,所以直接寫在一個(gè)c文件中。本人小白,有不足之處還望指教

游戲介紹

下圖是游戲開(kāi)始界面,$是小老鼠,#是墻,O是終點(diǎn),當(dāng)小老鼠把所有箱子推進(jìn)終點(diǎn)就代表游戲通過(guò)。

游戲思維

游戲地圖用一個(gè)二維數(shù)組去存儲(chǔ)。數(shù)組中不同的值代表不同的對(duì)象(老鼠、墻、路等)。當(dāng)小老鼠在移動(dòng)時(shí),數(shù)組中的值也會(huì)隨之改變,但是為了在游戲無(wú)法進(jìn)行下去時(shí)可以從新開(kāi)始游戲,所以需要另一個(gè)數(shù)組去保留地圖的初始狀態(tài)。也就是說(shuō)需要兩個(gè)二維數(shù)組,一個(gè)始終不改變,一個(gè)用來(lái)記錄實(shí)時(shí)的狀態(tài)。

小老鼠在移動(dòng)時(shí)會(huì)遇到兩種情況,即可移動(dòng)和不可移動(dòng)。在編寫代碼時(shí),只需要將可移動(dòng)的情況寫完成,那么就不需要去判斷不可移動(dòng)的狀態(tài)??梢苿?dòng)的情況有下面兩種:

1、小老鼠面前什么也沒(méi)有(面前是路或者是終點(diǎn))。
2、小老鼠前面是箱子,此時(shí)分為兩種情況(箱子前面是路或者箱子前面是終點(diǎn))。
這時(shí)候,應(yīng)當(dāng)思考的是如何根據(jù)二維數(shù)組的值去判斷上述情況,以及當(dāng)小老鼠移動(dòng)和推動(dòng)箱子時(shí),二維數(shù)組的值是如何變化的。

#include <stdio.h>
#include "get_keyboard.h"
//地圖7行8列 行[0-6] 列[0-7]
//0 路
//1 墻
//2 箱子
//3 終點(diǎn)
//4 小老鼠
//7 小老鼠站在終止上
//5 箱子到達(dá)終點(diǎn)上

int g_boards[7][8] =
{
 {0,1,1,1,1,1,1,0},
 {0,1,0,0,0,0,1,1},
 {1,3,0,1,1,2,0,1},
 {1,0,3,3,2,0,0,1},
 {1,0,0,1,2,0,0,1},
 {1,0,0,4,0,1,1,1},
 {1,1,1,1,1,0,0,0}
}, boards[7][8]={};
//記錄小老鼠在移動(dòng)中的位置
int row = 0;
int col = 0;
int cnt = 0;//箱子個(gè)數(shù),用來(lái)判斷游戲是否結(jié)束。

用0~4表示地圖上面有的小老鼠等物體,值得提的是對(duì)于箱子和小老鼠來(lái)說(shuō),他們移動(dòng)時(shí)都可能會(huì)在終點(diǎn)上,那么他們移入終點(diǎn)和移開(kāi)終點(diǎn)時(shí)的情況需要分別去判斷,為了能夠避免過(guò)多的判斷,當(dāng)它們移入終點(diǎn)時(shí),終點(diǎn)所在位置的值就等于它們的值加上終點(diǎn)的值。同理,當(dāng)它們移開(kāi)終點(diǎn)時(shí),終點(diǎn)所在位置的值就等于終點(diǎn)的值減去它們的值。這樣就不用去判斷小老鼠和箱子在不在終點(diǎn)上了。所以,小老鼠在終點(diǎn)上的值是7。

代碼詳解

這里先從main()函數(shù)開(kāi)始思考。當(dāng)游戲開(kāi)始時(shí),需要先將地圖初始化,即把用來(lái)記錄實(shí)時(shí)狀態(tài)的地圖初始化成游戲開(kāi)始時(shí)的地圖(就是前面提的的兩個(gè)地圖),所以這里需要init()函數(shù)。初始化后就是開(kāi)始游戲,游戲過(guò)程中需要獲取方向鍵,這些在start()函數(shù)中完成。之后,在這些函數(shù)中再去思考是否需要去寫其他函數(shù)補(bǔ)足功能。

//初始化地圖
void init()
{
 for(int i=0; i<7*8; i++)
 { //這里是為了當(dāng)你按下enter鍵時(shí),能夠重置游戲,重置游戲時(shí)需要重新初始化地圖
 boards[i/8][i%8]=g_boards[i/8][i%8];
 if(4==boards[i/8][i%8]) //這里還需要記錄老鼠的位置
 {
 row=i/8;
 col=i%8;
 }
 }
}

//打印地圖
void print()
{
 for(int i=0; i<7; i++)
 {
 for(int j=0; j<8; j++)
 {
 switch(boards[i][j])
 {
 case 0:
  printf(" ");break; //空格代表路徑
 case 1:
  printf("#");break; //打印墻
 case 2:
 case 5:
  printf("@");break; //打印箱子
 case 3:
  printf("O");break; //打印終點(diǎn)
 case 4:
 case 7:
  printf("$");break; //打印小老鼠
 }
 }
 printf("\n");
 }
}

//推箱子
void move(int nrow, int ncol, int nnrow, int nncol)
{
 if(0==boards[nrow][ncol] || 3==boards[nrow][ncol]) //如果小老鼠前面是路或者終點(diǎn),說(shuō)明可以移動(dòng)
 {
 boards[nrow][ncol] +=4;//小老鼠進(jìn)入這個(gè)位置了
 boards[row][col] -=4;//小老鼠離開(kāi)這個(gè)位置了
 //移動(dòng)過(guò)后小老鼠的位置也改變了
 row = nrow;
 col = ncol;
 }
 else if(2==boards[nrow][ncol] || 5==boards[nrow][ncol]) //如果小老鼠前面是箱子
 {
 if(0==boards[nnrow][nncol] || 3==boards[nnrow][nncol]) //如果箱子前面是路或者終點(diǎn)則可以移動(dòng)
 {
 boards[nnrow][nncol] +=2;
 boards[nrow][ncol] -=2-4;
 //這里其實(shí)是boards[nrow][ncol]=boards[nrow][ncol]-2+4
 //減去2是因?yàn)橄渥右谱吡耍由?是因?yàn)樾±鲜筮M(jìn)入了
 boards[row][col] -=4;
 row=nrow;
 col=ncol;
 }
 }
 for(int i=0; i<7; i++) //統(tǒng)計(jì)游戲是否結(jié)束,當(dāng)箱子都在終點(diǎn)上時(shí)就結(jié)束了
 {
 for(int j=0; j<8; j++)
 {
 if(5==boards[i][j])
 {
 cnt++;
 }
 if(3==cnt)
 {
 printf("通關(guān)!\n");
 exit(0);//通關(guān)退出游戲
 }
 }
 }
 cnt=0; //如果游戲沒(méi)有結(jié)束,下次還是需要從0統(tǒng)計(jì)
}

//開(kāi)始游戲
void start()
{
 while(1)
 {
 print();//游戲開(kāi)始時(shí)需要打印地圖,每次從鍵盤上獲得方向移動(dòng)后也需要打印地圖
 int dir=get_keyboard(); //從鍵盤獲取方向
 system("clear"); //下次打印地圖時(shí),先將屏幕清空
 switch(dir) //每次都需要判斷小老鼠前面和前面的前面的坐標(biāo)的狀態(tài),這樣可以在move()
  //函數(shù)中統(tǒng)一各個(gè)方向的寫法
 {
 case KEY_UP: move(row-1, col, row-2, col);break;
 case KEY_DOWN: move(row+1, col, row+2, col);break;
 case KEY_LEFT: move(row, col-1, row, col-2);break;
 case KEY_RIGHT: move(row, col+1, row, col+2);break;
 case KEY_ENTER:
  init();break; //按enter則從新開(kāi)始游戲
 case KEY_q:
  exit(0);//如果按q則退出游戲
 }
 }
}

int main()
{
 //游戲初始化
 init();
 system("clear"); //系統(tǒng)命令,用來(lái)清空屏幕

 //開(kāi)始游戲
 start();

 return 0;
}

好了,這就是今天的內(nèi)容。這里需要的用來(lái)獲取鍵盤的頭文件直接粘貼在下面。

#ifndef GETCH_H
#define GETCH_H
#include <stdio.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>

typedef enum KEYBOARD
{
 KEY_UP  = 183,
 KEY_DOWN = 184,
 KEY_RIGHT = 185,
 KEY_LEFT = 186,
 KEY_BACKSPACE = 127,
 KEY_ENTER = 10,
 KEY_0   = 48,
 KEY_1   = 49,
 KEY_2   = 50,
 KEY_3   = 51,
 KEY_4   = 52,
 KEY_5   = 53,
 KEY_6   = 54,
 KEY_7   = 55,
 KEY_8   = 56,
 KEY_9   = 57,
 KEY_A   = 65,
 KEY_B   = 66,
 KEY_C   = 67,
 KEY_D   = 68,
 KEY_E   = 69,
 KEY_F   = 70,
 KEY_G   = 71,
 KEY_H   = 72,
 KEY_I   = 73,
 KEY_J   = 74,
 KEY_K   = 75,
 KEY_L   = 76,
 KEY_M   = 77,
 KEY_N   = 78,
 KEY_O   = 79,
 KEY_P   = 80,
 KEY_Q   = 81,
 KEY_R   = 82,
 KEY_S   = 83,
 KEY_T   = 84,
 KEY_U   = 85,
 KEY_V   = 86,
 KEY_W   = 87,
 KEY_X   = 88,
 KEY_Y   = 89,
 KEY_Z   = 90,
 KEY_a   = 97,
 KEY_b   = 98,
 KEY_c   = 99,
 KEY_d   = 100,
 KEY_e   = 101, 
 KEY_f   = 102,
 KEY_g   = 103,
 KEY_h   = 104,
 KEY_i   = 105,
 KEY_j   = 106,
 KEY_k   = 107,
 KEY_l   = 108,
 KEY_m   = 109,
 KEY_n   = 110,
 KEY_o   = 111,
 KEY_p   = 112,
 KEY_q   = 113,
 KEY_r   = 114,
 KEY_s   = 115,
 KEY_t   = 116,
 KEY_u   = 117,
 KEY_v   = 118,
 KEY_w   = 119,
 KEY_x   = 120,
 KEY_y   = 121,
 KEY_z   = 122
}KEYBOARD;

//此函數(shù)能立即從鍵盤不回顯的接收數(shù)據(jù)
static int get_keyboard(void)
{
 //接收系統(tǒng)調(diào)用的執(zhí)行結(jié)果
 int ret = 0;
 //存儲(chǔ)終端設(shè)備的配置信息
 struct termios old;
 //通過(guò)系統(tǒng)調(diào)用獲取終端的配置信息
 ret=tcgetattr(STDIN_FILENO,&old);
 if(0 > ret)
 {
 perror("tcgetattr");
 return -1;
 }
 //初始化新的終端配置信息
 struct termios new = old;
 //取消回顯并立即獲取
 new.c_lflag &= ~(ICANON|ECHO);
 //設(shè)置新的終端配置信息
 ret= tcsetattr(STDIN_FILENO,TCSANOW,&new);
 if(0 > ret)
 {
 perror("tcsetattr");
 return -2;
 }
 //在新的模式下從終端獲取數(shù)據(jù)
 int key_value = 0;
 do
 {
 key_value += getchar();
 //由于和系統(tǒng)對(duì)FILE結(jié)構(gòu)體的實(shí)現(xiàn)各不相同
 //linux系統(tǒng) while(stdin->_IO_read_end - stdin->_IO_read_ptr);
 //OS系統(tǒng) while(stdin->_r);
 }while(stdin->_IO_read_end - stdin->_IO_read_ptr);
 //還原終端的配置信息
 ret = tcsetattr(STDIN_FILENO,TCSANOW,&old);
 if(0 > ret)
 {
 perror("tcsetattr");
 return -3;
 }
 //返回獲取到的數(shù)據(jù)
 return key_value;
}
#endif//GETCH_H

更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:

C++經(jīng)典小游戲匯總

python經(jīng)典小游戲匯總

python俄羅斯方塊游戲集合

JavaScript經(jīng)典游戲 玩不停

java經(jīng)典小游戲匯總

javascript經(jīng)典小游戲匯總

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

财经| 万载县| 石渠县| 开阳县| 乌鲁木齐县| 蓝山县| 哈巴河县| 林周县| 商洛市| 大名县| 上杭县| 吉水县| 崇阳县| 民勤县| 宾川县| 綦江县| 扬中市| 黄浦区| 疏勒县| 东莞市| 南靖县| 铁岭市| 仙桃市| 西吉县| 洞口县| 石台县| 收藏| 吉隆县| 松滋市| 广德县| 永兴县| 班玛县| 嘉荫县| 中卫市| 满洲里市| 蒙自县| 湖州市| 嘉善县| 仁化县| 临猗县| 烟台市|