码迷,mamicode.com
首页 > 编程语言 > 详细

C语言之贪吃蛇(conio.h)

时间:2015-02-27 17:08:39      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:

      写完基于Linux中curses库的贪吃蛇,发现只需要用到一个WIN的API(移动光标那个)改写move(int y, int x)函数,然后加上conio.h(一般编译器都会包含这个头文件)的getch(),就可以在Windows系统运行!

      Linux版链接:http://blog.csdn.net/u013351484/article/details/43940803


     游戏规则:


     初始时两条蛇会在中间,一条蛇头是‘@‘,食物是‘$’;另一条蛇头是‘+‘,食物是‘*‘,蛇身都是‘#‘。WASD控制‘+‘蛇方向,方向键控制‘@‘蛇方向,空格键暂停游戏,再按一次继续游戏。每条蛇只能吃自己的食物。撞墙,碰到自己或另一条蛇的身体,吃到另一条蛇的食物都会结束游戏。


     运行环境:windows系统

     编译器:VC++, g++,gcc, VS


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>

#define KEY_UP    72
#define KEY_DOWN  80
#define KEY_LEFT  75
#define KEY_RIGHT 77
#define LINES     23 
#define COLS      70

int dir_y[] = {-1, 1, 0, 0};
int dir_x[] = {0, 0, -1, 1};
int vis[100][100];
int scord;

typedef struct body
{
	int y, x;
	struct body *pre, *sub;
} Body;


typedef struct
{
	Body *head, *tail;
	int DIRECTION;
	int HEAD_X;
	int HEAD_Y;
	int FOOD_X;
	int FOOD_Y;
	char food;
	char H;
} Snake;

int Get_Rand_Number(int k)
{	
	static int first_time = 0;
	if(!first_time){
		first_time = 1;
		srand((unsigned int)(time(NULL)));
	}
	return rand()%k + 1;
}

void move(int y, int x)//移动光标位置
{   
    COORD c;
    c.X=x;   
    c.Y=y; 
    SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c); 
}

void Add(Snake *snake)
{
	Body *s;
	s = (Body *)malloc(sizeof(Body));
	s->y = snake->HEAD_Y;
	s->x = snake->HEAD_X;
	s->pre = NULL;
	s->sub = snake->head;
	snake->head->pre = s;
	snake->head = s;
}

void Free(Body *head)
{
	if(NULL == head) return;
	Free(head->sub);
	free(head);
}

void Initialization(Snake *snake, int y, int x)
{
	snake->DIRECTION = 0;
	int &FOOD_Y = snake->FOOD_Y;
	int &FOOD_X = snake->FOOD_X;
	snake->HEAD_Y = y;
	snake->HEAD_X = x;

	while(1)
	{
		FOOD_Y = Get_Rand_Number(LINES - 3);
		FOOD_X = Get_Rand_Number(COLS - 3);
		if(!vis[FOOD_Y][FOOD_X]){
			vis[FOOD_Y][FOOD_X] = 2;
			break;
		}
	}
	move(FOOD_Y, FOOD_X);
	printf("%c", snake->food);


	snake->head = (Body *)malloc(sizeof(Body));
	snake->head->y = y;
	snake->head->x = x;
	snake->head->pre = snake->head->sub = NULL;
	snake->tail = snake->head;
	move(y, x);
	printf("%c", snake->H);
}

void New_Food(Snake *snake)
{
	scord++;
	int &FOOD_Y = snake->FOOD_Y;
	int &FOOD_X = snake->FOOD_X;
	while(1){
		FOOD_Y = Get_Rand_Number(LINES - 2);
		FOOD_X = Get_Rand_Number(COLS - 2);
		if(!vis[FOOD_Y][FOOD_X]){
			vis[FOOD_Y][FOOD_X] = 2;
			break;
		}
	}
	move(FOOD_Y, FOOD_X);
	printf("%c", snake->food);
}

int Reverse_Direction(Snake *snake, int fy, int fx)
{
	int &HEAD_Y = snake->HEAD_Y;
	int &HEAD_X = snake->HEAD_X;
	Body *&head = snake->head;

	HEAD_Y += dir_y[snake->DIRECTION];
	HEAD_X += dir_x[snake->DIRECTION];

	if(HEAD_Y == fy && HEAD_X == fx) return 1;

	if(head->sub && HEAD_Y == head->sub->y && HEAD_X == head->sub->x){
		if(HEAD_Y == head->y){
			if(HEAD_X > head->x) HEAD_X = head->x - 1;
			else HEAD_X = head->x + 1;
		}
		else{
			if(HEAD_Y > head->y) HEAD_Y = head->y - 1;
			else HEAD_Y = head->y + 1;
		}
	}
	return 0;
}

