智能蛇的學習記錄

步驟

1、創建開始的蛇與框架;
用二維的字符數組構成基本的框架,並指明蛇開始的狀態。

char map[12][12]=
{"************",
 "*XXXXH     *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "************"
};
int direct=4;
int snakelength=5;
int snakeX[100]={1,2,3,4,5};
int snakeY[100]={1,1,1,1,1};

2、構建一些函數使其完成行進、轉彎等動作

void snake_move(int,int);//根據方向移動一次

3、每移動一次後,判斷其狀態,下一步可以往哪些方向移動,根據移動後距離食物的遠近來判斷往哪個方向移動,以獲得最近的吃到食物的路徑。

void calculate(void);//找到下一步方向
int distance(int);//計算通過一個方向的運動後距離食物的距離
void check(void);//找到哪些方向可以運動

4、食物被吃掉後,在空白位置隨機生成

void make_food(void);//隨機生成一個食物

5、判斷是否結束,咬到自己或是撞到框架即死亡,遊戲結束。

代碼

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

const int width = 12;
const int high = 12;
const int LENGTH_MAX = 100;
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'

char map[12][12]=
{"************",
 "*XXXXH     *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "*          *",
 "************"
};
void snake_move(int,int);//根據方向移動一次
void make_food(void);//隨機生成一個食物
void make_map(void);//根據座標得到圖案的形狀
void output(void);//輸出圖案
void gameover(void);//遊戲結束
void calculate(void);//找到下一步方向
int ifBump(void);//判斷蛇是否死亡
int ifReprat(int ,int );//判斷食物的座標是否與蛇的位置重複
int distance(int);//計算通過一個方向的運動後距離食物的距離
void check(void);//找到哪些方向可以運動

char key;//輸入的值
int direct=4;//記錄方向,給定初始方向
int snakelength=5;//記錄蛇的長度
int snakeX[100]={1,2,3,4,5};//組成蛇的各字符的橫座標
int snakeY[100]={1,1,1,1,1};//組成蛇的各字符的縱座標
int food[2]={5,6};//食物的座標
int movable[4] = { 0, 1, 0, 1 };//記錄各方向是否可運動

