关闭

c语言贪吃蛇

标签: c贪吃蛇linux贪吃蛇链表贪吃蛇
169人阅读 评论(0) 收藏 举报
分类:

这个小游戏,无聊时敲得。

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;
}



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:16011次
    • 积分:574
    • 等级:
    • 排名:千里之外
    • 原创:40篇
    • 转载:25篇
    • 译文:0篇
    • 评论:0条
    文章分类