#include<stdio.h>#include<windows.h>#include<time.h>#include<stdlib.h>#include<conio.h>#define N 21FILE *fp;int S;void boundary(void);//開始介面 void end(void); //結束 void gotoxy(int x,int y)//位置函數{COORD pos;pos.X=x;pos.Y=y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);}void color(int a)//顏色函數{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);}void init(int food[2])//初始化函數(初始化圍牆、顯示資訊、蘋果){system("cls");int i,j;//初始化圍牆int wall[N+2][N+2]={{0}};//初始化圍牆的二維數組 for(i=1;i<=N;i++){for(j=1;j<=N;j++)wall[i][j]=1;}color(10);for(i=0;i<N+2;i++)//畵圍牆 {for(j=0;j<N+2;j++){if(wall[i][j])printf(" ");else printf("#") ;} printf("\n") ; }gotoxy(N+3,3);//顯示資訊color(14);printf("\t\t按a,b,c,d改變方向\n");gotoxy(N+3,1);color(14);printf("\t\t按任意鍵暫停,按1返回,按2退出\n");gotoxy(N+5,3);color(14);printf("score:\n");food[0]=rand()%N+1;//隨機出現食物 food[1]=rand()%N+1;gotoxy(food[0],food[1]);color(12);printf("*\n");}void play()//具體玩的過程 {system("cls");int i,j;int** snake=NULL;//定義蛇的二維指標 int food[2];//食物的數組,food[0]代表橫座標,food[1]代表縱座標 int score=0;//為得分 int tail[2];//此數組為了記錄蛇的頭的座標 int node=3;//蛇的節數 char ch='p';srand((unsigned)time(NULL));//隨機數發生器的初始化函數 init(food); snake=(int**)realloc(snake,sizeof(int*)*node);//改變snake所指記憶體地區的大小為node長度 for(i=0;i<node;i++)snake[i]=(int*)malloc(sizeof(int)*2);for(i=0;i<node;i++)//初始化蛇的長度 {snake[i][0]=N/2;snake[i][1]=N/2+i;gotoxy(snake[i][0],snake[i][1]);color(14);printf("*\n");}while(1)//進入訊息迴圈{gotoxy(5,0);color(10);printf("#");gotoxy(0,5);color(10);printf("#");gotoxy(0,7);color(10);printf("#");gotoxy(0,9);color(10);printf("#");tail[0]=snake[node-1][0];//將蛇的後一節座標賦給tail數組 tail[1]=snake[node-1][1];gotoxy(tail[0],tail[1]);color(0);printf(" ");for(i=node-1;i>0;i--)//蛇想前移動的關鍵演算法,後一節的佔據前一節的地址座標 {snake[i][0]=snake[i-1][0];snake[i][1]=snake[i-1][1];gotoxy(snake[i][0],snake[i][1]);color(14);printf("*\n");}if(kbhit())//捕捉輸入資訊 {gotoxy(0,N+2);ch=getche();}switch(ch){case 'w':snake[0][1]--;break;case 's':snake[0][1]++;break;case 'a':snake[0][0]--;break;case 'd':snake[0][0]++;break;case '1':boundary() ;break;case '2':end();break;default: break;}gotoxy(snake[0][0],snake[0][1]);color(14);printf("*\n");Sleep(abs(200-0.5*score));//使隨著分數的增長蛇的移動速度越來越快 if(snake[0][0]==food[0]&&snake[0][1]==food[1])//吃掉食物後蛇分數加1,蛇長加1{score++;//分數增加 S=score;node++;//節數增加 snake=(int**)realloc(snake,sizeof(int*)*node);snake[node-1]=(int*)malloc(sizeof(int)*2);food[0]=rand()%N+1;//產生隨機數且要在圍牆內部 food[1]=rand()%N+1;gotoxy(food[0],food[1]);color(12);printf("*\n");gotoxy(N+12,3);color(14);printf("%d\n",score);//輸出得分 }if(snake[0][1]==0||snake[0][1]==N+1||snake[0][0]==0||snake[0][0]==N+1)//撞到圍牆後失敗{gotoxy(N/2,N/2);color(30);printf("GAME OVER!!!\n");for(i=0;i<node;i++)free(snake[i]);Sleep(INFINITE);exit(0);}} //從蛇的第四節開始判斷是否撞到自己,因為蛇頭為兩節,第三節不可能拐過來 for (i=3; i<node; i++) { for(j=0;j<node;j++) { if (snake[i][0]==snake[j][0] && snake[i][1]==snake[j][1]) { gotoxy(N/2,N/2);color(30);printf("GAME OVER!!!\n");for(i=0;i<node;i++)free(snake[i]);Sleep(INFINITE);exit(0);; } } } }void end()//結束函數 { system("cls"); system("cls");printf("EXIT!!!\n");}void grade()//成績記錄函數{system("cls");int i=0; char s;if( (fp=fopen("f:\\貪吃蛇\\貪吃蛇.txt","ar") )==NULL)//開啟檔案 { printf("\nCannot open file!\n"); exit(0); } if(i<S)i=S;color(14);fwrite(&i,sizeof(i),1,fp); fclose(fp);printf("最高的分為:%d\n\n",i); printf("\t按1返回\n\n");printf("\t按2退出\n\n");s=getche();switch(s){case '1':boundary();break;case '2': end();break;} } void boundary()//開始介面 {system("cls");char s;color(14);printf("\t\t歡迎來玩!!\n\n");printf("\t\t1:開始\n\n");printf("\t\t2:查看成績\n\n");printf("\t\t3:退出\n\n");printf("\t\t請選擇:");s=getche();switch(s){case '1': play();break;case '2': grade();break;case '3': end();break;}}int main(){boundary();getchar();return 0;}