int main(){
    output();
    while(1){
        calculate();
        system("cls");//清屏
        Sleep(30);
        snake_move(snakelength,direct);
        if((food[0]==0)&&(food[1]==0))
            make_food();
        make_map();
        output();
        if(ifBump()){
            gameover();
            break;
        }
        check();
    }
    getchar();
    return 0;
}
void output(void){//根據數組輸出將圖案打印出來
    int i,j;
    for(i=0;i<high;++i){
        for(j=0;j<width;++j){
            printf("%c",map[i][j]);
        }
        putchar('\n');
    }
}
void make_map(void){//根據數組得到圖案字符數組
    int i,j;
    for(i=0;i<width;++i){
        for(j=0;j<high;++j){
            if((i==0)||(j==0)||(i==width-1)||(j==high-1))
                map[i][j]=WALL_CELL;
            else
                map[i][j]=BLANK_CELL;
        }
    }
    for(i=0;i<snakelength-1;++i){
        map[snakeY[i]][snakeX[i]]=SNAKE_BODY;
    }
    int x=snakeY[snakelength-1],y=snakeX[snakelength-1];
    map[x][y]=SNAKE_HEAD;
    map[food[1]][food[0]]=SNAKE_FOOD;
}
void make_food(void){
    srand(time(0));
    int x = rand() % 10 + 1, y = rand() % 10 + 1;//生成一個1-11的數作爲橫座標,1-11的數作爲縱座標
    while (ifReprat(x,y)) {//如果有重複就重新生成一個,直到不重複爲止
        x = rand() % 10 + 1, y = rand() % 10 + 1;
    }
    food[0] = y;
    food[1] = x;
}
int ifReprat(int x,int y){//判斷食物的座標是否與蛇的位置重複
    int i;
    for(i=0;i<snakelength;++i){
        if((snakeX[i]==x)&&(snakeY[i]==y))
            return 0;
    }
    return 1;
}
void snake_move(int len,int dir){
    int x=snakeX[len-1],y=snakeY[len-1];//記住蛇頭此時的座標
    switch(dir){
        case 1://向上
                snakeY[len-1]--;//橫座標不變,縱座標-1
                break;
        case 2://向下
                snakeY[len-1]++;//橫座標不變,縱座標+1
                break;
        case 3://向左
                snakeX[len-1]--;//縱座標不變,橫座標-1
                break;
        case 4://向右
                snakeX[len-1]++;//縱座標不變,橫座標+1
                break;
    }
    if((snakeX[len-1]==food[0])&&(snakeY[len-1]==food[1])){
        snakeX[len]=snakeX[len-1];
        snakeY[len]=snakeY[len-1];
        snakeX[len-1]=x;
        snakeY[len-1]=y;
        food[0]=0;
        food[1]=0;
        snakelength++;
    }
    else{
        int j;
        for(j=0;j<len-2;j--){
            snakeX[j]=snakeX[j+1];
            snakeY[j]=snakeY[j+1];
        }
        snakeX[len-2]=x;
        snakeY[len-2]=y;
    }


}
void calculate(){//得到下一步運動的方向
    int i,j,n;
    for(i=0;i<4;++i){
        if((movable[i]==1)||(i<3))
            for(j=i+1;j<4;j++){
                if(movable[j]==1)
                    if(distance(i+1)>distance(j+1))
                        n=j;
                    else
                        n=i;
        }
    }
    direct=n;
}
int distance(int dir){//一次運動後的距離,根據其計算最優的方向
    switch(dir){
        case 1:
            return abs(snakeX[snakelength-1]-food[0])+abs(snakeY[snakelength-1]-1-food[1]);
        case 2:
            return abs(snakeX[snakelength-1]-food[0])+abs(snakeY[snakelength-1]+1-food[1]);
        case 3:
            return abs(snakeX[snakelength-1]-1-food[0])+abs(snakeY[snakelength-1]-food[1]);
        case 4:
            return abs(snakeX[snakelength-1]+1-food[0])+abs(snakeY[snakelength-1]-food[1]);
    }
}
void check(){//判斷哪些方向可運動
    if((map[snakeX[snakelength-1]][snakeY[snakelength-1]-1]==WALL_CELL)||(map[snakeX[snakelength-1]][snakeY[snakelength-1]-1]==SNAKE_BODY))
        movable[0]=0;
    else
        movable[0]=1;
    if((map[snakeX[snakelength-1]][snakeY[snakelength-1]+1]==WALL_CELL)||(map[snakeX[snakelength-1]][snakeY[snakelength-1]+1]==SNAKE_BODY))
        movable[1]=0;
    else
        movable[1]=1;
    if((map[snakeX[snakelength-1]-1][snakeY[snakelength-1]]==WALL_CELL)||(map[snakeX[snakelength-1]-1][snakeY[snakelength-1]]==SNAKE_BODY))
        movable[2]=0;
    else
        movable[2]=1;
    if((map[snakeX[snakelength-1]+1][snakeY[snakelength-1]]==WALL_CELL)||(map[snakeX[snakelength-1]+1][snakeY[snakelength-1]]==SNAKE_BODY))
        movable[3]=0;
    else
        movable[3]=1;
}
int ifBump(){//判斷蛇是否與框相撞或咬到自己而死亡
    int x=snakeX[snakelength-1],y=snakeY[snakelength-1];
    if((x==0)||(x==width-1)||(y==0)||(y==high-1))
        return 1;
    int i;
    for(i=0;i<snakelength-2;++i){
        if((x==snakeX[i])&&(y==snakeY[i]))
            return 1;
    }
    return 0;
}
void gameover(){//輸出遊戲結束
    printf("遊戲結束!");
}

考慮較爲粗略,是爲學習的一點總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章