贪吃蛇-控制台

本文把游戏区域就行编号,第一行从0到WIDTH-1,…… 到HEIGHT-1 到 WIDTH*HEIGHT-1(二维数组)。并用trace[LEN]数组保存snake移动的轨迹(保存的是数值,数值就能表现出所在的行和列),(trace[0]始终为snake的头部),根据display()函数绘图,延时,在绘图,达到刷新屏幕的效果。

贪吃蛇-控制台

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>

#define HEIGHT 10
#define WIDTH 10
#define LEN HEIGHT*WIDTH/2
#define SPEED 800

enum moveState{
    UP = -1*WIDTH, DOWN = WIDTH, LEFT = -1, RIGHT = 1
};

int x, y;   /* rand point */
int trace[LEN] = {0};   /* trace the snake */ 
moveState ms = UP;      /* default UP */
int len = 1;    /* snake length */

void display();
void gotoxy(int x, int y);
void automove();
void randpoint();
void gameover();
void keyinput();
int merge();

int main(void)
{
    srand(time(0));
    x = rand()%WIDTH;
    while((y = rand()%HEIGHT) == 0)     // y != 0
        ;
    trace[0] = y*WIDTH + x;
    display();
    randpoint();
    while(1){
        keyinput();
    }
    return 0;
}

/* goto (x, y) point oisition */
void gotoxy(int x, int y)
{
    HANDLE hOut;
    COORD pos={x, y};   // windows API, 光标位置 
    hOut=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hOut,pos);     // set

  //SetConsoleTextAttribute(hOut,0x00|0x05);
}

void display()
{
    int i, j;
    gotoxy(0,0);

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x00|0x05);    // API, set color
    /* display the bound */
    for(i = 0; i < HEIGHT+2; i++){
        for(j = 0; j < WIDTH+2; j++){
            if(i == 0 || i == HEIGHT+1 || j == 0 || j == WIDTH+1)
                printf("□");   /* 2 char */
            else
                printf("  ");
        }
        printf("\n");
    }

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x00|0x06);    // API, set color

    gotoxy(WIDTH*2+4, HEIGHT/3);
    printf("\t ↑ ← ↓ → space");
    gotoxy(WIDTH*2+4, HEIGHT/5*3);
    printf("\t score: %d", len*100);

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x00|0x07);    // API, set color
    /* display the rand point */
    gotoxy(2*x+2, y+1);     // include bound
    printf("■");        // 2 char

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x00|0x02);    // API, set color
    /* display the snake */
    for(i = 0; i < len; i++){
        gotoxy(trace[i]%WIDTH*2+2, trace[i]/WIDTH+1);
        printf("■");
    }
    Sleep(SPEED);     // delay SPEED ms 
}

/* 根据ms的方向进行移位,保存新的路径 */
void automove()
{
    int i;

    /* shift bit  */
    for(i = len-1; i > 0; i--){
        trace[i] = trace[i-1];
    }
    trace[i] += ms;     /* i = 0 */ 
}

/* 合并新的随机点 */
int merge()
{
    int i;
    int temp = y*WIDTH + x;
    if(temp == trace[0]){
        /* shift bit  */
        len++;
        for(i = len-1; i > 0; i--){
            trace[i] = trace[i-1];
        }
        trace[i] += ms;         /* i = 0 */
        return 1;
    }

    return 0;
}

/* born randpoint */
void randpoint()
{
    int i;
    while(1){
        x = rand()%WIDTH;
        y = rand()%HEIGHT;
        for(i = 0; i < len; i++)
            if(y*WIDTH+x == trace[i])
                break;
        if(i == len)
            return;
    }
}

void keyinput()
{
    int i;
    while(!kbhit()){    // no keyboard input
        automove();
        if(trace[0] < 1 || trace[0] > HEIGHT*WIDTH || trace[0]%WIDTH == WIDTH-1 && ms == LEFT 
                    || trace[0]%WIDTH == 0 && ms == RIGHT)
            gameover();
        for(i = 1; i < len; i++)
            if(trace[0] == trace[i])
                gameover();
        if(merge() == 1)
            randpoint();
        display();
    }

    int key = getch();      //获取键盘输入 
    if(key == 27)
        exit(0);
    else if(key == ' '){    // space for Pause
        while(getch() != ' ')
            ;
    }
    else if(key == 0xE0){   //方向键会产生2个字符 
        key = getch();
        switch(key){
            case 0x48:  //up
                ms = UP;        
                break;
            case 0x4B:  //left
                ms = LEFT;
                break;
            case 0x4D:  //right
                ms = RIGHT;
                break;
            case 0x50:  //down
                ms = DOWN;
                break;
        }
    }

    automove();
    /* judge out of the bound */
    if(trace[0] < 1 || trace[0] > HEIGHT*WIDTH || trace[0]%WIDTH == WIDTH-1 && ms == LEFT 
                    || trace[0]%WIDTH == 0 && ms == RIGHT)
        gameover();
    /* judge head touched the body */
    for(i = 1; i < len; i++)
        if(trace[0] == trace[i])
            gameover();
    if(merge() == 1)
        randpoint();
    display();
}

void gameover()
{
    gotoxy(WIDTH/2, HEIGHT/2);
    printf("you are lost!\n");
    gotoxy(0, HEIGHT+2);
    exit(0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值