贪吃蛇

来源:互联网 发布:flame软件前景 编辑:程序博客网 时间:2024/04/30 09:08

1.最近在了解ncurses这个字符终端处理库,使用这个库写了一个简单的贪吃蛇游戏w,s,a,d控制上下左右,代码如下:


#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <ncurses.h>typedef struct _tagDirect{int x;int y;}Direct;typedef struct _tagSnakeNode{int x;int y;struct _tagSnakeNode* pre;struct _tagSnakeNode* next;}SnakeNode,Snake;static Direct dir;static int fx;static int fy;static int length = 0;static Snake* SnakeInit(){SnakeNode* sn = (SnakeNode*)malloc(sizeof(SnakeNode));if (sn == NULL){return NULL;}memset(sn,0,sizeof(SnakeNode));sn->next = sn->pre = sn;return sn;}//add head pos static int SnakeInsert(Snake* sn,int x,int y){if (sn == NULL){return -1;}SnakeNode* node = (SnakeNode*)malloc(sizeof(SnakeNode));if (node == NULL){return -2;}node->x = x;node->y = y;node->next = sn->next;sn->next->pre = node;sn->next = node;node->pre = sn;return 0;}//del tail pos static int SnakeDelete(Snake* sn){if (sn == NULL){return -1;}SnakeNode* tail = sn->pre;tail->pre->next  = sn;sn->pre = tail->pre;free(tail);tail = NULL;return 0;}static void SnakeDeinit(Snake* sn){if (sn == NULL){return;}SnakeNode* p = sn->next;SnakeNode* tmp = NULL;while(p && p->next != sn){tmp = p;p = p->next;free(tmp);tmp = NULL;}free(sn);sn = NULL;}static void MakeFood(){int x = rand()%COLS;if(x == 0)x = 1;int y = rand()%(LINES-2);if (y == 0)y = 1;move(y,x);printw("O");fx = x;fy = y;}//蛇的每一次前进,在链表的头部增加一个节点,在尾部删除一个节点//如果蛇吃了一个食物,就不用删除节点了static int SnakeShow(Snake* sn){int isEat = 0;if (sn == NULL){return -1;}move(fy,fx);printw("O");if(sn->next->x+dir.x == COLS || sn->next->x+dir.x == 0 ||sn->next->y+dir.y == LINES || sn->next->y+dir.y == -1){move(LINES/2,COLS/2);addstr("crash the wall,game over!");refresh();return -2;}//如果蛇头砬到自己的身体,则游戏结束    if('@' == mvinch(sn->next->y+dir.y, sn->next->x+dir.x) )    {    move(LINES/2,COLS/2);    addstr("crash itself,game over!");refresh();    return -3;    }SnakeInsert(sn,sn->next->x+dir.x,sn->next->y+dir.y);if(sn->next->x == fx && sn->next->y == fy){isEat = 1;MakeFood();length++;if(length == 20){move(LINES/2,COLS/2);addstr("you are win!");refresh();return 1;}}if(isEat == 0){move(sn->pre->y,sn->pre->x);printw(" ");SnakeDelete(sn);}move(sn->next->y,sn->next->x);printw("@");refresh();return 0;}static int  UpdateDirect(char ch){if('a' == ch)    {    if(dir.x == 1)    return 0;        dir.x = -1;        dir.y = 0;    }    else if('w' == ch)    {    if(dir.y == 1)    return 0;        dir.x = 0;        dir.y = -1;    }    else if('d' == ch)    {    if(dir.x == -1)    return 0;        dir.x = 1;        dir.y = 0;    }    else if('s' == ch)    {    if(dir.y == -1)    return 0;        dir.x = 0;        dir.y = 1;    }    else if('q' == ch)    {        return 1;    }    return 0;}int main(int argc, char const *argv[]){/* code */char c = 0;int ret = 0;struct timeval timeout;initscr();cbreak();                    //把终端的CBREAK模式打开    noecho();                    //关闭回显    curs_set(0);                //把光标置为不可见    srand(time(NULL));  //seedSnake* sn = SnakeInit();if (sn == NULL){return -1;}SnakeInsert(sn,10,20);MakeFood();dir.x = 1;dir.y = 0;for(;;){fd_set rdfds;FD_ZERO(&rdfds);FD_SET(0,&rdfds); //inputtimeout.tv_sec = 0;timeout.tv_usec = 500000; //500msret = select(1,&rdfds,NULL,NULL,&timeout);if (ret < 0){continue;}if(FD_ISSET(0,&rdfds)){fread(&c,1,1,stdin);// fprintf(stderr,"have %02x\n",c);if(UpdateDirect(c) == 1){move(LINES/2,COLS/2);    addstr("quit!");refresh();break;}}// main loopif((ret = SnakeShow(sn)) < 0)break;if(ret == 1)break;move(0,(COLS-strlen("SCORE:XX"))/2);printw("SCORE:%02d",length);refresh();}SnakeDeinit(sn);getch();endwin();return 0;}


0 0