zoukankan      html  css  js  c++  java
  • 【C】链表实现贪吃蛇小游戏

    Snake.h

    #ifndef _SNAKE_H_
    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    #include<assert.h>
    #include<time.h>
    
    #define _SNAKE_H_
    #define FOOD "■"
    #define INIT_X 24
    #define INIT_Y 5
    
    //蛇的节点
    typedef struct node{
    	int _x;
    	int _y;
    	struct node *_next;
    }SnakeNode,*pSnakeNode;
    
    //蛇的行走方向
    enum DIRECTION{UP=1,DOWN,LEFT,RIGHT};
    
    //蛇的当前状态
    enum Status{OK,KILL_BY_SELF,KILL_BY_WALL};
    
    //蛇本身
    typedef struct snake{
    	pSnakeNode _pSnake;//蛇头指针
    	pSnakeNode _pFood;//蛇的食物
    	enum DIRECTION _Dir;//蛇行走的方向
    	enum Status _status;//蛇的当前状态
    	int _SleepTime;//每走一步停一步的时间
    	int _grade;
    }Snake,*pSnake;
    
    void DropMap();
    void SetPos(int x,int y);
    void Welcome();
    int NextHasFood(pSnake ps,pSnakeNode newNode);
    void EatFood(pSnake ps,pSnakeNode newNode);
    void NoFood(pSnake ps,pSnakeNode newNode);
    void KillBySelf(pSnake ps);
    void KillByWall(pSnake ps);
    void SnakeRun(pSnake ps);
    void test1();
    #endif


    Snake.c

    #include"snake.h"
    
    //设置光标所在位置
    void SetPos(int x,int y){
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    	COORD pos = {0};
    	pos.X=x;
    	pos.Y=y;
    	SetConsoleCursorPosition(handle,pos);
    }
    
    //绘制地图
    void DropMap(){
    	int i;
    	system("cls");
    	for(i=0;i<58;i+=2){
    		SetPos(i,0);
    		printf(FOOD);
    	}
    	for(i=0;i<26;i++){
    		SetPos(0,i);
    		printf(FOOD);
    		SetPos(58,i);
    		printf(FOOD);
    	}
    	for(i=0;i<=58;i+=2){
    		SetPos(i,26);
    		printf(FOOD);
    	}
    	SetPos(66,3);
    	printf("分数:0");
    	SetPos(66,5);
    	printf("按空格加速/减速");
    }
    //初始化蛇
    void InitSnake(pSnake ps){
    	pSnakeNode cur=NULL;
    	int i=0;
    	cur = (pSnakeNode)malloc(sizeof(SnakeNode));
    	memset(cur,0,sizeof(SnakeNode));
    	cur->_x=INIT_X;
    	cur->_y=INIT_Y;
    	cur->_next=NULL;
    	ps->_SleepTime = 500;
    	ps->_status = OK;
    	ps->_Dir = RIGHT;
    	ps->_grade = 0;
    	for(i=1;i<=4;i++){
    		ps->_pSnake = (pSnakeNode)malloc(sizeof(SnakeNode));
    		ps->_pSnake->_next = cur;
    		ps->_pSnake->_x = INIT_X+i*2;
    		ps->_pSnake->_y = INIT_Y;
    		cur=ps->_pSnake;
    	}
    	while(cur!=NULL){
    		SetPos(cur->_x,cur->_y);
    		printf(FOOD);
    		cur= cur->_next;
    	}
    
    }
    
    void CreateFood(pSnake ps){
    	pSnakeNode food = NULL;
    	pSnakeNode cur = NULL;
    	food = (pSnakeNode)malloc(sizeof(SnakeNode));
    	srand(time(NULL));
    
    again:
    	memset(food,0,sizeof(SnakeNode));
    	do{
    		food->_x=rand()%56+2;
    	}while(food->_x%2!=0);
    	food->_y = rand()%25+1;
    
    	cur = ps->_pSnake;
    	while(cur!=NULL){
    		if(cur->_x == food->_x&&cur->_y == food->_y){
    			goto again;			//返回到again
    		}
    		cur = cur->_next;
    	}
    
    	SetPos(food->_x,food->_y);
    	printf(FOOD);
    	ps->_pFood=food;
    }
    
    void Welcome(){
    	system("color 73");
    	system("mode con cols=100 lines=32");
    	SetPos(25,6);
    	printf("贪吃蛇游戏
    ");
    	SetPos(22,8);
    	printf("↑ ↓ ← → 控制方向
    ");
    }
    
    void start(pSnake ps){
    	Welcome();
    	getchar();
    	DropMap();
    	InitSnake(ps);
    	CreateFood(ps);
    }
    
    int NextHasFood(pSnake ps,pSnakeNode newNode){
    	return (ps->_pFood->_x==newNode->_x) && (ps->_pFood->_y==newNode->_y);
    }
    
    void EatFood(pSnake ps,pSnakeNode newNode){
    	pSnakeNode cur = ps->_pSnake;
    	newNode->_next = cur;
    	ps->_pSnake = newNode;
    	cur = ps->_pSnake;
    	ps->_grade+=4;
    	while(cur!=NULL){
    		SetPos(cur->_x,cur->_y);
    		printf(FOOD);
    		cur=cur->_next;
    	}
    	if(ps->_SleepTime>300)
    		ps->_SleepTime-=100;
    	else if(ps->_SleepTime>100)
    		ps->_SleepTime-=50;
    
    	SetPos(72,3);
    	printf("%d",ps->_grade);
    	CreateFood(ps);
    }
    
    void NoFood(pSnake ps,pSnakeNode newNode){
    	pSnakeNode cur = ps->_pSnake;
    	newNode->_next = cur;
    	ps->_pSnake = newNode;
    	
    	cur=ps->_pSnake;
    	while(cur->_next->_next!=NULL){
    		SetPos(cur->_x,cur->_y);
    		printf(FOOD);
    		cur=cur->_next;
    	}
    	SetPos(cur->_next->_x,cur->_next->_y);
    	printf(" ");
    	free(cur->_next);
    	cur->_next=NULL;
    }
    
    enum DIRECTION getDir(pSnake ps){
    	do{
    		if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=DOWN)
    			ps->_Dir=DOWN;
    		if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=UP)
    			ps->_Dir=UP;
    		if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=LEFT)
    			ps->_Dir=LEFT;
    		if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=RIGHT)
    			ps->_Dir=RIGHT;
    	}while(ps->_status==OK);
    	return ps->_Dir;
    }
    
    void SnakeMove(pSnake ps){
    	pSnakeNode newNode = (pSnakeNode)malloc(sizeof(SnakeNode));
    	memset(newNode,0,sizeof(SnakeNode));
    	newNode->_x = ps->_pSnake->_x;
    	newNode->_y = ps->_pSnake->_y;
    
    	switch(ps->_Dir){
    	case UP:
    		newNode->_y--;
    		break;
    	case DOWN:
    		newNode->_y++;
    		break;
    	case LEFT:
    		newNode->_x-=2;
    		break;
    	case RIGHT:
    		newNode->_x+=2;
    		break;
    	default:
    		break;
    	}
    	if(NextHasFood(ps,newNode)){
    		EatFood(ps,newNode);
    	}
    	else{
    		NoFood(ps,newNode);	
    	}
    
    }
    void KillBySelf(pSnake ps){
    	pSnakeNode cur = ps->_pSnake->_next;
    	while(cur){
    		if(cur->_x==ps->_pSnake->_x&&cur->_y==ps->_pSnake->_y){
    			ps->_status=KILL_BY_SELF;
    			SetPos(66,7);
    			printf("自杀");
    			SetPos(0,27);
    		}		
    		cur = cur->_next;
    	}
    }
    				
    void KillByWall(pSnake ps){
    	if(ps->_pSnake->_x==0||ps->_pSnake->_x==58||
    		ps->_pSnake->_y==0||ps->_pSnake->_y==26){
    			ps->_status = KILL_BY_WALL;
    			SetPos(66,7);
    			printf("撞墙");
    			SetPos(0,27);
    	}
    }
    
    void SnakeRun(pSnake ps){
    	int flag = 0;
    	do{
    		if(GetAsyncKeyState(VK_DOWN)&&ps->_Dir!=UP){
    			ps->_Dir = DOWN;
    		}
    		else if(GetAsyncKeyState(VK_UP)&&ps->_Dir!=DOWN){
    			ps->_Dir = UP;
    		}
    		else if(GetAsyncKeyState(VK_LEFT)&&ps->_Dir!=RIGHT){
    			ps->_Dir = LEFT;
    		}
    		else if(GetAsyncKeyState(VK_RIGHT)&&ps->_Dir!=LEFT){
    			ps->_Dir = RIGHT;
    		}
    		else if(GetAsyncKeyState(VK_SPACE)){    //按下空格来控制蛇的加速减速
    			if(flag==0){
    				ps->_SleepTime/=2;
    				flag=1;
    			}
    			else if(flag==1){
    				ps->_SleepTime*=2;
    				flag=0;
    			}
    		}
    		SnakeMove(ps);
    		KillBySelf(ps);
    		KillByWall(ps);
    		Sleep(ps->_SleepTime);
    	}while(ps->_status == OK);
    	
    }
    
    void test1(){
    	Snake snake;
    	start(&snake);
    	SnakeRun(&snake);
    }
    

    main.c

    #include"snake.h"
    
    int main(){
    	test1();
    	getchar();
    	system("pause");
    	return 0;
    }
    


  • 相关阅读:
    Coursera Algorithms Programming Assignment 2: Deque and Randomized Queue (100分)
    Coursera Algorithms week1 查并集 练习测验:3 Successor with delete
    Coursera Algorithms week1 查并集 练习测验:2 Union-find with specific canonical element
    项目选题报告答辩总结
    项目UML设计(团队)
    第七次作业--项目需求分析(团队)
    结对项目--第二次作业
    【软件工程实践 · 团队项目】 第二次作业
    第五次作业--原型设计(结对)
    团队项目系列博客 —— 在路上(之wampserver 修改根目录以及配置多站点以及修改端口号)
  • 原文地址:https://www.cnblogs.com/yongtaochang/p/13615375.html
Copyright © 2011-2022 走看看