算法参照Perl字符贪吃蛇,源码:
#include <stdio.h> #include <windows.h> #define WIDTH 12 // 宽 #define HEIGHT 8 // 高 #define DEBUG 0 const char FENCE ='*'; // 栅栏 const char HEAD ='@'; // 蛇头 const char BODY ='#'; // 蛇身 const char FOOD ='O'; // 食物 const char BLANK =' '; // 空白 char arr[HEIGHT][WIDTH]; struct Snake{ int y,x; }snake[WIDTH*HEIGHT]; // 结构体,保存坐标点 int len=0,food=0,key=0,score=0,alive=1,direct=4,speed=1,full=(WIDTH-2)*(HEIGHT-2); // 长度、食物、按键、总分、存活、方向、速度 int uldr[5][2]={{},{-1,0},{0,-1},{1,0},{0,1}}; // 上、左、下、右 void init(){ // 初始化游戏地图 int y=0,x=0,start_pos=HEIGHT/2; for(y=0;y<HEIGHT;y++) for(x=0;x<WIDTH;x++) if( y == 0 || y == HEIGHT-1 || x == 0 || x == WIDTH-1 ){ arr[y][x] = FENCE; } else{ arr[y][x] = BLANK; } snake[0].y=start_pos; snake[0].x=3; len++; snake[1].y=start_pos; snake[1].x=2; len++; arr[ snake[0].y ][ snake[0].x ] = HEAD ; arr[ snake[1].y ][ snake[1].x ] = BODY ; } void show(){ int y,x; if(!DEBUG)system("cls"); printf("your score:%d ",score); printf("current speed:%d ",speed); for(y=0 ; y<HEIGHT ; y++ ){ for(x=0 ; x<WIDTH ; x++ ) printf("%c",arr[y][x]); printf(" "); } } void make_food(){ int rx,ry; while(!food){ rx = rand()%WIDTH; ry = rand()%HEIGHT; if( arr[ry][rx] == BLANK ){ arr[ry][rx]=FOOD; food=1; break; } } } void move(){ int cnt=0; if( kbhit()!=0 ){ while( kbhit() != 0)key=getch(); switch(key){ case 'w' : direct=(direct == 3)?3:1;break; case 'a' : direct=(direct == 4)?4:2;break; case 's' : direct=(direct == 1)?1:3;break; case 'd' : direct=(direct == 2)?2:4;break; default : direct; } // 禁止反向移动 } len++; // 准备将当前位置放在snake数组首部 if(DEBUG)printf("len:%d ",len); for(cnt=len-1;cnt>0;cnt--){ snake[cnt].x=snake[cnt-1].x; snake[cnt].y=snake[cnt-1].y; // 1234 变为 51234 } snake[0].y+=uldr[direct][0]; snake[0].x+=uldr[direct][1]; // 移动蛇头 } void check_head(){ int y=snake[0].y; int x=snake[0].x; int i=0; int cnt=0; if(y < 1 || y > HEIGHT-2 || x < 1 || x > WIDTH-2){ // 是否越界 alive=0; } if( arr[y][x] == BODY ){ // 是否吃到自己 alive=0; } if( arr[y][x] == BLANK){ arr[y][x] = HEAD; } if( arr[y][x] == FOOD ){ // 吃到食物 arr[y][x] = HEAD; score++; len++; food=0; snake[len-1].y=snake[len-2].y; // 蛇尾增加一节蛇身 snake[len-1].x=snake[len-2].x; make_food(); } if(DEBUG)printf("len:%d ",len); if(DEBUG){ for(;i<len;i++){ printf("y,x:(%d,%d) ",snake[i].y,snake[i].x); } } arr[ snake[len-1].y ][ snake[len-1].x ]=BLANK; // 先清除蛇尾显示 len--; for(cnt=1;cnt<=len-1;cnt++){ arr[ snake[cnt].y ][ snake[cnt].x ]=BODY; // 蛇身显示 } } void main(){ init(); make_food(); while(alive && len<full){ move(); check_head(); speed=(speed > 9)?9:(score/5+1); if(alive){ show(); Sleep(1000-speed*100); // 多久刷新一次 } } if( len == full){ printf("congratulations! "); } else{ printf("you lose "); } }