貪吃蛇示例

最近在瞭解ncurses這個字符終端處理庫,使用這個庫寫了一個簡單的貪吃蛇遊戲w,s,a,d控制上下左右,代碼如下:


<code>#include 
#include 
#include 
#include 
#include 
 
 
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));  //seed
 
	Snake* 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); //input
		timeout.tv_sec = 0;
		timeout.tv_usec = 500000; //500ms
		ret = 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 loop
		if((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;
}/<code>


分享到:


相關文章: