c語言貪喫蛇

這個小遊戲,無聊時敲得。

1.運行環境ubuntu版本c89下,基本能兼容。

2.實現了非堵塞的輸入。

3.每次喫一個,都會變長

4.採用鏈表完成

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termio.h>

#define TTY_PATH "/dev/tty"
#define STTY_ON  "stty raw -echo -F"
#define STTY_OFF "stty -raw echo -F"

char map[10][10];
char direct = 'a';
typedef struct node 
{
	int x;
	int y;	
	struct node* next;
}Node;
typedef struct food
{
	int x;
	int y;
}Food;

Node* head;
Food* food;
void init_map()//初始化地圖
{
	int i,j;
	for(i = 0; i < 10; i++)
		for(j = 0; j < 10; j++)
		{
			if(i==0||i==9||j==0||j==9)
			{
				map[i][j] = '*';
			}
			else
			{
				map[i][j] = ' ';
			}
		}
}

void print()//打印地圖
{
	int i,j;
	for(i = 0; i < 10; i++)
	{
		for(j = 0; j < 10; j++)
		{
			printf(" %c ",map[i][j]);
		}
		printf("\n");
	}
}

void init_snake(int n)//初始化n個長度的貪喫蛇
{
	int i = 0;
	Node* pre;
	Node* node;
	node = (Node*)malloc(sizeof(Node));
	node -> x = 4;
	node -> y = 5;
	node -> next = NULL;
	map[node->x][node->y] = '*';
	pre = node;
	head = pre;
	for( i = 1; i < n; i++)
	{
		Node* node_next;
		node_next = (Node*)malloc(sizeof(Node));
		node_next -> x = 4;
		node_next -> y = i+5;
		node_next -> next = NULL;
		map[node_next->x][node_next->y] = '*';
		pre -> next = node_next;
		pre = pre -> next;
	}
}
void init_food()//初始化食物
{
	if(food == NULL)
	{
		Food* f = (Food*)malloc(sizeof(Food));
		food=f;
	}
	food -> x = rand()%8 + 1;
	food -> y = rand()%8 + 1;
	if(map[food->x][food->y] == '*')
		init_food();
	else
		map[food->x][food->y]='@';
}

void eat_food(int x, int y)//喫掉食物後,生成一個新的食物
{
	Node* pre;
	Node* add_node = (Node*)malloc(sizeof(Node));
	add_node -> x = x;
	add_node -> y = y;
	add_node -> next = NULL;
	map[x][y] = '*';
	pre = head;
	while( pre->next )
		pre = pre -> next;

	pre -> next = add_node;

}
int is_over(int x,int y)//判斷是否撞牆,撞尾
{
	if(map[x][y] == '*')
	{
		return 1;
	}
	return 0;
}
void gameover()//遊戲結算,清空動態分配空間
{
	Node *pre, *last;
	pre = last = head;
	while (pre)
	{
		pre = pre -> next;
		free(last);
		last = pre;
	}
	free(food);
	food = NULL;
	head = NULL;
}
void move(char ch)//移動
{

	if(direct == ch)
		return;
	if(ch == 'a'|| ch=='s'|| ch=='d' || ch=='w')
		if( !((direct=='a' && ch=='d')||
		(direct=='d' && ch=='a')||
		(direct=='s' && ch=='w')||
		(direct=='w' && ch=='s')))
		direct = ch;

	if( !head )
		exit(-1);
	
	Node *pre,*last;
	pre = head;
	int is_eat = 0;
	int last_x;
	int last_y;
	int x1 = pre -> x;
	int y1 = pre -> y;
	
	switch(direct)
	{
		case 'a':	
			y1--;
			break;
		case 'w':
			x1--;
			break;
		case 's':
			x1++;
			break;
		case 'd':
			y1++;
			break;
	}
	if(is_over(x1,y1))
	{
		gameover();
		printf("game over!!!!!\n");
		exit(0);
	}
	if(map[x1][y1] == '@')
	{
		is_eat = 1;
		init_food();
	}
	map[x1][y1] = '*';

	int x2 = pre -> x;
	int y2 = pre -> y;
	
	while( pre )//通過記錄兩個點,實現貪喫蛇移動
	{
		pre -> x = x1;
		pre -> y = y1;
		if(!pre->next)
		{
			last_x = x2;
			last_y = y2;
			map[x2][y2] = ' ';
			break;
		}
		pre = pre -> next;

		x1 = pre -> x;
		y1 = pre -> y;

		pre -> x = x2;
		pre -> y = y2;

		if(!pre->next)
		{
			last_x = x1;
			last_y = y1;
			map[x1][y1] = ' ';
			break;
		}
		x2 = pre -> next -> x;
		y2 = pre -> next -> y;
		pre = pre -> next;
	}
	if(is_eat)
		eat_food( last_x , last_y);
}


char in_direct()//非堵塞鍵盤輸入
{
	fd_set fd;
	struct timeval tv;
	char ch;
	FD_ZERO(&fd);
	FD_SET(0, &fd);
	tv.tv_sec = 0;
	tv.tv_usec = 10;
	if(select(1, &fd ,NULL, NULL, &tv) > 0)
	{
		ch = getchar(); 
	}
	return ch;
}


int main()
{
	srand(time(NULL));
	init_map();
	init_snake(3);
	init_food();
	int i = 0;
	char ch;
	for(i = 0;; i++)
	{
		usleep(500000);
		system("clear");
		system(STTY_ON TTY_PATH);
		ch = in_direct();
		system(STTY_OFF TTY_PATH);
		move(ch);
		print();
		fflush(stdout);
	}

	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章