«

基于DFS和简单启发式的AI贪吃蛇

zjr0330 发布于 阅读:229 C++


寒假快结束了,今年是蛇年,做一个AI贪吃蛇庆祝一下

这条基于食物位置,向食物位置移动,并且附带DFS的简单避障。

一年多没碰C++了,写的不好还请给位大佬指正!

经测试,这条的平均得分大致为40-50,当然有可能因为数据量过小出现偏差

如果想要让这条慢一点,可以把AI_game函数里面被注释掉的Sleep(50);取消注释。具体如下:

void AI_game() {
    while (true) {
        Sleep(50);
        snakes.snake_move();
        map_print();
    }
}

用上面的代码替换掉下面代码中的AI_game函数就行了。

或者查看这里找慢版AI贪吃蛇

当然这是萌新向的,因为...

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;

int mapp[16][16];
void map_print();

enum turn {
    UP = 1,
    DOWN = 2,
    LEFT = 3,
    RIGHT = 4
};

struct food {
    int x, y;
    void food_updata() {
        int x_1, y_1;
        do {
            x_1 = (rand() % 13) + 1;
            y_1 = (rand() % 13) + 1;
        } while (mapp[x_1][y_1] == 1); // 确保食物不在蛇身上
        mapp[x_1][y_1] = 3;
        x = x_1;
        y = y_1;
    }
} foods;

struct snake {
    private:
        bool ismp[101][101] = {false}, rt = false;
        int path[256][2], ln = 0;
        int find_min = 99999999;
        bool dfs_find_way = false;
//      snake_find find_dfs;

    public:
        int body_x[1000], body_y[1000];
        int l = 2;

        void game_over() {
            cout << "game over\n";
            cout << "Final Score: " << l - 2 << " !\n";
            system("pause");
            exit(0);
        }

        void dfs(int x, int y, int num = 1) {
//          cout << num << "\n";
            if (x <= 0 || x > 13 || y <= 0 || y > 13)return;
            if (x == foods.x && y == foods.y && num < find_min) {
                path[ln][0] = x;
                path[ln][1] = y;
                ln++;
                rt = true;
                find_min = num;
                return;
            }
            if (ismp[x][y] == true) {
                return;
            }
            if (!dfs_find_way && ((mapp[x][y] == 1 /*&& (x != body_x[0] || y != body_y[0])*/) || mapp[x][y] == 2)) {
                return;
            }
            if (dfs_find_way && ((mapp[x][y] == 1 && (x != body_x[0] || y != body_y[0])) || mapp[x][y] == 2)) {
                return;
            }
            ismp[x][y] = true;
            if (x != body_x[0] || y != body_y[0]) {
                path[ln][0] = x;
                path[ln][1] = y;
                ln++;
            }
            dfs(x + 1, y, num + 1);
//          if (rt)return;
            dfs(x, y + 1, num + 1);
//          if (rt)return;
            dfs(x - 1, y, num + 1);
//          if (rt)return;
            dfs(x, y - 1, num + 1);
//          if (rt)return;
            ln--;
        }

