每日一题 No.38 AI贪吃蛇(三)

xiaoxiao2021-02-27  403

本题要求:

继续昨天的贪吃蛇继续做。

输入格式:

输出格式:

输入样例:

输出样例:

解题思路 :

比昨天的加了个randomMove 和 优化goAway即可。 如果想吃满全屏,只需要将寻路调整成寻找最远路径即可。

代码 :

#include <iostream> #include <string> #include <cstring> #include <conio.h> #include <windows.h> #include <cstdlib> #include <ctime> #include <iomanip> #include <queue> #include <stack> #include <fstream> using namespace std; #define X 10 #define Y 10 enum FACE {UP_ = 0, DOWN_ = 1, LEFT_ = 2, RIGHT_ = 3}; int gameMap[X][Y]; void gotoXY(int x, int y) { //Initialize the coordinates COORD coord = {x, y}; //Set the position SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } pair<int, int> apple; ofstream out("c:\\1.txt"); class Snake { public: int x; // 头部位置 int y; int tx; // 尾巴位置 int ty; int food; int point; FACE face; Snake(int gameMap[X][Y]) { init(gameMap); } void init(int gameMap[X][Y]) { x = X / 2; y = Y / 2; tx = -1; ty = -1; food = 0; point = 3; face = UP_; gameMap[x][y] = point; setFood(gameMap); } void setFace(FACE f) { switch(face) { case UP_: if (f != DOWN_) { face = f; } break; case DOWN_: if (f != UP_) { face = f; } break; case LEFT_: if (f != RIGHT_) { face = f; } break; case RIGHT_: if (f != LEFT_) { face = f; } break; } } void setFood(int gameMap[X][Y]) { int tempX, tempY; srand(time(0)); do { tempX = rand() % (X - 1) + 1; tempY = rand() % (X - 1) + 1; } while (gameMap[tempX][tempY]); gameMap[tempX][tempY] = 2; apple.first = tempX; apple.second = tempY; } bool check(int gameMap[X][Y], int x, int y) { if (x < 0 || y < 0 || x >= X || y >= Y || (gameMap[x][y] != 2 && gameMap[x][y] != 0)) { return false; } else { if (gameMap[x][y] == 2) { food++; setFood(gameMap); } return true; } } bool move(int gameMap[X][Y]) { moveTail(gameMap); return moveHead(gameMap); } bool moveHead(int gameMap[X][Y]) { if (tx == -1) { tx = x; ty = y; } switch(face) { case UP_: y--; break; case DOWN_: y++; break; case LEFT_: x--; break; case RIGHT_: x++; break; default: getch(); break; } if (check(gameMap, x, y)) { gameMap[x][y] = ++point; return true; } else { return false; } } void moveTail(int gameMap[X][Y]) { if (food != 0) { food--; return; } int nextX = tx; int nextY = ty; int fx[4] = {1, -1, 0, 0}; int fy[4] = {0, 0, -1, 1}; for (int i = 0; i < 4; i++) { if (gameMap[tx + fx[i]][ty + fy[i]] == gameMap[tx][ty] + 1) { nextX = tx + fx[i]; nextY = ty + fy[i]; break; } } gameMap[tx][ty] = 0; tx = nextX; ty = nextY; } }; Snake snake(gameMap); void init(); void display(int gameMap[X][Y]); void setFood(int gameMap[X][Y]); void control(int ch); stack<int> bfs(pair<int, int> start, pair<int, int> end) { stack<int> path; int dist[101][101]; int dist2[101][101]; for (int i = 0; i < X; i++) { for (int j = 0; j < Y; j++) { dist[i][j] = 0x7f7f; dist2[i][j] = -1; } } queue<pair<int, int> > que; dist[start.first][start.second] = 0; que.push(start); int fx[4] = {0, 0, -1, 1}; int fy[4] = {-1, 1, 0, 0}; while (que.size()) { pair<int, int> now; now = que.front(); que.pop(); if (now == end) { break; } for (int i = 0; i < 4; i++) { int nx = now.first + fx[i]; int ny = now.second + fy[i]; if (nx >= 0 && ny >= 0 && nx < X && ny < Y && (gameMap[nx][ny] == 0 || gameMap[nx][ny] == gameMap[end.first][end.second]) && dist[nx][ny] == 0x7f7f) { que.push(pair<int, int>(nx, ny)); dist2[nx][ny] = i; dist[nx][ny] = dist[now.first][now.second] + 1; } } } out << start.first << "," << start.second << "->" << end.first << "," << end.second << endl; out << " "; for (int i = 0; i < X; i++) { out << setw(4) << i; } out << endl; for (int i = 0; i < Y; i++) { out << i << ":"; for (int j = 0; j < X; j++) { out << setw(4) << dist2[j][i]; } out << endl; } //getch(); int d = dist2[end.first][end.second]; while (d != -1) { path.push(d); switch(d) { case UP_: d = dist2[end.first][++end.second]; break; case DOWN_: d = dist2[end.first][--end.second]; break; case LEFT_: d = dist2[++end.first][end.second]; break; case RIGHT_: d = dist2[--end.first][end.second]; break; } } return path; } void moveFace(pair<int, int> &nowPos, int face) { switch(face) { case UP_: nowPos.second--; break; case DOWN_: nowPos.second++; break; case LEFT_: nowPos.first--; break; case RIGHT_: nowPos.first++; break; } } pair<int, int> findNear(int tx, int ty) { pair<int, int> p; int fx[4] = {1, -1, 0, 0}; int fy[4] = {0, 0, -1, 1}; for (int i = 0; i < 4; i++) { if (gameMap[tx + fx[i]][ty + fy[i]] == gameMap[tx][ty] + 1) { p.first = tx + fx[i]; p.second = ty + fy[i]; return p; } } } bool randomMove() { int fy[4] = {-1, 1, 0, 0}; int fx[4] = {0, 0, -1, 1}; int i = -1; vector<int> vec; bool flag = false; for (i = 0; i < 4; i++) { if (gameMap[snake.x + fx[i]][snake.y + fy[i]] == 0) { pair<int, int> nowPos(snake.x + fx[i], snake.y + fy[i]); stack<int> path = bfs(nowPos, pair<int, int>(snake.tx, snake.ty)); if (!path.empty()) { flag = true; break; } vec.push_back(i); } } if (!flag) { if (vec.size() != 0) { i = vec[0]; } } if (i != -1 && i != 4) { snake.setFace((FACE)i); snake.move(gameMap); display(gameMap); return true; } else { return false; } } bool goAway() { pair<int, int> nowPos(snake.x, snake.y); stack<int> path = bfs(nowPos, pair<int, int>(snake.tx, snake.ty)); if (!path.empty()) { snake.setFace((FACE)path.top()); snake.move(gameMap); display(gameMap); return true; } else { randomMove(); return true; } return false; } bool autoMove(int gameMap[X][Y]) { pair<int, int> nowPos(snake.x, snake.y); stack<int> path = bfs(nowPos, apple); if (!path.empty()) { moveFace(nowPos, (FACE)path.top()); if (snake.tx != -1) { int temp = gameMap[apple.first][apple.second]; gameMap[apple.first][apple.second] = 0; stack<int> path2 = bfs(nowPos, pair<int, int>(snake.tx, snake.ty)); gameMap[apple.first][apple.second] = temp; if (!path2.empty()) { int d = path.top(); snake.setFace((FACE)d); snake.move(gameMap); display(gameMap); } else { goAway(); } } else { snake.setFace((FACE)path.top()); snake.move(gameMap); display(gameMap); } } else { goAway(); } return true; } int main() { init(); display(gameMap); while (true) { if (kbhit()) { char a = getch(); control(a); } if (autoMove(gameMap) == false) { return 0; } } return 0; } void init() { memset(gameMap, 0, sizeof(gameMap)); for (int y = 0; y < Y; y++) { for (int x = 0; x < X; x++) { if (x == 0 || y == 0 || x == X - 1 || y == Y - 1) { gameMap[x][y] = -99; } } } snake.init(gameMap); } void display(int gameMap[X][Y]) { for (int y = 0; y < Y; y++) { for (int x = 0; x < X; x++) { gotoXY(x * 2, y); switch(gameMap[x][y]) { case 0: // 空白 cout << " "; break; case -99: // 墙 cout << "■"; break; case 2: // 苹果 cout << "★"; break; default: // 蛇身 cout << "□"; break; } } } gotoXY(snake.tx * 2, snake.ty); cout << "☆"; gotoXY(0, 15); gotoXY(snake.x * 2, snake.y); cout << "●"; } void setFood(int gameMap[X][Y]) { int tempX, tempY; srand(time(0)); do { tempX = rand() % (X - 1) + 1; tempY = rand() % (X - 1) + 1; } while (gameMap[tempX][tempY]); gameMap[tempX][tempY] = 2; } void control(int ch) { switch(ch) { case 'w': case 'W': if (snake.face != DOWN_) { snake.setFace(UP_); } break; case 'a': case 'A': if (snake.face != RIGHT_) { snake.setFace(LEFT_); } break; case 'd': case 'D': if (snake.face != LEFT_) { snake.setFace(RIGHT_); } break; case 's': case 'S': if (snake.face != UP_) { snake.setFace(DOWN_); } break; } }
转载请注明原文地址: https://www.6miu.com/read-2241.html

最新回复(0)