UNIX_C 链表贪吃蛇游戏_吃苹果可生长——<.c 函数实现文件>

UNIX_C  链表实现贪吃蛇游戏_吃苹果可生长(.c 函数实现文件)


 UNIX_C 链表贪吃蛇游戏_吃苹果可生长代码——<.c 测试文件文件>

UNIX_C 链表贪吃蛇游戏_吃苹果可生长代码——<.h头文件>



//链表实现可生长贪吃蛇游戏
#include "snake_me.h"

//设置苹果开始的随机位置
NOTE * init_apple( NOTE * p_apple )
{
	p_apple->row = (rand()%(SIZE_ROW-2)) +1;	//随机坐标
	p_apple->col = (rand()%(SIZE_COL-2)) +1;
	p_apple->mark = APPLE;				//标记为蛇

	return p_apple;
}

//蛇身动态分配内存生成
SNAKE * init_note(void)
{
	SNAKE * pnote_temp = (SNAKE *) malloc ( sizeof(SNAKE) );
	if( !pnote_temp )
	{
		perror("Malloc");
		return NULL;
	}

	pnote_temp->note.mark = MID;

	pnote_temp->note.row = 0;
	pnote_temp->note.col = 0;

	pnote_temp->p_next = NULL;
	pnote_temp->p_pre = NULL;

	return pnote_temp;
}

//初始化蛇头并设置蛇开始位置
SNAKE * init_snake_head( void )
{
	SNAKE * psnake_head = init_note();	//蛇头

	if(!psnake_head)
	{
		perror("psnake_head or psanke_tail or psnake_flag is NULL");
		return NULL;
	}
	

	//将蛇头默认设置在地图中间
	psnake_head->note.row = SIZE_ROW / 2;
	psnake_head->note.col = SIZE_COL / 2;
	psnake_head->note.mark = HEAD;

	psnake_head->p_next = NULL;
	psnake_head->p_pre = NULL;
	return psnake_head;
}

//初始化蛇尾
SNAKE * init_snake_tail( SNAKE * p_snake )
{
	SNAKE * psnake_head = p_snake;

	SNAKE * psnake_tail = init_note();	//蛇尾

	if(!psnake_head || !psnake_tail )
	{
		perror("psnake_head or psanke_tail or psnake_flag is NULL");
		return NULL;
	}
	
	//将蛇尾坐标放在蛇头后面
	psnake_tail->note.row = psnake_head->note.row - 1;
	psnake_tail->note.col = psnake_head->note.col;
	psnake_tail->note.mark = TAIL;
	
	//将蛇尾挂在蛇头链表后面
	psnake_head->p_next = psnake_tail;
	psnake_tail->p_pre = psnake_head;

	psnake_tail->p_next = NULL;
	psnake_head->p_pre = NULL;

	return psnake_head;
}

//蛇身插入一节
SNAKE * insert_add_snake(const NOTE * apple, SNAKE * p_snake )
{
	SNAKE * psnake_temp = init_note();

	if(!psnake_temp)
	{
		perror("Psnake_mid ERROR");
		return NULL;
	}
	
	psnake_temp->note.mark = HEAD;	
	psnake_temp->note.col = apple->col;
	psnake_temp->note.row = apple->row;
	
	p_snake->note.mark = MID;
	psnake_temp->p_pre = NULL;
	psnake_temp->p_next = p_snake;
	p_snake->p_pre = psnake_temp;


	return psnake_temp;
}

//判断蛇和苹果位置是否重叠返回1为苹果和蛇有重叠,返回-1为不重叠
int link_overlap( const NOTE * p_apple, const SNAKE * p_snake)
{
	const SNAKE * psnake_i = NULL;
	
	//printf("%d:%d\t", p_apple->row, p_apple->col);
	
	int i = 0;
	for( psnake_i = p_snake; psnake_i != NULL; psnake_i = psnake_i->p_next )
	{
	//	printf("%d:%d-",i++, psnake_i->note.row, psnake_i->note.col);

		if(p_apple->row == psnake_i->note.row && p_apple->col == psnake_i->note.col)
		{
			return 1;
		}

	}

	return -1;
}

//判断蛇头是否和苹果的位置相同,相同表示吃到了苹果,1返回重叠,-1为不重叠
int link_overlap_head( const NOTE * p_apple, const SNAKE * p_snake)
{

	if(p_apple->row == p_snake->note.row && p_apple->col == p_snake->note.col)
	{
		return 1;
	}

	return -1;
}