        turn find_food() {
            ln = 0, find_min = 99999999;
            rt = false;
            for (int i = 0; i < 101; i++) {
                for (int j = 0; j < 101; j++) {
                    ismp[i][j] = false;
                }
            }
            int fdway = 0, fdway2 = 0;
AGAIN_FINDWAY:
            if ((body_x[0] < foods.x && (mapp[body_x[0] + 1][body_y[0]] == 3 || mapp[body_x[0] + 1][body_y[0]] == 0)) && fdway2 % 4 == 0) {
                dfs(body_x[0] + 1, body_y[0]);
                if (!rt && fdway2 != 4) {
                    cout << "No Way!" << endl;
//                  system("pause");
                    fdway2++;
                    goto AGAIN_FINDWAY;
                }
                return RIGHT;
            } else if ((body_y[0] < foods.y && (mapp[body_x[0]][body_y[0] + 1] == 3 || mapp[body_x[0]][body_y[0] + 1] == 0)) && (fdway2 % 4 == 1 || fdway2 == 0)) {
                dfs(body_x[0], body_y[0] + 1);
                if (!rt) {
                    cout << "No Way!" << endl;
//                  system("pause");
                    fdway2++;
                    goto AGAIN_FINDWAY;
                }
                return DOWN;
            } else if ((body_y[0] > foods.y && (mapp[body_x[0]][body_y[0] - 1] == 3 || mapp[body_x[0]][body_y[0] - 1] == 0)) && (fdway2 % 4 == 2 || fdway2 == 0)) {
                dfs(body_x[0], body_y[0] - 1);
                if (!rt) {
                    cout << "No Way!" << endl;
//                  system("pause");
                    fdway2++;
                    goto AGAIN_FINDWAY;
                }
                return UP;
            } else if ((body_x[0] > foods.x && (mapp[body_x[0] - 1][body_y[0]] == 3 || mapp[body_x[0] - 1][body_y[0]] == 0)) && (fdway2 % 4 == 3 || fdway2 == 0)) {
                dfs(body_x[0] - 1, body_y[0]);
                if (!rt) {
                    cout << "No Way!" << endl;
//                  system("pause");
                    fdway2++;
                    goto AGAIN_FINDWAY;
                }
                return LEFT;
            } else {
                if ((mapp[body_x[0]][body_y[0] - 1] == 3 || mapp[body_x[0]][body_y[0] - 1] == 0) && (fdway < 1 || fdway % 4 == 0)) {
                    dfs(body_x[0], body_y[0] - 1);
                    if (!rt && fdway < 4) {
                        cout << "No Way!" << endl;
//                      system("pause");
                        fdway++;
                        goto AGAIN_FINDWAY;
                    }
                    return UP;
                } else if ((mapp[body_x[0] - 1][body_y[0]] == 3 || mapp[body_x[0] - 1][body_y[0]] == 0) && (fdway < 2 || fdway % 4 == 1)) {
                    dfs(body_x[0] - 1, body_y[0]);
                    if (!rt && fdway < 4) {
                        cout << "No Way!" << endl;
//                      system("pause");
                        fdway++;
                        goto AGAIN_FINDWAY;
                    }
                    return LEFT;
                } else if ((mapp[body_x[0] + 1][body_y[0]] == 3 || mapp[body_x[0] + 1][body_y[0]] == 0) && (fdway < 3 || fdway % 4 == 2)) {
                    dfs(body_x[0] + 1, body_y[0]);
                    if (!rt && fdway < 4) {
                        cout << "No Way!" << endl;
//                      system("pause");
                        fdway++;
                        goto AGAIN_FINDWAY;
                    }
                    return RIGHT;
                } else if (mapp[body_x[0]][body_y[0] + 1] == 3 || mapp[body_x[0]][body_y[0] + 1] == 0) {
                    dfs(body_x[0], body_y[0] + 1);
                    if (!rt && fdway < 4) {
                        cout << "No Way!" << endl;
//                      system("pause");
                        fdway++;
                        goto AGAIN_FINDWAY;
                    }
                    return DOWN;
                } else {
                    if (mapp[body_x[0] + 1][body_y[0]] == 3 || mapp[body_x[0] + 1][body_y[0]] == 0) {
                        return RIGHT;
                    }else if(mapp[body_x[0]][body_y[0] - 1] == 3 || mapp[body_x[0]][body_y[0] - 1] == 0){
                        return UP;
                    }else if(mapp[body_x[0] - 1][body_y[0]] == 3 || mapp[body_x[0] - 1][body_y[0]] == 0){
                        return LEFT;
                    }
                    dfs(body_x[0], body_y[0]);
                    cout << "\n" << rt << endl;
                    system("pause");
                    game_over();
                }
            }
            return DOWN;
        }

//      turn find_food(int n=0) {
//
////            find_dfs.cleann();
////            find_dfs.mapm[body_x[0]][body_y[0]] = 1;
////            find_dfs.path[0][0] = body_x[0];
////            find_dfs.path[0][1] = body_y[0];
////            find_dfs.path_size = 0;
////            find_dfs.finddfs(body_x[0], body_y[0]);
//
//          ln = 0, find_min = 99999999;
//          rt = false;
//          for (int i = 0; i < 101; i++) {
//              for (int j = 0; j < 101; j++) {
//                  ismp[i][j] = false;
//              }
//          }
//          dfs(body_x[0], body_y[0]);
//          if (rt) {
////                cout << "\n\n" << ln << endl;
////                for (int i = 0; i < ln; i++) {
////                    cout << path[i][0] << " " << path[i][1] << endl;
////                }
////                system("pause");
//              if (path[0][0] == body_x[0]) {
//                  if (path[0][1] > body_y[0]) {
//                      return DOWN;
//                  } else {
//                      return UP;
//                  }
//              } else {
//                  if (path[0][0] > body_x[0]) {
//                      return RIGHT;
//                  } else {
//                      return LEFT;
//                  }
//              }
//          } else {
//              if (mapp[body_x[0]][body_y[0] - 1] == 3 || mapp[body_x[0]][body_y[0] - 1] == 0) {
//                  return UP;
//              } else if (mapp[body_x[0] - 1][body_y[0]] == 3 || mapp[body_x[0] - 1][body_y[0]] == 0) {
//                  return LEFT;
//              } else if (mapp[body_x[0] + 1][body_y[0]] == 3 || mapp[body_x[0] + 1][body_y[0]] == 0) {
//                  return RIGHT;
//              } else if (mapp[body_x[0]][body_y[0] + 1] == 3 || mapp[body_x[0]][body_y[0] + 1] == 0) {
//                  return DOWN;
//              } else {
//                  dfs(body_x[0], body_y[0]);
//                  cout << "\n" << rt << endl;
//                  system("pause");
//                  game_over();
//              }
//          }
//          return LEFT;
//      }

