思路很简单
如果蛇能吃到食物且吃到食物后能找到尾巴,就去吃食物(最短路)
否则就跟着尾巴走(最长路)
期间做了一点优化,比如把步子存起来就不用跑一步看一下了,最长路也不需要,只要不是最短路就行了
代码上传gitee了:https://gitee.com/linhui_fun/gluttonous_snake
试着跑了一下,视频在B站
核心代码
代码语言:javascript复制public void AImove() {
if (mnsnake == null) mnsnake = new ArrayDeque<>();
else mnsnake.clear();
for (int i = 0; i < height; i ) {
for (int j = 0; j < width; j ) {
btable[i][j] = -table[i][j];
}
}
if (canGet(snake.getFirst(), food, btable, mnsnake) > 0) {
for (int i = 0; i < height; i ) {
for (int j = 0; j < width; j ) {
btable[i][j] = -table[i][j];
}
}
for (Body_joint body_joint : mnsnake) {
btable[body_joint.getX()][body_joint.getY()] = -1;
}
if (canGet(food, snake.getLast(), btable, null) > 0) {
return;
}
}
mnsnake.clear();
int maxx = 0;
for (int i = -1; i <= 1; i ) {
for (int j = -1; j <= 1; j ) {
if (i == j || i * j != 0 || isOut(snake.getFirst().getX() i, snake.getFirst().getY() j))
continue;
if (table[snake.getFirst().getX() i][snake.getFirst().getY() j] != 0) continue;
for (int ii = 0; ii < height; ii ) {
for (int jj = 0; jj < width; jj ) {
btable[ii][jj] = -table[ii][jj];
}
}
btable[snake.getLast().getX()][snake.getLast().getY()] = 0;
int t = canGet(new Body_joint(snake.getFirst().getX() i, snake.getFirst().getY() j), snake.getLast(), btable, null);
t =snake.getFirst().getDis(food);
if (maxx < t) {
maxx = t;
if (mnsnake.isEmpty())
mnsnake.addFirst(new Body_joint(snake.getFirst().getX(), snake.getFirst().getY()));
mnsnake.getFirst().setDx(i);
mnsnake.getFirst().setDy(j);
}
}
}
if(mnsnake.isEmpty())
{
mnsnake.addFirst(new Body_joint(snake.getFirst()));
mnsnake.getFirst().setDx(snake.getLast().getX()-snake.getFirst().getX());
mnsnake.getFirst().setDy(snake.getLast().getY()-snake.getFirst().getY());
}
}
public int canGet(Body_joint qd, Body_joint zd, int[][] map, Deque<Body_joint> road) {
map[qd.getX()][qd.getY()] = map[zd.getX()][zd.getY()] = 0;
PriorityQueue<Body_joint> openlist = new PriorityQueue<>();
int[][] oc = new int[height][width];
int[][] ddx = new int[height][width];
int[][] ddy = new int[height][width];
for (int i = 0; i < height; i ) {
for (int j = 0; j < width; j ) {
ddx[i][j] = ddy[i][j] = oc[i][j] = 0;
}
}
qd.setS(1 qd.getDis(zd));
openlist.add(qd);
oc[qd.getX()][qd.getY()] = 1;//1是open -1是close
map[qd.getX()][qd.getY()] = 1;
Body_joint btemp, bbtemp = null;
while (!openlist.isEmpty()) {
if (map[zd.getX()][zd.getY()] != 0) break;
btemp = openlist.poll();
if (oc[btemp.getX()][btemp.getY()] == -1) continue;
oc[btemp.getX()][btemp.getY()] = -1;
for (int i = -1; i <= 1; i ) {
for (int j = -1; j <= 1; j ) {
if (i == j || i * j != 0 || isOut(btemp.getX() i, btemp.getY() j) || oc[btemp.getX() i][btemp.getY() j] == -1 || map[btemp.getX() i][btemp.getY() j] == -1)
continue;//不可抵达或close
if (oc[btemp.getX() i][btemp.getY() j] == 0||map[btemp.getX() i][btemp.getY() j] > map[btemp.getX()][btemp.getY()] 1) {
oc[btemp.getX() i][btemp.getY() j] = 1;
map[btemp.getX() i][btemp.getY() j] = map[btemp.getX()][btemp.getY()] 1;
bbtemp = new Body_joint(btemp.getX() i, btemp.getY() j, i, j);
bbtemp.setS(map[btemp.getX() i][btemp.getY() j] bbtemp.getDis(zd));
openlist.add(bbtemp);
ddx[bbtemp.getX()][bbtemp.getY()] = i;
ddy[bbtemp.getX()][bbtemp.getY()] = j;
}
}
}
}
if (map[zd.getX()][zd.getY()] == 0) return -1;
;
if (road == null) return map[zd.getX()][zd.getY()];
int tx = zd.getX(), ty = zd.getY();
road.addFirst(new Body_joint(tx, ty));
while (road.getFirst().getX() != qd.getX() || road.getFirst().getY() != qd.getY()) {
bbtemp = new Body_joint(tx - ddx[tx][ty], ty - ddy[tx][ty]);
bbtemp.setDx(ddx[road.getFirst().getX()][road.getFirst().getY()]);
bbtemp.setDy(ddy[road.getFirst().getX()][road.getFirst().getY()]);
road.addFirst(bbtemp);
int tempx=tx;
int tempy=ty;
tx -= ddx[tempx][tempy];
ty -= ddy[tempx][tempy];
}
road.pollLast();
return road.size();
}