console下纯字符实现的贪吃蛇

来源:互联网 发布:国密算法是否可解密 编辑:程序博客网 时间:2024/05/22 12:33

最近简直超级无聊……


code blocks win7 64编译运行无问题,应该其他编译器也不会有问题。

w:上

s:下

a:左

d:右

CS标准方向控制,AK47和M4这种高级货是没有滴……


废话不多说,直接上代码。


#include "stdio.h"#include "stdlib.h"#include "windows.h"#include "time.h"// ----------------------------------------------------------------------------//                 definition// ----------------------------------------------------------------------------// basic char node#define _FOOD                   "#"#define _SNAKE_NODE             "O"#define _SNAKE_END              "+"#define _SNAKE_HEAD             "@"#define _MAP_NODE               " "#define _MAP_EDGE               "O"// area pos and range#define _AREA_X_OFFSET           10#define _AREA_Y_OFFSET           5#define _AREA_X_LINE_MAX         30         // max line num in x direction#define _AREA_Y_LINE_MAX         20         // max line num in y direction#define _SNAKE_LENGTH_MAX        30// key val defintion#define _KEY_UP             'w'#define _KEY_DOWN           's'#define _KEY_LEFT           'a'#define _KEY_RIGHT          'd'// default snake speed#define _DEFAULT_SNAKE_SPEED  300             // 1 step per second// ----------------------------------------------------------------------------//                 type// ----------------------------------------------------------------------------// basic typetypedef unsigned char     BYTE;typedef unsigned short    WORD;typedef unsigned long     DWORD;typedef unsigned char  *  PBYTE;typedef unsigned short *  PWORD;typedef unsigned long  *  PDWORD;// element typetypedef enum{    _ET_MAP_NODE,    _ET_MAP_EDGE,    _ET_FOOD,    _ET_SNAKE_HEAD,    _ET_SNAKE_NODE,    _ET_SNAKE_END}E_ET;// snake node typetypedef enum{    _ESNT_HEAD = _ET_SNAKE_HEAD,    _ESNT_NODE = _ET_SNAKE_NODE,    _ESNT_END  = _ET_SNAKE_END}E_SNT;// node postypedef struct{    BYTE by_x;    BYTE by_y;}T_Pos, *PT_Pos;// snake nodetypedef struct{    E_SNT e_type;    T_Pos t_pos;    //BOOL  b_valid;}T_Snake_Node;// directiontypedef enum{    _UP,    _DOWN,    _LEFT,    _RIGHT}E_DRCT;// snaketypedef struct{    DWORD        dw_speed;    E_DRCT       e_direction;    BYTE         by_node_num;    T_Snake_Node at_node[_SNAKE_LENGTH_MAX];}T_Snake;// foodtypedef struct{    BOOL b_eaten;    T_Pos t_pos;}T_Food;// key typetypedef enum{    _E_KT_NONE,    _E_KT_UP,    _E_KT_DOWN,    _E_KT_LEFT,    _E_KT_RIGHT,    _E_KT_SIZE}E_KEY_TYPE;// ----------------------------------------------------------------------------//                 local para// ----------------------------------------------------------------------------// range bufferE_ET l_ae_area[_AREA_Y_LINE_MAX][_AREA_X_LINE_MAX];// snakeT_Snake l_t_snake;BOOL    l_b_key_lock = FALSE;T_Food   l_t_food = {.b_eaten = TRUE};// ----------------------------------------------------------------------------//                 function// ----------------------------------------------------------------------------// ------------------------------------// pos jump// ------------------------------------void Pos_Jump(int x, int y){    COORD  pos  = {_AREA_X_OFFSET + x, _AREA_Y_OFFSET + y};    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hOut, pos);}// ------------------------------------// draw rect element// ------------------------------------void Rect_Elem_Draw(E_ET e_et){    switch(e_et)    {    case _ET_FOOD:        printf(_FOOD);        break;    case _ET_SNAKE_NODE:        printf(_SNAKE_NODE);        break;    case _ET_SNAKE_HEAD:        printf(_SNAKE_HEAD);        break;    case _ET_SNAKE_END:        printf(_SNAKE_END);        break;    case _ET_MAP_EDGE:        printf(_MAP_EDGE);        break;    case _ET_MAP_NODE:    default:        printf(_MAP_NODE);        break;    }}// ------------------------------------// draw map// ------------------------------------void Area_Refresh( void ){    BYTE i, j, k;    // make Y offset    for(i=0 ; i<_AREA_Y_OFFSET ; i++)    {        printf("\r\n");    }    // refresh rect line by line    for(i=0 ; i<_AREA_Y_LINE_MAX ; i++)    {        // make X offset        for(k=0 ; k<_AREA_X_OFFSET ; k++)        {            printf(" ");        }        // draw line        for(j=0 ; j<_AREA_X_LINE_MAX ; j++)        {            Rect_Elem_Draw(l_ae_area[i][j]);        }        printf("\r\n");    }}// ------------------------------------// snake init// ------------------------------------void Snake_Init(){    l_t_snake.dw_speed              = _DEFAULT_SNAKE_SPEED;    l_t_snake.e_direction           = _RIGHT;    l_t_snake.by_node_num           = 3;    //l_t_snake.at_node[0].b_valid    = TRUE;    l_t_snake.at_node[0].e_type     = _ESNT_END;    l_t_snake.at_node[0].t_pos.by_x = 2;    l_t_snake.at_node[0].t_pos.by_y = 1;    //l_t_snake.at_node[0].b_valid    = TRUE;    l_t_snake.at_node[1].e_type     = _ESNT_NODE;    l_t_snake.at_node[1].t_pos.by_x = 2;    l_t_snake.at_node[1].t_pos.by_y = 2;    //l_t_snake.at_node[0].b_valid    = TRUE;    l_t_snake.at_node[2].e_type     = _ESNT_HEAD;    l_t_snake.at_node[2].t_pos.by_x = 2;    l_t_snake.at_node[2].t_pos.by_y = 3;}// ------------------------------------// area init// notice: should be called after snake//         init// ------------------------------------void Area_Init(){    BYTE by_i, by_j;    // set area default value    for(by_i=0 ; by_i<_AREA_X_LINE_MAX ; by_i++)    {        for(by_j=0 ; by_j<_AREA_Y_LINE_MAX ; by_j++)        {            l_ae_area[by_i][by_j] = _ET_MAP_NODE;        }    }    // set area edge value    for(by_i=0 ; by_i<_AREA_X_LINE_MAX ; by_i++)    {        l_ae_area[0][by_i]                    = _ET_MAP_EDGE;        l_ae_area[_AREA_Y_LINE_MAX - 1][by_i] = _ET_MAP_EDGE;    }    for(by_j=0 ; by_j<_AREA_Y_LINE_MAX ; by_j++)    {        l_ae_area[by_j][0]                    = _ET_MAP_EDGE;        l_ae_area[by_j][_AREA_X_LINE_MAX - 1] = _ET_MAP_EDGE;    }}void Show_Game_Over(){    Pos_Jump(_AREA_X_LINE_MAX/4, _AREA_X_LINE_MAX+1);    printf("Game Over!");    Pos_Jump(_AREA_X_LINE_MAX/4, _AREA_X_LINE_MAX+2);    printf("Press Anykey to Exit...");}BOOL Snake_Is_Dead(){    T_Pos t_head_pos = l_t_snake.at_node[l_t_snake.by_node_num-1].t_pos;    BYTE i;    // touch area ----------------    if(   t_head_pos.by_x == 0       || t_head_pos.by_x >= _AREA_X_LINE_MAX-1       || t_head_pos.by_y == 0       || t_head_pos.by_y >= _AREA_Y_LINE_MAX-1)    {        Show_Game_Over();        return TRUE;    }    // touch body --------    for(i=0 ; i<l_t_snake.by_node_num-1 ; i++)    {        if(  t_head_pos.by_x == l_t_snake.at_node[i].t_pos.by_x           &&t_head_pos.by_y == l_t_snake.at_node[i].t_pos.by_y)        {            return TRUE;        }    }    return FALSE;}// ------------------------------------// on snake moving// ------------------------------------On_Snake_Moving(){    static DWORD dw_time_cur  = 0;    static DWORD dw_time_last = 0;    BYTE         by_i = 0;    T_Pos        t_end_pos_before_moving;    BYTE by_neck_index, by_head_index;    // check speed    dw_time_cur = GetTickCount();    if(dw_time_cur < dw_time_last + l_t_snake.dw_speed)    {        return;    }    l_b_key_lock = FALSE;    dw_time_last = dw_time_cur;    // move    by_head_index = l_t_snake.by_node_num - 1;    by_neck_index = l_t_snake.by_node_num - 2;    if(  l_t_snake.at_node[by_neck_index].t_pos.by_x != l_t_snake.at_node[by_head_index].t_pos.by_x       ||l_t_snake.at_node[by_neck_index].t_pos.by_y != l_t_snake.at_node[by_head_index].t_pos.by_y) // last step not eat food    {        t_end_pos_before_moving = l_t_snake.at_node[0].t_pos;        for(by_i=1 ; by_i<l_t_snake.by_node_num ; by_i++)        {            l_t_snake.at_node[by_i - 1].t_pos = l_t_snake.at_node[by_i].t_pos;        }        // refresh snake        Pos_Jump(t_end_pos_before_moving.by_x,                 t_end_pos_before_moving.by_y);        Rect_Elem_Draw(_ET_MAP_NODE);    }    switch(l_t_snake.e_direction)    {    case _UP:        l_t_snake.at_node[by_head_index].t_pos.by_y--;        break;    case _DOWN:        l_t_snake.at_node[by_head_index].t_pos.by_y++;        break;    case _LEFT:        l_t_snake.at_node[by_head_index].t_pos.by_x--;        break;    case _RIGHT:        l_t_snake.at_node[by_head_index].t_pos.by_x++;        break;    }    for(by_i=0 ; by_i<l_t_snake.by_node_num ; by_i++)    {        Pos_Jump(l_t_snake.at_node[by_i].t_pos.by_x,                 l_t_snake.at_node[by_i].t_pos.by_y);        Rect_Elem_Draw(l_t_snake.at_node[by_i].e_type);    }    // eat food    if(  l_t_snake.at_node[by_head_index].t_pos.by_x == l_t_food.t_pos.by_x       &&l_t_snake.at_node[by_head_index].t_pos.by_y == l_t_food.t_pos.by_y)    {        l_t_snake.at_node[by_head_index+1] = l_t_snake.at_node[by_head_index];        l_t_snake.at_node[by_head_index].e_type = _ESNT_NODE;        l_t_snake.by_node_num++;        l_t_food.b_eaten = TRUE;    }}// ------------------------------------// key detect// ------------------------------------E_KEY_TYPE Key_Detect(){    BYTE       by_key_value;    E_KEY_TYPE e_kt;    if(0 == kbhit())    {        return _E_KT_NONE;    }    by_key_value = (BYTE)(getch());    if(l_b_key_lock)    {        return _E_KT_NONE;    }    switch(by_key_value)    {    case _KEY_UP:        e_kt = _E_KT_UP;        break;    case _KEY_DOWN:        e_kt = _E_KT_DOWN;        break;    case _KEY_LEFT:        e_kt = _E_KT_LEFT;        break;    case _KEY_RIGHT:        e_kt = _E_KT_RIGHT;        break;    default:        e_kt = _E_KT_NONE;        break;    }    return e_kt;}// ------------------------------------// changing snake direction// ------------------------------------void On_Changing_Snake_Drctn(E_KEY_TYPE e_kt){    switch(e_kt)    {    case _E_KT_UP:        if(  (_LEFT  == l_t_snake.e_direction)           ||(_RIGHT == l_t_snake.e_direction))        {            l_t_snake.e_direction = _UP;        }        break;    case _E_KT_DOWN:        if(  (_LEFT  == l_t_snake.e_direction)           ||(_RIGHT == l_t_snake.e_direction))        {            l_t_snake.e_direction = _DOWN;        }        break;    case _E_KT_LEFT:        if(  (_UP    == l_t_snake.e_direction)           ||(_DOWN  == l_t_snake.e_direction))        {            l_t_snake.e_direction = _LEFT;        }        break;    case _E_KT_RIGHT:        if(  (_UP   == l_t_snake.e_direction)           ||(_DOWN == l_t_snake.e_direction))        {            l_t_snake.e_direction = _RIGHT;        }        break;    }}// ------------------------------------// On key down// ------------------------------------void On_Key_Down(){    E_KEY_TYPE e_kt;    e_kt = Key_Detect();    if(_E_KT_NONE != e_kt)    {        // lock keyboard        l_b_key_lock = TRUE;        // changing snake direction        On_Changing_Snake_Drctn(e_kt);        // system operation    }}void Refresh_Food(){    T_Pos t_food_pos;    if(l_t_food.b_eaten)    {        srand(time(0));        t_food_pos.by_x = rand()%(_AREA_X_LINE_MAX-1-1)+1;        t_food_pos.by_y = rand()%(_AREA_Y_LINE_MAX-1-1)+1;        l_t_food.t_pos = t_food_pos;        Pos_Jump(l_t_food.t_pos.by_x, l_t_food.t_pos.by_y);        Rect_Elem_Draw(_ET_FOOD);        l_t_food.b_eaten = FALSE;    }}// ------------------------------------// main// ------------------------------------int main(){    int i_tmp = 0;    Area_Init();    Area_Refresh();    Snake_Init();    while(1)    {        On_Key_Down();        On_Snake_Moving();        Refresh_Food();        if(TRUE == Snake_Is_Dead())        {            break;        }    }    getch();    return 0;}

上张截图


0 0