#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <time.h> #include <windows.h> const int H = 8; //地圖的高 const int L = 16; //地圖的長 char GameMap[8][16]; //遊戲地圖 int key; //按鍵保存 int sum = 1, over = 0; //蛇的長度, 遊戲結束(自吃或碰牆) int dx[4] = {0, 0, -1, 1}; //左、右、上、下的方向 int dy[4] = {-1, 1, 0, 0}; struct Snake //蛇的每個節點的數據類型 { int x, y; //左邊位置 int now; //保存當前節點的方向, 0,1,2,3分別爲左右上下 }Snake[8*16]; const char Shead = '@'; //蛇頭 const char Sbody = '#'; //蛇身 const char Sfood = '*'; //食物 const char Snode = '.'; //'.'在地圖上標示爲空 void Initial(); //地圖的初始化 void Create_Food(); //在地圖上隨機產生食物 void Show(); //刷新顯示地圖 void Button(); //取出按鍵,並推斷方向 void Move(); //蛇的移動 void Check_Border(); //檢查蛇頭是否越界 void Check_Head(int x, int y); //檢查蛇頭移動後的位置狀況 int main() { Initial(); Show(); return 0; } void Initial() //地圖的初始化 { int i, j; int hx, hy; system("title 貪吃蛇"); //控制檯的標題 memset(GameMap, '.', sizeof(GameMap)); //初始化地圖全部爲空'.' system("cls"); srand(time(0)); //隨機種子 hx = rand()%H; //產生蛇頭 hy = rand()%L; GameMap[hx][hy] = Shead; Snake[0].x = hx; Snake[0].y = hy; Snake[0].now = -1; Create_Food(); //隨機產生食物 for(i = 0; i < H; i++) //地圖顯示 { for(j = 0; j < L; j++) printf("%c", GameMap[i][j]); printf("\n"); } printf("\n小小C語言貪吃蛇\n"); printf("按隨意方向鍵開始遊戲\n"); getch(); //先接受一個按鍵,使蛇開始往該方向走 Button(); //取出按鍵,並推斷方向 } void Create_Food() //在地圖上隨機產生食物 { int fx, fy; while(1) { fx = rand()%H; fy = rand()%L; if(GameMap[fx][fy] == '.') //不能出現在蛇所佔有的位置 { GameMap[fx][fy] = Sfood; break; } } } void Show() //刷新顯示地圖 { int i, j; while(1) { Sleep(500); //延遲半秒(1000爲1s),即每半秒刷新一次地圖 Button(); //先推斷按鍵在移動 Move(); if(over) //自吃或碰牆即遊戲結束 { printf("\n**遊戲結束**\n"); printf(" >_<\n"); getchar(); break; } system("cls"); //清空地圖再顯示刷新吼的地圖 for(i = 0; i < H; i++) { for(j = 0; j < L; j++) printf("%c", GameMap[i][j]); printf("\n"); } printf("\n小小C語言貪吃蛇\n"); printf("按隨意方向鍵開始遊戲\n"); } } void Button() //取出按鍵,並推斷方向 { if(kbhit() != 0) //檢查當前是否有鍵盤輸入,如有則返回一個非0值,不然返回0 { while(kbhit() != 0) //可能存在多個按鍵,要全部取完,以最後一個爲主 key = getch(); //將按鍵從控制檯中取出並保存到key中 switch(key) { //左 case 75: Snake[0].now = 0; break; //右 case 77: Snake[0].now = 1; break; //上 case 72: Snake[0].now = 2; break; //下 case 80: Snake[0].now = 3; break; } } } void Move() //蛇的移動 { int i, x, y; int t = sum; //保存當前蛇的長度 //記錄當前蛇頭的位置,並設置爲空,蛇頭先移動 x = Snake[0].x; y = Snake[0].y; GameMap[x][y] = '.'; Snake[0].x = Snake[0].x + dx[ Snake[0].now ]; Snake[0].y = Snake[0].y + dy[ Snake[0].now ]; Check_Border(); //蛇頭是否越界 Check_Head(x, y); //蛇頭移動後的位置狀況,參數爲: 蛇頭的開始位置 if(sum == t) //未吃到食物即蛇身移動哦 for(i = 1; i < sum; i++) //要從蛇尾節點向前移動哦,前一個節點做爲參照 { if(i == 1) //尾節點設置爲空再移動 GameMap[ Snake[i].x ][ Snake[i].y ] = '.'; if(i == sum-1) //爲蛇頭後面的蛇身節點,特殊處理 { Snake[i].x = x; Snake[i].y = y; Snake[i].now = Snake[0].now; } else //其它蛇身即走到前一個蛇身位置 { Snake[i].x = Snake[i+1].x; Snake[i].y = Snake[i+1].y; Snake[i].now = Snake[i+1].now; } GameMap[ Snake[i].x ][ Snake[i].y ] = '#'; //移動後要置爲'#'蛇身 } } void Check_Border() //檢查蛇頭是否越界 { if(Snake[0].x < 0 || Snake[0].x >= H || Snake[0].y < 0 || Snake[0].y >= L) over = 1; } void Check_Head(int x, int y) //檢查蛇頭移動後的位置狀況 { if(GameMap[ Snake[0].x ][ Snake[0].y ] == '.') //爲空 GameMap[ Snake[0].x ][ Snake[0].y ] = '@'; else if(GameMap[ Snake[0].x ][ Snake[0].y ] == '*') //爲食物 { GameMap[ Snake[0].x ][ Snake[0].y ] = '@'; Snake[sum].x = x; //新添加的蛇身爲蛇頭後面的那個 Snake[sum].y = y; Snake[sum].now = Snake[0].now; GameMap[ Snake[sum].x ][ Snake[sum].y ] = '#'; sum++; Create_Food(); //食物吃完了當即再產生一個食物 } else over = 1; }