我們為貪吃蛇的節點設置為一個結構體,構成貪吃蛇的身子的話我們使用鏈表,鏈表的每一個節點是一個結構體
顯示貪吃蛇身子的一個節點
我們這邊node就表示一個蛇的身體? 就是一小節
輸出結果如下
顯示貪吃蛇完整身子
效果如下
代碼實現
????????這個hasSnakeNode(hang,lie)這個函數就是來判斷當前這個坐標是否為蛇的身子的坐標,坐標帶進去,如果符合return 1;那么返回1 到地圖這里? ?1? 的話就是ture 使hasSnakeNode這個函數生效,然后打印[ ]蛇身。那么函數封裝的好處就是在于我們可以進行多個節點的判斷
????????宏觀的看,每個坐標都會進入到hasSnakeNode(hang,lie)進行判斷,如果行列坐標等于蛇身子的行列坐標,那么就返回1? ? ? ? 我們會去想p的下一項是哪里操作的 請看main函數node1.next=&next2,這個是關鍵,才能遍歷鏈表,暫時是靜態的寫鏈表,下一次我們用動態添加的方法進行添加節點
代碼
#include <curses.h>
struct snack{
????????int hang;
????????int lie;
????????struct snack *next;
};
struct snack node1 = {2,2,NULL};
struct snack node2 = {2,3,NULL};
struct snack node3 = {2,4,NULL};
void initgame()
{
????????initscr();
????????keypad(stdscr,1);
}
int ?hasSnackNode(int i,int j)
{
????????struct snack *p;
????????p = &node1;
????????while(p != NULL){
????????????????if(p->hang==i && p->lie==j){
????????????????????????return 1;
????????????????}
????????????????p=p->next;
????????}
????????return 0;
}
void gamepic()
{
????????int hang;
????????int lie;
????????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(hasSnackNode(hang,lie)){
????????????????????????????????????????printw("[]");
?????????????????????????????????}
?????????????????????????????????else{
?????????????????????????????????????????printw(" ?");
?????????????????????????????????}
????????????????????????}
????????????????????????printw("\n");
????????????????}
????????????????if(hang == 19){
????????????????????????for(lie=0;lie<20;lie++){
?????????????????????????????????printw("--");
????????????????????????}
????????????????????????printw("\n");
????????????????}
??????????}
??????????printw("by shijintao");
???}
int main()
{
initgame();
????????????????node1.next = &node2;
????????????????node2.next = &node3;
????????????????gamepic();
????????????????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;//全局變量
void initgame()
{
????????initscr();
????????keypad(stdscr,1);
}
int ?hasSnakeNode(int i,int j)
{
????????struct snake *p;
????????p = head; //現在頭節點是head? 不是node1了? 而且這個head是通過initSnake影響的,因為head是全局變量,所以可以使用head
????????while(p != NULL){
????????????????if(p->hang==i && p->lie==j){
????????????????????????return 1;
????????????????}
????????????????p=p->next;
????????}
????????return 0;
}
void gamepic()
{
????????int hang;
????????int lie;
????????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");
???}
void addNode()
{
????????struct snake *new;
????????new =(struct snake *)malloc(sizeof(struct snake));
????????new->hang=tail->hang; //最先開始tail的值等于head
????????new->lie=tail->lie+1;
????????tail->next = new;
????????tail = new;//每次改變tail的值
????????new->next = NULL;
}
void ?initSnake()
{
????????head = (struct snake *)malloc(sizeof(struct snake));
????????head->hang=2;
????????head->lie=2;
????????head->next=NULL;
????????tail = head;
????????addNode();
}
int main()
{
????????????????initgame();
????????????????initSnake();
????????????????gamepic();
????????????????getch();
????????????????endwin();
????????????????return 0;
}
代碼優化的點:
將原先死板添加的,變成動態的添加節點,并進行封裝,減少代碼冗余
void ?initSnake()
{
????????head = (struct snake *)malloc(sizeof(struct snake));? ??
????????head->hang=2;//這些都是設置初始值
????????head->lie=2;
????????head->next=NULL;
????????tail = head;//蛇的初始狀態頭節點也是尾節點
????????addNode(); //如果你不加這個的話? 蛇的身子就只有一個,我覺得加一個也就是比較好看
}
void addNode()
{
????????struct snake *new;
????????new =(struct snake *)malloc(sizeof(struct snake));
????????new->hang=tail->hang;?//這個只是單純的向右邊加入,不考慮方向,以后回頭來看不要被誤導
????????new->lie=tail->lie+1;
????????tail->next = new;
????????tail = new;//可以這樣想每次新節點插入后這個tail的值(行和列)都會回到最上方全局變量的地方然后,tail的值是不會被刷新的,是一直被影響的,被上一個節點影響,隨后保存信息,因為他是全局變量
????????new->next = NULL;
}
initSnake()這個函數直接就是把蛇的頭節點,也就是蛇的初始位置,hang、lie 都默認的設置好,就像我們玩貪吃蛇初始有個蛇停在那邊,這個函數就是這個作用。
這兩個函數搭配使用組成了蛇的身子,我們都說用動態創建鏈表要用到指針,且鏈表都是有頭節點和尾節點,為了不容易出現錯誤 我們將頭指針和尾指針設置為全局變量。
頭節點是指針,我們需要為指針賦予一個內存空間,因為后面我們需要在尾點后方插入新的節點,那么我們需要將新節點每次開辟一個空間。
最先開始尾節點就是頭節點
addNode是添加新節點到尾節點后邊
我們將添加新節點,還有初始化貪吃蛇的行列,封裝成了函數,直接調用函數即可在尾部添加新節點