實現貪吃蛇四方向的風騷走位
實現代碼
#include <curses.h>
#include <stdlib.h>
struct snake{
????????int hang;
????????int lie;
????????struct snake *next;
};
struct snake *head;
struct snake *tail;
int key;
int dir; //全局變量
#define UP ????1? //這個是宏定義,主要就是讓人更好理解 ,也為了后期的方向做了鋪墊
#define DOWN ?-1
#define LEFT ??2
#define RIGHT -2
void initNcurse()
{
????????initscr();
????????keypad(stdscr,1);
????????noecho();
}
int ?hasSnakeNode(int i,int j)
{
????????struct snake *p;
????????p = head;
????????while(p != NULL){
????????????????if(p->hang==i && p->lie==j){
????????????????????????return 1;
????????????????}
????????????????p=p->next;
????????}
????????return 0;
}
void gamepic()
{
????????int hang;
????????int lie;
????????move(0,0);
????????for(hang=0;hang<20;hang++){
????????????????if(hang == 0){
????????????????????????for(lie=0;lie<20;lie++){
????????????????????????????????printw("--");
????????????????????????}
?????????????????printw("\n");
????????????????}
????????????????if(hang>=0 && hang<=19){
????????????????????????for(lie=0;lie<=20;lie++){
?????????????????????????????????if(lie==0||lie==20){
?????????????????????????????????????????printw("|");
?????????????????????????????????}else if(hasSnakeNode(hang,lie)){
????????????????????????????????????????printw("[]");
?????????????????????????????????}
?????????????????????????????????else{
?????????????????????????????????????????printw(" ?");
?????????????????????????????????}
????????????????????????}
????????????????????????printw("\n");
????????????????}
????????????????if(hang == 19){
????????????????????????for(lie=0;lie<20;lie++){
?????????????????????????????????printw("--");
????????????????????????}
????????????????????????printw("\n");
????????????????}
??????????}
??????????printw("by shijintao\n");
??????????printw("key =%d\n",key);
???}
void addNode()
{
????????struct snake *new;
????????new =(struct snake *)malloc(sizeof(struct snake));
????????new->next=NULL;
????????????????switch(dir){
????????????????case UP:
????????????????????????new->hang=tail->hang-1;
????????????????????????new->lie=tail->lie;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
????????????????case DOWN:
????????????????????????new->hang=tail->hang+1;
????????????????????????new->lie=tail->lie;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
????????????????case LEFT:
????????????????????????new->lie=tail->lie-1;
????????????????????????new->hang=tail->hang;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
????????????????case RIGHT:
????????????????????????new->lie=tail->lie+1;
????????????????????????new->hang=tail->hang;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
?????????????????}
}
當為dir為up的時候? hang變,lie不變
當為dir為down的時候? hang變,lie不變
當為dir為left的時候? lie變,hang不變
當為dir為right的時候? lie變,hang不變
void ?initSnake()
{
????????struct snake *p;
?????????dir = RIGHT; //這邊我們設置了一個初始方向? dir是全局變量
????????while(head != NULL){
?????????????p=head;
?????????????head=head->next;
?????????????free(p);
????????}
head = (struct snake *)malloc(sizeof(struct snake));
????????head->hang=2;
????????head->lie=2;
????????head->next=NULL;
????????tail = head;
????????addNode();
????????addNode();
}
void deleteNode()
{
????????struct snake *p;
????????p = head;
????????head = head->next;
????????free(p);
}
void moveSnake()
{
????????addNode();
????????deleteNode();
????????if(tail->hang==0||tail->hang==20||tail->lie==20||tail->lie==0){
????????????????initSnake();
????????}
}
void * ?changeDir()
{
????????while(1){
????????????????key =getch();
????????????????switch(key){? ?//這個key是全局變量? 會通過changeDir函數改變
????????????????????????case KEY_DOWN:
????????????????????????????????dir = DOWN;? //這個DOWN是通過宏定義定義的
????????????????????????????????break;
????????????????????????case KEY_UP:
????????????????????????????????dir = UP;
????????????????????????????????break;
????????????????????????case KEY_RIGHT:
????????????????????????????????dir = RIGHT;
????????????????????????????????break;
????????????????????????case KEY_LEFT:
????????????????????????????????dir = LEFT;
????????????????????????????????break;
????????????????}
????????}
}
void * gamerefresh()
{
????????while(1){
????????????????moveSnake();
????????????????gamepic();
????????????????refresh();
????????????????usleep(100000);
????????}
}
int main()
{
????????????????pthread_t th1;
????????????????pthread_t th2;
????????????????initNcurse();
????????????????initSnake();
????????????????gamepic();
????????????????pthread_create(&th2,NULL,gamerefresh,NULL);
????????????????pthread_create(&th1,NULL,changeDir,NULL);
????????????????while(1);//死循環不能讓主線程退出,這樣就可以一直玩游戲了
????????????????getch();
????????????????endwin();
????????????????return 0;
}
??????????????????????????????????????????????????????????????????????
優化代碼(方向相反不能直接走)
#include <curses.h>
#include <stdlib.h>
struct snake{
????????int hang;
????????int lie;
????????struct snake *next;
};
struct snake *head;
struct snake *tail;
int key;
int dir;
#define UP ????1
#define DOWN ?-1
#define LEFT ??2
#define RIGHT -2
void initNcurse()
{
????????initscr();
????????keypad(stdscr,1);
????????noecho(); //這個就是ncurse的按鍵盤的時候會彈出來亂七八糟的符號,輸入這個就可以去掉,不然地圖很奇怪,很多亂七八糟的符號
}
int ?hasSnakeNode(int i,int j)
{
????????struct snake *p;
????????p = head;
????????while(p != NULL){
????????????????if(p->hang==i && p->lie==j){
????????????????????????return 1;
????????????????}
????????????????p=p->next;
????????}
????????return 0;
}
void gamepic()
{
????????int hang;
????????int lie;
????????move(0,0);
????????for(hang=0;hang<20;hang++){
????????????????if(hang == 0){
????????????????????????for(lie=0;lie<20;lie++){
????????????????????????????????printw("--");
????????????????????????}
?????????????????printw("\n");
????????????????}
????????????????if(hang>=0 && hang<=19){
????????????????????????for(lie=0;lie<=20;lie++){
?????????????????????????????????if(lie==0||lie==20){
?????????????????????????????????????????printw("|");
?????????????????????????????????}else if(hasSnakeNode(hang,lie)){
????????????????????????????????????????printw("[]");
?????????????????????????????????}
?????????????????????????????????else{
?????????????????????????????????????????printw(" ?");
?????????????????????????????????}
????????????????????????}
????????????????????????printw("\n");
????????????????}
????????????????if(hang == 19){
????????????????????????for(lie=0;lie<20;lie++){
?????????????????????????????????printw("--");
????????????????????????}
????????????????????????printw("\n");
????????????????}
??????????}
??????????printw("by shijintao\n");
??????????printw("key =%d\n",key);
???}
void addNode()
{
????????struct snake *new;
????????new =(struct snake *)malloc(sizeof(struct snake));
????????new->next=NULL;
????????????????switch(dir){
????????????????case UP:
????????????????????????new->hang=tail->hang-1;
????????????????????????new->lie=tail->lie;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
????????????????case DOWN:
????????????????????????new->hang=tail->hang+1;
????????????????????????new->lie=tail->lie;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
????????????????case LEFT:
????????????????????????new->lie=tail->lie-1;
????????????????????????new->hang=tail->hang;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
????????????????case RIGHT:
????????????????????????new->lie=tail->lie+1;
????????????????????????new->hang=tail->hang;
????????????????????????tail->next=new;
????????????????????????tail = new;
????????????????????????break;
?????????????????}
}
void ?initSnake()
{
????????struct snake *p;
????????while(head != NULL){
?????????????p=head;
?????????????head=head->next;
?????????????free(p);
????????}
head = (struct snake *)malloc(sizeof(struct snake));
????????dir = RIGHT;
????????head->hang=2;
????????head->lie=2;
????????head->next=NULL;
????????tail = head;
????????addNode();
????????addNode();
}
void deleteNode()
{
????????struct snake *p;
????????p = head;
????????head = head->next;
????????free(p);
}
void moveSnake()
{
????????addNode();
????????deleteNode();
????????if(tail->hang==0||tail->hang==20||tail->lie==20||tail->lie==0){
????????????????initSnake();
????????}
}
void turn(int direction)
{
????????if(abs(dir) != abs(direction)){
????????????????dir = direction;
????????}
}
//這段代碼就是更改貪吃蛇不能相反移動的核心了,利用abs絕對值的方法,這個direction是新的方向,這個dir是舊方向 ,在這邊我們設置左右上下的值互為相反數,如果他們的絕對值相等的話,那我們就不把新方向替代舊方向,說白了我白說了,只要絕對值相等,那么就不會換方向,只要絕對值不相等,就換方向,這個值取決于你在宏定義里面的設置,就像下面的一樣
//#define UP ????1
//#define DOWN ?-1
//#define LEFT ??2
//#define RIGHT -2
void * ?changeDir()
{
????????while(1){
????????????????key =getch();
????????????????switch(key){
????????????????????????case KEY_DOWN:
????????????????????????????????turn(DOWN);
????????????????????????????????break;
????????????????????????case KEY_UP:
????????????????????????????????turn(UP);
????????????????????????????????break;
????????????????????????case KEY_RIGHT:
????????????????????????????????turn(RIGHT);
????????????????????????????????break;
????????????????????????case KEY_LEFT:
????????????????????????????????turn(LEFT);
????????????????????????????????break;
????????????????}
????????}
}
void * gamerefresh()
{
????????while(1){
????????????????moveSnake();
????????????????gamepic();
????????????????refresh();
????????????????usleep(100000);
????????}
}
int main()
{
????????????????pthread_t th1;
????????????????pthread_t th2;
????????????????initNcurse();
????????????????initSnake();
????????????????gamepic();
????????????????pthread_create(&th2,NULL,gamerefresh,NULL);
????????????????pthread_create(&th1,NULL,changeDir,NULL);
????????????????while(1);
????????????????getch();
????????????????endwin();
????????????????return 0;
}