目录
前言
修改方向
修改内容
效果展示
两个新的问题🙋
1.问题1
2.问题2
代码如下:
前言
我们上一节实现了贪吃蛇吃食物身体节点变长,但是食物的刷新位置不是随机的,并且初始化几次后食物就刷不见了,本节我们就来解决这个问题。
修改方向
我们这个地图格子是20X20,随机数函数不能有界限,那么我们思考方向就是随机数然后对20进行取余,那么最终得到的数字一定是在区间内的。
修改内容
void initfood()
{int x = rand()%20;int y = rand()%20;food.hang = x;food.lie = y;
}
我们之前地图下面还会打印出“by beiweiqiuAC”,我们修改一下,可以打印出食物的行和列坐标。
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 if(hasfood(hang,lie)) printw("##");else printw(" ");}printw("\n");}if(hang == 19){for(lie = 0;lie < 20;lie ++){printw("--");}printw("\n");printw("by beiweiqiuAC,food.hang=%d,food.lie=%d\n",food.hang,food.lie);}}}
效果展示
两个新的问题🙋
我们发现如果食物在地图的最上方的我们的贪吃蛇是吃不到,我们尝试解决这个问题,并且贪吃蛇可以从自己的身体中间穿过去,这很明显是不符合逻辑的,所以我们来优化这两个问题,贪吃蛇这个项目就完结了。
1.问题1
食物在地图的最上方,贪吃蛇就会直接撞墙死掉,原因是tail的行第一行就是0,所以只有最上面那一行不行,所以我们只需要修改让贪吃蛇在第0行的时候不死就行了:
void moveSnake()
{addNode();if(hasfood(tail->hang,tail->lie)){initfood();}else{deleNode();}if(tail ->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20){initSnake();}
}
2.问题2
贪吃蛇在运行的过程当中,贪吃蛇撞到自己的身体不会死掉,所以我们要优化这个问题,其实非常简单,我们只需要判断尾巴节点和身体节点是否重合即可。
int ifSnakeDie()
{struct Snake *p;p = head;if(tail ->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20){return 1;}while(p ->next != NULL){if(p->hang == tail->hang && p -> lie == tail->lie){return 1;}p = p -> next;}return 0;
}
通过遍历链表的位置再来与尾节点的位置做比较,如果相同就死掉,此时游戏的功能就齐全了。
代码如下:
#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>#define UP 1
#define DOWN -1
#define LEFT 2
#define RIGHT -2struct Snake
{int hang;int lie;struct Snake * next;
};struct Snake * head = NULL;
struct Snake * tail = NULL;
int key;
int dir;struct Snake food;void initfood()
{int x = rand()%20;int y = rand()%20;food.hang = x;food.lie = y;
}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;
}int hasfood(int i,int j)
{if(food.hang == i && food.lie == j) return 1;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 if(hasfood(hang,lie)) printw("##");else printw(" ");}printw("\n");}if(hang == 19){for(lie = 0;lie < 20;lie ++){printw("--");}printw("\n");printw("by beiweiqiuAC,food.hang=%d,food.lie=%d\n",food.hang,food.lie);}}}void addNode()
{struct Snake * new = (struct Snake *)malloc(sizeof(struct Snake));new->next = NULL;switch(dir){case UP:new->hang = tail->hang - 1;new->lie = tail->lie;break;case DOWN:new->hang = tail->hang + 1;new->lie = tail->lie;break;case LEFT:new->hang = tail->hang;new->lie = tail->lie - 1;break;case RIGHT:new->hang = tail->hang;new->lie = tail->lie + 1;break;}tail->next = new;tail = new;
}void initSnake(){struct Snake * p;dir = RIGHT;while(head != NULL){p = head;head = head -> next;free(p);}initfood();head = (struct Snake *)malloc(sizeof(struct Snake));head->hang = 1;head->lie = 1;head->next = NULL;tail = head;addNode();addNode();addNode();addNode();
}void deleNode()
{// struct Snake * p;// p = head;head = head ->next;// free(p);
}int ifSnakeDie()
{struct Snake *p;p = head;if(tail ->hang < 0 || tail->lie == 0 || tail->hang == 20 || tail ->lie == 20){return 1;}while(p ->next != NULL){if(p->hang == tail->hang && p -> lie == tail->lie){return 1;}p = p -> next;}return 0;
}void moveSnake()
{addNode();if(hasfood(tail->hang,tail->lie)){initfood();}else{deleNode();}if(ifSnakeDie()){initSnake();}
}void* refreshJieMian()
{while(1){moveSnake();gamePic();refresh();usleep(100000);}
}void turn(int direction)
{if(abs(dir) != abs(direction)){dir = direction;}
}void* changeDir()
{while (1){key = getch();switch (key){case 0402:turn(DOWN);break;case 0403:turn(UP);break;case 0404:turn(LEFT);break;case 0405:turn(RIGHT);break;}}
}int main()
{pthread_t t1;pthread_t t2;initNcurse();initSnake();gamePic();pthread_create( &t1, NULL,refreshJieMian, NULL);pthread_create( &t2, NULL, changeDir, NULL);while(1);getch();//防止程序退出endwin();return 0;
}
效果展示:
C语言贪吃蛇效果展示
此时,我们的C语言贪吃蛇项目就已经完成了「完结散花🌹🌹🌹」