最近学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; }
原文地址:http://blog.csdn.net/u014494705/article/details/40209145