糯米文學吧

位置:首頁 > 計算機 > C語言

用C語言如何實現貪吃蛇編程

C語言2.06W

貪吃蛇遊戲在理論上是可以無限的進行下去的(除了撞牆和咬到自己),那麼遊戲主體就一定是個循環。下面是小編為大家帶來的關於用C語言如何實現貪吃蛇編程的知識,歡迎閲讀

用C語言如何實現貪吃蛇編程
  貪吃蛇實現原理:

貪吃蛇遊戲在理論上是可以無限的進行下去的(除了撞牆和咬到自己),那麼遊戲主體就一定是個循環。

蛇是如何動起來的?在這裏就是通過不斷改變蛇的座標,然後根據蛇的座標不斷刷新屏幕在視覺上形成蛇的移動效果。

食物出現在隨機位置(當然不能出現在障礙物和蛇身上)。

蛇能吃到食物其實就是蛇頭的座標與食物的座標重合時。

當蛇咬到自己或者撞到牆的時候遊戲結束(座標判斷)

#include

#include

#include

#include

#include

//72,80,75,77是方向鍵對應的鍵值

#define UP 72

#define DOWN 80

#define LEFT 75

#define RIGHT 77

#define SNAKE 1 //蛇的座標標識

#define FOOD 2 //食物的座標標識

#define BAR 3 //牆的座標標識

//初始化地圖 17*17

char map[17][17] = {0};

//初始化蛇頭座標

unsigned char snake[50] = {77};

//初始化食物座標

unsigned char food = 68;

//蛇長

char len = 1;

//存儲座標數字與x、y的轉換函數

void tran(unsigned char num,unsigned char * x,unsigned char * y);

//打印遊戲

void print_game(void);

//獲取方向函數(注意當蛇身長度超過一節時不能回頭)

int get_dir(int old_dir);

//移動蛇身函數(遊戲大部分內容在其中)

void move_snake(int dir);

//生產食物的函數

unsigned char generate_food(void);

//判斷蛇死活的函數(判斷了蛇是否撞到邊界或者自食)

int isalive(void);

int main(void){

int dir = UP; //初始方向默認向上,UP是我們定義的宏

//按道理該遊戲是可以無限繼續下去的,因此是個循環

while(1){

print_game(); //打印遊戲

dir = get_dir(dir); //獲取方向(我們摁下的方向)

move_snake(dir); //移動蛇身

if(!isalive()){ //判斷蛇的生命狀態

break;

}

}

printf("Game Over!");

return 0;

}

//

void tran(unsigned char num,unsigned char * x,unsigned char * y){

*x = num >> 4;

*y = (unsigned char)(num << 4) >> 4; //注意這裏要做個強制類型轉換

//根據彙編,如果不做強制轉換,y的值與num的'值相同

}

void print_game(void){

int i,j;

//根據地圖上每點的情況繪製遊戲( i 表示 x 軸,j 表示 y 軸),按行打印,j表示行,i表示列

for(j = 0;j < 17;j ++){

for(i = 0;i < 17;i ++){

//空白地方

if(map[i][j] == 0){

put' ');

}

//蛇身

else if(map[i][j] == SNAKE){

put'*');

}

//圍欄

else if(map[i][j] == BAR){

put'#');

}

//食物

else if(map[i][j] == FOOD){

put'$');

}

}

put'');

}

Sleep(500); //休眠函數 將進程掛起500ms,包含在window.h(在linux下用 sleep(),#include )

system("cls"); //清屏函數 配合下一次 print_game() 起到刷新作用,包含在stdlib.h中

}

int get_dir(int old_dir){

int new_dir = old_dir;

//用kbhit()與getch()組合實現鍵盤響應

//kbhit() 檢查當前是否有鍵盤輸入,若有則返回一個非0值,否則返回0

//getch() 用ch=_getch();會等待你按下任意鍵之後,把該鍵字符所對應的ASCII碼賦給ch,再執行下面的語句。

if(_kbhit()){

_getch(); //第一次輸出的方向鍵的擴展值,第二次是方向鍵的實際值,只有方向鍵上下左右這樣

new_dir = _getch(); //getch()函數要使用兩次,原因是因為第一次返回的值指示該鍵擴展的字符,第二次調用才返回實際的鍵代碼

//如果蛇身長度大於1,則不能回頭,如果摁回頭方向,則按原來方向走

//abs(new_dir - old_dir) == 2 表示 |LEFT-RIGHT|

//abs(new_dir - old_dir) == 8 表示 |UP-DOWN|

if(len > 1 && (abs(new_dir - old_dir) == 2 || abs(new_dir - old_dir) == 8)){

new_dir = old_dir;

}

}

return new_dir;

}

void move_snake(int dir){

int last = snake[0],current; //last與current用於之後蛇座標的更新

int i,j;

int grow=0; //判斷是否要長身體

unsigned char x, y,fx,fy; //蛇座標與食物座標

tran(food, &fx, &fy); //食物座標

tran(snake[0], &x, &y); //蛇頭座標

switch (dir){ //更新蛇頭座標(座標原點是左上角)

case UP:

y--;

break;

case DOWN:

y++;

break;

case LEFT:

x--;

break;

case RIGHT:

x++;

break;

}

//按位抑或(妙!)

//

snake[0] = ((x ^ 0) << 4) ^ y; //將x,y換回一個數

//x與0抑或保留原值

//將x與y重新合成一個值

//蛇吃到了食物

if (snake[0] == food) {

grow = 1;

food = generate_food(); //產生新食物

}

for (i = 0; i

if (i == 0) //如果只有頭,跳過,因為前面已更新蛇頭座標

continue;

current = snake[i]; //將當前操作的蛇節座標存儲到current裏

snake[i] = last; //完成當前操作蛇節座標的更新

last = current; //last記錄的是上一次操作蛇節的座標,這次操作已經結束,故把current賦給last

}

//如果蛇邊長了

if (grow) {

snake[len] = last;

len++;

}

for (j = 0; j < 17; j ++){ //將邊界與食物加到地圖裏去(i,j 對應 x軸和y軸)

for (i = 0; i < 17; i ++){

if (i == 0 || i == 16 || j == 0 || j == 16){

map[i][j] = BAR;

}

else if (i == fx&&j == fy){

map[i][j] = FOOD;

}

else{

map[i][j] = 0;

}

}

for (i = 0; i < len; i++) { //將蛇加到地圖裏去

tran(snake[i], &x, &y);

if (snake[i] > 0){

map[x][y] = SNAKE;

}

}

}

}

unsigned char generate_food(void)

{

unsigned char food_,fx,fy;

int in_snake=0,i;

//以當前時間為參數提供種子供rand()函數生成更為隨機的數

srand((unsigned int)time(NULL));

//循環產生在邊界內且不在蛇身上的食物

do {

food_ = rand() % 255;//產生一個0--255的隨機數

tran(food_, &fx, &fy);

for (i = 0; i < len; i++){

if (food_ == snake[i]){

//在不在蛇身上

in_snake = 1;

}

}

} while (fx == 0 || fx == 16 || fy == 0 || fy == 16 || in_snake);

return food_;

}

int isalive(void)

{

int self_eat = 0;

int i;

unsigned char x, y;

tran(snake[0], &x, &y);

for (i = 1; i < len; i++){

if (snake[0] == snake[i]){

self_eat = 1;

}

}

//蛇頭撞邊界或者吃到自己 ,則死掉

return (x == 0 || x == 16 || y == 0 || y >= 16 || self_eat) ? 0 : 1;

}