C字符贪吃蛇

  算法参照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\n",score);
    printf("current speed:%d\n",speed);
    for(y=0 ; y<HEIGHT ; y++ ){
        for(x=0 ; x<WIDTH ; x++ )
            printf("%c",arr[y][x]);
        printf("\n");
    }
}

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\n",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\n",len);
    if(DEBUG){
        for(;i<len;i++){
            printf("y,x:(%d,%d)\n",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!\n");
    }
    else{
        printf("you lose\n");
    }
}    

 

posted @ 2015-06-22 22:16  葡萄不吐皮  阅读(258)  评论(0编辑  收藏  举报