//显示地图内容
void show_map(const NOTE * p_apple, const SNAKE * p_snake )
{
        int r = 0;
        int c = 0;
		int flag = 0;

        for( r = 0; r < SIZE_ROW; r++)
        {
                for( c = 0; c<SIZE_COL; c++)
                {
						flag = 0;
                        if( 0 == r || SIZE_ROW-1 == r )     //墙
                        {
                                printf("%c", PIC_ROW_WALL);
								continue;
                        }
                       
						 if( 0 == c || SIZE_COL-1 == c )     //墙
                        {
                                printf("%c", PIC_COL_WALL);
								continue;
                        }
                       
						 if(r == p_apple->row && c == p_apple->col && p_apple->mark == APPLE )
                        {
                                printf("%c", PIC_APPLE);        //苹果
								continue;
                        }

                       const SNAKE * psnake_i = NULL;
                        //遍历蛇比较坐标
                        for( psnake_i = p_snake; psnake_i != NULL; psnake_i = psnake_i->p_next )
                        {
                            if( r == psnake_i->note.row && c == psnake_i->note.col )
                            {
								flag = 1;		//标记位

                                if( psnake_i->note.mark == HEAD)    //蛇头
                                {
                                        printf("%c", PIC_HEAD);
										break;
                                }
                                if(psnake_i->note.mark == TAIL)    //蛇尾
                                {
                                        printf("%c", PIC_TAIL);
										break;
                                }
                                if(psnake_i->note.mark == MID)     //蛇尾
                                {
                                        printf("%c", PIC_MID);
										break;
                                }
                            }
						
                        }
					
						if(0 == flag)
						{
							printf(" ");
						}
                }

				printf("\n");
        }
}

//释放动态申请的内存
void  dele_init_snake( SNAKE * p_snake )
{
        SNAKE *  psnake_i =  p_snake;

        while( psnake_i != NULL )
        {
            SNAKE * psnake_temp = psnake_i->p_next;
            free(psnake_i);
            psnake_i = psnake_temp;
			psnake_temp = NULL;
        }
}
//UNIX中自动获取键盘字符,而不用敲击回车键读取字符
static int linux_getch(void)
{

	struct termios term_old;

	ioctl( STDIN_FILENO, TCGETS, &term_old );

	struct termios term_new = term_old;

	term_new.c_lflag &= ~( ECHO | ICANON );

	ioctl( STDIN_FILENO, TCSETS, &term_new );

	int ch = getchar();

	ioctl(STDIN_FILENO, TCSETS, &term_old);

	return ch;

}

//检查蛇头是否与蛇身体发生触碰, 如有则游戏结束
 void inspect_snake( const SNAKE * p_snake )
{
	const SNAKE * psnake_head = p_snake;
	const SNAKE * psnake_i = NULL;

	for ( psnake_i = p_snake->p_next; psnake_i != NULL; psnake_i = psnake_i->p_next)
	{
		//判断蛇头坐标是否与蛇身坐标有重合
		if(psnake_i->note.row == psnake_head->note.row && psnake_i->note.col == psnake_head->note.col)
		{
			printf("\n\n\t蛇咬到自己,游戏结束!!!\n");
			exit(-1);
		}
	}
}

//移动蛇
SNAKE * move_snake( SNAKE * p_snake )
{

	NOTE pnote_temp = p_snake->note;
//	SNAKE * psnake_temp = p_snake;

	printf("\n\n");
	printf("\t上 %c\n", U);
	printf("左 %c\t\t右 %c\n", L, R);
	printf("\t下 %c\n", D);

	printf("请输入蛇移动的方向:");
	int ch = linux_getch();		//获取方向并不用按回车键

	if( U == ch || (U-'a'+'A') == ch )
	{
		pnote_temp.row--;
	}
	else if( D == ch || (D-'a'+'A') == ch )
	{
		pnote_temp.row++;
	}
	else if( L == ch || (L-'a'+'A') == ch )
	{
		pnote_temp.col--;
	}
	else if( R == ch || (R-'a'+'A') == ch )
	{
		pnote_temp.col++;
	}

	if(pnote_temp.row == 0 || pnote_temp.row == SIZE_ROW-1 
		|| pnote_temp.col == 0 || pnote_temp.col == SIZE_COL-1 )
	{
		printf("\n\n\t蛇触碰墙壁,游戏结束!\n");
		exit(-1);
	}	
		
	SNAKE * psnake_i = NULL;

	for( psnake_i = p_snake; psnake_i != NULL; psnake_i = psnake_i->p_next )
	{
		NOTE  temp = psnake_i->note;

		psnake_i->note.row = pnote_temp.row;	//把新坐标赋值给蛇头
		psnake_i->note.col = pnote_temp.col;
		
		pnote_temp = temp;		//把蛇头原坐标赋值给下一个坐标
	}	
	
	return p_snake;
}

//


















注:此代码为自己初学而写,如有不足或错误初请评论处提出并指教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值