智能蛇学习记录

从原来的贪吃蛇到现在的智能蛇,需要克服几个难关。

1,清屏

#include <windows.h>
system("cls");

2,让蛇自己移动

void snake_move(int direct,int snake[snake_max_length][3])//让蛇移动 direct=1向上 direct=2向下 direct=3向左 direct=4向右
{   int x, y;//作为临时交换的值  head为蛇头
    int i;
    for (i = 0;i < 5;i++) {
        if (snake[i][0] == 1) {
            head = i;
            break;
        }
    }
    //找到头并将头的坐标保留用于下一个补上来
    x = snake[head][1];
    y = snake[head][2];
    switch (direct){
        case 1://向上
            snake[head][1]--;//横坐标不变,纵坐标+1
            break;
        case 2://向下
            snake[head][1]++;//横坐标不变,总左边-1
            break;
        case 3://向左
            snake[head][2]--;//纵坐标不变,横坐标-1
            break;
        case 4://向右
            snake[head][2]++;//纵坐标不变,横坐标+1
            break;
    }
    //头已经到了下一个位置,接下来将之前所有的身体放到前一个的位置上
        int j;
        for (j = head - 1;j >= 0;j--) {
            int temp;
            temp = x, x = snake[j][1], snake[j][1] = temp;
            temp = y, y = snake[j][2], snake[j][2] = temp;
        }
}

3,让蛇具有躲避障碍并吞吃食物的智能

char whereGoNext(snake[][],food[][]){//智能重新设置蛇的方向
    char moveable[4]={'H','F','K','M'};//方向
    int distance[4]={0,0,0,0};//距离
    distance[0]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]+1-food[1])*(snake[head][2]+1-food[1]);
    if(map[snake[head][1]][snake[head][2]+1]==wall_cell||map[snake[head][1]][snake[head][2]+1]==snake_food){//避免撞到墙和身体
        distance[0]=9999;
    }
    distance[1]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]-1-food[1])*(snake[head][2]-1-food[1]);
    if(map[snake[head][1]][snake[head][2]-1]==wall_cell||map[snake[head][1]][snake[head][2]-1]==snake_food){
        distance[1]=9999;
    }
    distance[2]=(snake[head][1]-1-food[0])*(snake[head][1]-1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
    if(map[snake[head][1]-1][snake[head][2]]==wall_cell||map[snake[head][1]-1][snake[head][2]]==snake_food){
        distance[2]=9999;
    }
    distance[3]=(snake[head][1]+1-food[0])*(snake[head][1]+1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
    if(map[snake[head][1]+1][snake[head][2]]==wall_cell||map[snake[head][1]+1][snake[head][2]]==snake_food){
        distance[3]=9999;
    }
    int min=get_min(distance);//取距离最小的下标
return moveable[min];
}

最终完成品

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

#define snake_max_length 20
#define snake_head 'H'
#define snake_body 'X'
#define blank_cell ' '
#define snake_food '$'
#define wall_cell '*'

char map[12][12]=        //初始状态的游戏背景
        {"************",
         "*          *",
         "*          *",
         "*     *    *",
         "*     *    *",
         "*     *    *",
         "*     *    *",
         "*     *    *",
         "*          *",
         "*          *",
         "*          *",
         "************"};

int snake[snake_max_length][3];//设定蛇
int head;//设定蛇头位置
int direct=4;//设定初始方向向右
int food[2];

char whereGoNext(snake[][],food[][]){//智能重新设置蛇的方向
    char moveable[4]={'H','F','K','M'};//方向
    int distance[4]={0,0,0,0};//距离
    distance[0]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]+1-food[1])*(snake[head][2]+1-food[1]);
    if(map[snake[head][1]][snake[head][2]+1]==wall_cell||map[snake[head][1]][snake[head][2]+1]==snake_food){//避免撞到墙和身体
        distance[0]=9999;
    }
    distance[1]=(snake[head][1]-food[0])*(snake[head][1]-food[0])+(snake[head][2]-1-food[1])*(snake[head][2]-1-food[1]);
    if(map[snake[head][1]][snake[head][2]-1]==wall_cell||map[snake[head][1]][snake[head][2]-1]==snake_food){
        distance[1]=9999;
    }
    distance[2]=(snake[head][1]-1-food[0])*(snake[head][1]-1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
    if(map[snake[head][1]-1][snake[head][2]]==wall_cell||map[snake[head][1]-1][snake[head][2]]==snake_food){
        distance[2]=9999;
    }
    distance[3]=(snake[head][1]+1-food[0])*(snake[head][1]+1-food[0])+(snake[head][2]-food[1])*(snake[head][2]-food[1]);
    if(map[snake[head][1]+1][snake[head][2]]==wall_cell||map[snake[head][1]+1][snake[head][2]]==snake_food){
        distance[3]=9999;
    }
    int min=get_min(distance);//取距离最小的下标
return moveable[min];
}
int ifReprat(int snake[400][3], int x, int y){//判断生成的食物是否与蛇有重复
    int i=0;
    for (i = 0;i < 400;i++) {
        if (snake[i][0] == 1) break;
        if ((snake[i][1] == x&&snake[i][2] == y)) {//有重复
            return 1;
        }
    }
    return 0;
}
void makeFood(int food[]){//生成随机数制作一个食物坐标
    srand(time(0));
    int x = rand() % 49 + 2, y = rand() % 19 + 2;//生成一个1-50的数作为横坐标  1-20的数作为纵坐标
    while (ifReprat(snake,x,y)) {//如果有重复就重新生成一个  直到不重复为止
        x = rand() % 49 + 2, y = rand() % 19 + 2;
    }
    food[0] = y;
    food[1] = x;
}