void Move(Snake *snake)
{
	int &FOOD_Y = snake->FOOD_Y;
	int &FOOD_X = snake->FOOD_X;
	int &HEAD_Y = snake->HEAD_Y;
	int &HEAD_X = snake->HEAD_X;
	Body *&head = snake->head;
	Body *&tail = snake->tail;

	move(HEAD_Y, HEAD_X);
	printf("%c", snake->H);
	vis[HEAD_Y][HEAD_X] = 1;

	if(head->sub){
		move(head->sub->y, head->sub->x);
		printf("#");
	}
		
	if(HEAD_Y == FOOD_Y && HEAD_X == FOOD_X){
		printf("%c", 7);
		New_Food(snake);
	}
	else{
		move(tail->y, tail->x);
		printf(" ");
		vis[tail->y][tail->x] = 0;
		if(tail->pre){
			Body *tmp = tail;
			tail = tail->pre;
			tail->sub = NULL;
			free(tmp);
		}
	
	}
}

void Box()
{
	move(0, 0);
	int x,y;
	for(y=0; y<LINES; y++){
		for(x=0; x<COLS; x++){
			if(0 == x || COLS - 1 == x || 0 == y || LINES - 1 == y){
				printf("#");
				vis[y][x] = 1;
			}
			else printf(" ");
		}
		printf("\n");
	}
}

int Judge_Kill(Snake *snake)
{
	if(1 == vis[snake->HEAD_Y][snake->HEAD_X]) return 1; 
	return 0;
}

int main()
{
	Box();
	Snake snake1, snake2;
	snake1.food = '$';
	snake2.food = '*';
	snake1.H = '@';
	snake2.H = '+';

	int init1_y = LINES / 2;
	int init1_x = COLS / 2 - 1;
	int init2_y = LINES / 2;
	int init2_x = COLS / 2 + 1;
	vis[init1_y][init1_x] = vis[init2_y][init2_x] = 1;

	//初始化两条蛇的位置和食物位置
	Initialization(&snake1, init1_y, init1_x);
	Initialization(&snake2, init2_y, init2_x);

	int key = 0;
	int pause = 0;
	key = getch();
	while(1)
	{
		if(kbhit() != 0)////检查当前是否有键盘输入,若有则返回一个非0值,否则返回0 
 		{   
			while(kbhit() != 0)//可能存在多个按键,要全部取完,以最后一个为主 
      			key = getch();
		}
		if(KEY_UP == key) snake1.DIRECTION = 0;
		else if(KEY_DOWN == key) snake1.DIRECTION = 1;
		else if(KEY_LEFT == key) snake1.DIRECTION = 2;
		else if(KEY_RIGHT == key) snake1.DIRECTION = 3;
		else if('w' == key) snake2.DIRECTION = 0;
		else if('s'== key) snake2.DIRECTION = 1;
		else if('a' == key) snake2.DIRECTION = 2;
		else if('d' == key) snake2.DIRECTION = 3;
		else if(' ' == key){//暂停
			while((key = getch()) != ' ');
			key = 0;
		}


		int over = 0, over1 = 0, over2 = 0;
		//确定下一步移动的位置及是否吃到另一条蛇的食物
		over1 = Reverse_Direction(&snake1, snake2.FOOD_Y, snake2.FOOD_X);
		over2 = Reverse_Direction(&snake2, snake1.FOOD_Y, snake1.FOOD_X);

		//判断游戏结束
		if(Judge_Kill(&snake1) || Judge_Kill(&snake2) || over1 || over2){
			Free(snake1.head);
			Free(snake2.head);
			break;
		}

		//为各自的链表添加结点
		Add(&snake1);
		Add(&snake2);
		
		//移动蛇
		Move(&snake1);
		Move(&snake2);


		Sleep(250);
	}
	move(LINES, 0);
	Sleep(3000);
	return 0;
}





C语言之贪吃蛇(conio.h)

标签:

原文地址:http://blog.csdn.net/u013351484/article/details/43968983

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!