用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;
}
-
C語言合併排序及實例代碼
歸併排序也稱合併排序,其算法思想是將待排序序列分為兩部分,依次對分得的兩個部分再次使用歸併排序,之後再對其進行合併。下面是小編分享的C語言合併排序及實例代碼,一起來看一下吧。合併排序僅從算法思想上了解歸併排序會覺得很抽象,接下來就以對序列A[0],A[l]…,A...
-
C語言學習攻略
導語:C語言作為最流行的程序設計語言,是任何一個計算機專業及其愛好者們都必須掌握的一門編程語言。下面就由小編為大家介紹一下C語言學習攻略,歡迎大家閲讀!一、C語言學習中存在的問題(一)基礎薄弱,無法適應C語言學習的課程通常安排在大一,這個時候,學生們剛剛進入...
-
C語言指針的長度和類型講解
對於初學者深入理解C語言程序設計有很好的參考價值,下面是小編為大家整理的C語言指針的長度和類型講解,歡迎參考~一般來説,如果考慮應用程序的兼容性和可移植性,指針的長度就是一個問題,在大部分現代平台上,數據指針的長度通常是一樣的,與指針類型無關,儘管C標準沒有規...
-
如何使用C語言求N的階乘
使用C語言求N的階乘的方法是很多小夥伴都想知道的,下面小編給大家介紹如何使用C語言求N的階乘,歡迎閲讀!如何使用C語言求N的階乘用遞歸法求N的.階乘程序調用自身稱為遞歸(recursion).它通常把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求...