• 贪吃蛇 c++ ncurses


    近期学ncurses。用贪吃蛇训练下

    思路:不构造链表。蛇头向前进方向打点,蛇尾逐点消失,形成移动。

               须要记录蛇头方向,蛇尾方向。并用list仿造队列,增加拐点信息(空间比链表每一个结点开辟空间节省非常多)

                思路感觉比較清晰,几个小时就写了 出来

    编程环境 ubuntu12.04   安装ncurses :sudo apt-get install ncurses  编译:g++ xx.cpp -lncurses

    #include<iostream>
    #include<list>
    #include<algorithm>
    #include<ncurses.h>
    #include<signal.h>
    #include<sys/time.h>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    /*************定义方向****************/
    #define UP 1		
    #define DOWN 2
    #define LEFT 3
    #define RIGHT 4
    
    #define random(x) (rand()%x+1)		//用来产生随机数
    
    struct SNode						//结点
    {
    	int x;
    	int y;
    	//SNode *next;
    }fruit;								//定义果子
    
    struct Snake
    {
    	SNode front;
    	SNode back;
    	list<SNode> turn;				//这里用list仿造一个队列
    	list<int> turn_direction;		//2个List主要用来存拐点信息。方便推断
    	int front_direction;			//蛇头的前进方向
    	int back_direction;				//蛇尾的消失方向
    	int len;
    }mysnake;
    
    int ch,eat,i;		
    list<SNode>::iterator turn_iter;
    void show(int signumber);
    void conctroller(void);				
    void draw_node(SNode node, char paint);
    void end_game();
    bool crash();
    
    int main()
    {
    	struct itimerval value;
    	value.it_value.tv_sec=0;
    	value.it_value.tv_usec=200000;
    	value.it_interval.tv_sec=0;
    	value.it_interval.tv_usec=200000;
    	signal(SIGALRM,&show); 
    //	setitimer(ITIMER_REAL,&value,NULL);  
    
    	initscr();		//初始化虚拟屏幕
    	raw();			//禁用行缓冲
    	noecho();		//关闭键盘回显
    	keypad(stdscr,TRUE);	//开启功能键盘
    	for(int i=0;i<40;i++)
    	{
    		mvaddch(0,i,'-');
    		mvaddch(21,i,'-');
    	}
    	for(int i=0;i<21;i++)
    	{
    		mvaddch(i,0,'|');
    		mvaddch(i,41,'|');
    	}	
    
    	mysnake.front.x=2;
    	mysnake.front.y=1;
    	mysnake.back.x=1;
    	mysnake.back.y=1;
    	mysnake.len=2;
    	fruit.x=random(20);
    	fruit.y=random(20);	
    	draw_node(mysnake.front,'*');
    	draw_node(mysnake.back,'*');
    	draw_node(fruit,'#');
    	mysnake.front_direction=RIGHT;
    	mysnake.back_direction=RIGHT;
    	mvprintw(22,0,"/******Game : snake  len:%d  by Plss******/",mysnake.len);
    	refresh();
    
    	getch();//等待接收一个空字符,開始游戏
    	setitimer(ITIMER_REAL,&value,NULL);  //开启定时器
    	while(ch != KEY_F(2))
    	{
    		conctroller();
    	}
    	endwin();
    	return 0;
    }
    
    void conctroller(void)
    {
    	ch=getch();
    	switch(ch)
    	{
    		case KEY_UP:
    			if(mysnake.front_direction!=DOWN)
    			{
    				mysnake.front_direction=UP;
    				mysnake.turn_direction.push_back(mysnake.front_direction);
    				mysnake.turn.push_back(mysnake.front);
    				sleep(100);
    			}break;
    		case KEY_DOWN:
    			if(mysnake.front_direction!=UP)
    			{
    				mysnake.front_direction=DOWN;
    				mysnake.turn_direction.push_back(mysnake.front_direction);
    				mysnake.turn.push_back(mysnake.front);
    				sleep(100);				
    			}break;
    		case KEY_LEFT:
    			if(mysnake.front_direction!=RIGHT)
    			{
    				mysnake.front_direction=LEFT;
    				mysnake.turn_direction.push_back(mysnake.front_direction);
    				mysnake.turn.push_back(mysnake.front);
    				sleep(100);				
    			}break;
    		case KEY_RIGHT:
    			if(mysnake.front_direction!=LEFT)
    			{
    				mysnake.front_direction=RIGHT;
    				mysnake.turn_direction.push_back(mysnake.front_direction);
    				mysnake.turn.push_back(mysnake.front);
    				sleep(100);			
    			}break;
    	}
    }
    void show(int signumber)
    {
    	if(signumber==SIGALRM)
    	{
    		eat=0;
    		draw_node(mysnake.back,' ');
    		if(mysnake.front.x==fruit.x && mysnake.front.y==fruit.y)
    			eat=1;
    		for(int i=0;i<=eat;i++)
    		{
    			switch(mysnake.front_direction)
    			{
    				case UP: mysnake.front.y--;break;
    				case DOWN:mysnake.front.y++;break;
    				case LEFT:mysnake.front.x--;break;
    				case RIGHT:mysnake.front.x++;break;
    			}	
    			draw_node(mysnake.front,'*');	
    		}
    		switch(mysnake.back_direction)
    		{
    			case UP:mysnake.back.y--;break;
    			case DOWN:mysnake.back.y++;break;
    			case LEFT:mysnake.back.x--;break;
    			case RIGHT:mysnake.back.x++;break;
    		}
    		if(mysnake.turn_direction.size()  && (mysnake.back.x==mysnake.turn.front().x &&  mysnake.back.y==mysnake.turn.front().y))
    		{
    			mysnake.back_direction=mysnake.turn_direction.front();
    			mysnake.turn_direction.pop_front();
    			mysnake.turn.pop_front();
    		}				
    	
    		if(crash())	end_game();
    		if(eat)
    		{
    			mysnake.len++;
    			mvprintw(22,0,"/******Game : snake  len:%d  by Plss******/",mysnake.len);
    			fruit.x=random(20);
    			fruit.y=random(20);
    			draw_node(fruit,'#');
    		}
    		refresh();
    	}
    }
    void draw_node(SNode node,char paint)
    {
    	mvaddch(node.y,node.x,paint);
    }
    
    void end_game()
    {
    	struct itimerval value;
    	value.it_value.tv_sec=0;
    	value.it_value.tv_usec=0;
    	value.it_interval.tv_sec=0;
    	value.it_interval.tv_usec=0;
    	setitimer(ITIMER_REAL,&value,NULL);  
    	mvprintw(10,18,"Game_over");
    }
    bool crash()
    {	
    	int Max,Min;
    	SNode tmp;
    	if(mysnake.front.x>40  || mysnake.front.x<=0 ||mysnake.front.y<=0 || mysnake.front.y>20 )
    		return true;							//撞墙
    	/*推断是否撞到自己*/	
    	if(!mysnake.turn.empty())
    	{
    		i=mysnake.turn.size()-1;
    		turn_iter = mysnake.turn.end();
    
    		while(i--)
    		{
    			tmp=*turn_iter;
    			turn_iter--;
    			if((*turn_iter).x==tmp.x && (*turn_iter).x==mysnake.front.x)	
    			{
    				Max=max((*turn_iter).y,tmp.y);
    				Min=min((*turn_iter).y,tmp.y);
    				if(mysnake.front.y>=Min && mysnake.front.y<=Max)return true;
    			}
    			else if((*turn_iter).y==tmp.y && (*turn_iter).y==mysnake.front.y)	
    			{
    				Max=max((*turn_iter).x,tmp.x);
    				Min=min((*turn_iter).x,tmp.x);
    				if(mysnake.front.x>=Min && mysnake.front.x<=Max)return true;
    			}
    		
    		}
    		turn_iter = mysnake.turn.begin();
    		if((*turn_iter).x==mysnake.back.x && (*turn_iter).x==mysnake.front.x)
    		{
    			Max=max((*turn_iter).y,mysnake.back.y);
    			Min=min((*turn_iter).y,mysnake.back.y);
    			if(mysnake.front.y>=Min && mysnake.front.y<=Max)return true;
    		}
    		else if((*turn_iter).y==mysnake.back.y && (*turn_iter).y==mysnake.front.y)
    		{
    			Max=max((*turn_iter).x,mysnake.back.x);
    			Min=min((*turn_iter).x,mysnake.back.x);
    			if(mysnake.front.x>=Min && mysnake.front.x<=Max)return true;
    		}
    	}	
    
    	return false;
    }


  • 相关阅读:
    Java读取Excel文件的几种方法
    PowerDesigner的安装和数据库创建(转载)
    JAVA UUID 生成
    Mysql的“Limit”操作
    实现java 中 list集合中有几十万条数据,每100条为一组取出
    MySQL5中大数据错误:Packet for query is too large (****** > ******). You can change this value on the server by setting the max_allowed_packet' variable.;
    Mybatis 示例之 foreach
    JAVA WEB ------ 文件下载及导出数据到office Execl表格
    8 -- 深入使用Spring -- 4...3 AOP的基本概念
    8 -- 深入使用Spring -- 4...2 使用AspectJ实现AOP
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6852550.html
Copyright © 2020-2023  润新知