        void snake_move() {
            int move_temp = find_food();
            int x_temp = body_x[0], y_temp = body_y[0];
            int x_last_temp = body_x[l - 1], y_last_temp = body_y[l - 1];
            if (move_temp == LEFT) {
                mapp[body_x[0] - 1][body_y[0]] = 1, mapp[body_x[l - 1]][body_y[l - 1]] = 0;
                for (int i = 0; i < l; i++) {
                    if (i == 0) {
                        body_x[0] = body_x[0] - 1;
                    } else {
                        int x2_temp = x_temp, y2_temp = y_temp;
                        x_temp = body_x[i], y_temp = body_y[i];
                        body_x[i] = x2_temp, body_y[i] = y2_temp;
                    }
                }
//              dfs(body_x[0],body_y[0]);
//              if(!rt){
//                  cout<<"No Way!"<<endl;
//                  system("pause");
//              }
            } else if (move_temp == RIGHT) {
                mapp[body_x[0] + 1][body_y[0]] = 1, mapp[body_x[l - 1]][body_y[l - 1]] = 0;
                for (int i = 0; i < l; i++) {
                    if (i == 0) {
                        body_x[0] = body_x[0] + 1;
                    } else {
                        int x2_temp = x_temp, y2_temp = y_temp;
                        x_temp = body_x[i], y_temp = body_y[i];
                        body_x[i] = x2_temp, body_y[i] = y2_temp;
                    }
                }
            } else if (move_temp == UP) {
                mapp[body_x[0]][body_y[0] - 1] = 1, mapp[body_x[l - 1]][body_y[l - 1]] = 0;
                for (int i = 0; i < l; i++) {
                    if (i == 0) {
                        body_y[0] = body_y[0] - 1;
                    } else {
                        int x2_temp = x_temp, y2_temp = y_temp;
                        x_temp = body_x[i], y_temp = body_y[i];
                        body_x[i] = x2_temp, body_y[i] = y2_temp;
                    }
                }
            } else if (move_temp == DOWN) {
                mapp[body_x[0]][body_y[0] + 1] = 1, mapp[body_x[l - 1]][body_y[l - 1]] = 0;
                for (int i = 0; i < l; i++) {
                    if (i == 0) {
                        body_y[0] = body_y[0] + 1;
                    } else {
                        int x2_temp = x_temp, y2_temp = y_temp;
                        x_temp = body_x[i], y_temp = body_y[i];
                        body_x[i] = x2_temp, body_y[i] = y2_temp;
                    }
                }
            }
            if (body_x[0] == foods.x && body_y[0] == foods.y) {
                body_x[l] = x_last_temp, body_y[l] = y_last_temp;
                mapp[body_x[l]][body_y[l]] = 1;
                l++;
                foods.food_updata();
            }
        }
} snakes;

void init() {
    for (int i = 0; i < 15; i++) {
        for (int j = 0; j < 15; j++) {
            mapp[i][j] = 0;
        }
    }
    for (int i = 0; i < 15; i++) {
        mapp[i][0] = 2;
        mapp[0][i] = 2;
        mapp[14][i] = 2;
        mapp[i][14] = 2;
    }
    mapp[7][7] = 1;
    snakes.body_x[0] = 7, snakes.body_y[0] = 7;
    mapp[7][8] = 1;
    snakes.body_x[1] = 7, snakes.body_y[1] = 8;
    int x_1, y_1;
AGAIN_FOOD:
    x_1 = (rand() % 13) + 1, y_1 = (rand() % 13) + 1;
    mapp[x_1][y_1] = 3;
    foods.x = x_1, foods.y = y_1;
    if (mapp[7][7] == 3) {
        mapp[7][7] = 1;
        goto AGAIN_FOOD;
    }
}

void map_print() {
    system("cls");
    for (int i = 0; i < 15; i++) {
        for (int j = 0; j < 15; j++) {
            if (j == snakes.body_x[0] && i == snakes.body_y[0]) {
                cout << "H";
                continue;
            }
            if (mapp[j][i] == 0) {
                cout << '.';
            } else if (mapp[j][i] == 1) {
                cout << '#';
            } else if (mapp[j][i] == 2) {
                cout << '*';
            } else if (mapp[j][i] == 3) {
                cout << 'F';
            }
        }
        printf("\n");
    }
}

void AI_game() {
    while (true) {
//      Sleep(50);
        snakes.snake_move();
        map_print();
    }
}

int main() {
    srand(time(NULL));
    init();
    map_print();
    AI_game();
    return 0;
}

That`s all

Or to Here to see this page.

瞎写的英文

AI C++ 技术

请先 登录 再评论