int ifEat(int head, int food[2]){//判断食物是否被吃掉
    if (snake[head][1] == food[0] && snake[head][2] == food[1])
        return 1;
    else
        return 0;
}

int ifBump(int head){//判断是否会相撞(撞自己或撞墙)
     if ((snake[head][2]==0|| snake[head][2] == 51)  ||  (snake[head][1] == 0|| snake[head][1] == 21))//撞墙
            return 1;
        int i=0;
        for (i = 0;i < head-1;i++) {
            if ((snake[i][1] == snake[head][1]&&snake[i][2] == snake[head][2])) {//幢自己
                return 1;
            }
        }
        return 0;
}

void snake_move(int direct,int snake[snake_max_length][3])//让蛇移动 direct=1向上 direct=2向下 direct=3向左 direct=4向右
{   int x, y;//作为临时交换的值  head为蛇头
    int i;
    for (i = 0;i < 5;i++) {
        if (snake[i][0] == 1) {
            head = i;
            break;
        }
    }
    //找到头并将头的坐标保留用于下一个补上来
    x = snake[head][1];
    y = snake[head][2];
    switch (direct){
        case 1://向上
            snake[head][1]--;//横坐标不变,纵坐标+1
            break;
        case 2://向下
            snake[head][1]++;//横坐标不变,总左边-1
            break;
        case 3://向左
            snake[head][2]--;//纵坐标不变,横坐标-1
            break;
        case 4://向右
            snake[head][2]++;//纵坐标不变,横坐标+1
            break;
    }
    //头已经到了下一个位置,接下来将之前所有的身体放到前一个的位置上
        int j;
        for (j = head - 1;j >= 0;j--) {
            int temp;
            temp = x, x = snake[j][1], snake[j][1] = temp;
            temp = y, y = snake[j][2], snake[j][2] = temp;
        }
}

void output(int snake[snake_max_length][3],char map[12][12],int food[]){//打印游戏画面

    int i;
    int j;
    for (i = 0;i <5;i++) {//绘制蛇
        if (snake[i][0] == 1) break;
        map[snake[i][1]][snake[i][2]] = snake_body;
    }
    map[snake[i][1]][snake[i][2]] = snake_head;
    map[food[0]][food[1]] = snake_food;//绘制食物
    for (i = 0;i<12;i++) {//打印游戏画面
        for (j = 0;j<12;j++) {
                printf("%c", map[i][j]);
        }
        printf("\n");
    }
}

void game_over()//当游戏结束时输出Game Over
{
    printf("Game Over");
return;
}

int main()
{
    output(snake,map,food);//输出游戏画面
    while(1){
       system("cls");//清屏
       char ch=whereGoNext(snake,food);//智能重新设置蛇的运动方向
       switch (ch) {
       case 'H'://向上
         if (direct != 2)
            direct = 1;
         break;
       case 'P'://向下
         if (direct != 1)
            direct = 2;
         break;
       case 'K'://向左
         if (direct != 4)
            direct = 3;
         break;
       case 'M'://向右
         if (direct != 3)
            direct = 4;
         break;
       }
       snake_move(direct,snake[snake_max_length][3]);//让蛇移动
       if (!food[0]&&!food[1]) {//食物已经被吃掉--重新生成食物
            makeFood(food);//生成食物坐标
        }
       if (ifBump(head)) {//相撞,游戏结束
            break;
        }
       output(snake,map,food);//输出游戏画面
    }
    game_over();//输出Game Over
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值