基于DFS和简单启发式的AI贪吃蛇
寒假快结束了,今年是蛇年,做一个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.
瞎写的英文