Я пытаюсь изменить игру pacman с сайта Mason 19.Что мне нужно сделать, так это заставить pacman бегать самостоятельно и проходить любую доску как можно быстрее.До сих пор я добился того, чтобы pacman работал сам по себе, но он застрял в петле в верхней части доски.То, что я хочу знать, - это то, что было бы лучшим способом заставить его работать, а не зацикливаться.
Программа, из которой я использую код, происходит от Mason19 https://cs.gmu.edu/~eclab/projects/mason/
код, который я изменил, находится внутри Pac.java и класса doPolicyStep.
protected void doPolicyStep(SimState state)
{
if(lastAction == NOTHING)
{
if(isPossibleToDoAction(Pac.E))
{
pacman.actions[0] = Pac.E;
performAction(Pac.E);
}
else if(isPossibleToDoAction(Pac.S))
{
pacman.actions[0] = Pac.S;
performAction(Pac.S);
}
else if(isPossibleToDoAction(Pac.N))
{
pacman.actions[0] = Pac.N;
performAction(Pac.N);
}
else
{
pacman.actions[0] = Pac.W;
performAction(Pac.W);
}
}
else if(lastAction == Pac.E)
{
if(isPossibleToDoAction(Pac.E))
{
pacman.actions[0] = Pac.E;
performAction(Pac.E);
}
else if(isPossibleToDoAction(Pac.S))
{
pacman.actions[0] = Pac.S;
performAction(Pac.S);
}
else if(isPossibleToDoAction(Pac.N))
{
pacman.actions[0] = Pac.N;
performAction(Pac.N);
}
else
{
pacman.actions[0] = Pac.W;
performAction(Pac.W);
}
}
else if(lastAction == Pac.S)
{
if(isPossibleToDoAction(Pac.S))
{
pacman.actions[0] = Pac.S;
performAction(Pac.S);
}
else if(isPossibleToDoAction(Pac.W))
{
pacman.actions[0] = Pac.W;
performAction(Pac.W);
}
else if(isPossibleToDoAction(Pac.E))
{
pacman.actions[0] = Pac.E;
performAction(Pac.E);
}
else
{
pacman.actions[0] = Pac.N;
performAction(Pac.N);
}
}
else if(lastAction == Pac.W)
{
if(isPossibleToDoAction(Pac.W))
{
pacman.actions[0] = Pac.W;
performAction(Pac.W);
}
else if(isPossibleToDoAction(Pac.N))
{
pacman.actions[0] = Pac.N;
performAction(Pac.N);
}
else if(isPossibleToDoAction(Pac.S))
{
pacman.actions[0] = Pac.S;
performAction(Pac.S);
}
else
{
pacman.actions[0] = Pac.E;
performAction(Pac.E);
}
}
else if(lastAction == Pac.N)
{
if(isPossibleToDoAction(Pac.N))
{
pacman.actions[0] = Pac.N;
performAction(Pac.N);
}
else if(isPossibleToDoAction(Pac.W))
{
pacman.actions[0] = Pac.W;
performAction(Pac.W);
}
else if(isPossibleToDoAction(Pac.E))
{
pacman.actions[0] = Pac.E;
performAction(Pac.E);
}
else
{
pacman.actions[0] = Pac.S;
performAction(Pac.S);
}
}
int nextAction = pacman.getNextAction(tag);
/ ** Метод isPossibleToDoAction () Определяет, может ли агент двигаться с данным действием (N / W / S / E/ НИЧЕГО) без врезаться в стену.* /
public boolean isPossibleToDoAction(int action)
{
if (action == NOTHING)
{
return false; // no way
}
IntGrid2D maze = pacman.maze;
int[][] field = maze.field;
// the Agents grid is discretized exactly on 1x1 boundaries so we can use floor rather than divide
// the agent can straddle two locations at a time. The basic location is x0, y0, and the straddled location is x1, y1.
// It may be that x0 == y0.
int x0 = (int) location.x;
int y0 = (int) location.y;
int x1 = location.x == x0 ? x0 : x0 + 1;
int y1 = location.y == y0 ? y0 : y0 + 1;
// for some actions we can only do the action if we're not straddling, or if our previous action was NOTHING
if ((x0 == x1 && y0 == y1) || lastAction == NOTHING)
{
switch (action)
{
// we allow toroidal actions
case N:
return (field[maze.stx(x0)][maze.sty(y0 - 1)] == 0);
case E:
return (field[maze.stx(x0 + 1)][maze.sty(y0)] == 0);
case S:
return (field[maze.stx(x0)][maze.sty(y0 + 1)] == 0);
case W:
return (field[maze.stx(x0 - 1)][maze.sty(y0)] == 0);
}
} // for other actions we're continuing to do what we did last time.
// assuming we're straddling, this should always be allowed unless our way is blocked
else if (action == lastAction)
{
switch (action)
{
// we allow toroidal actions
case N: // use y0
return (field[maze.stx(x0)][maze.sty(y0)] == 0);
case E: // use x1
return (field[maze.stx(x1)][maze.sty(y0)] == 0);
case S: // use y1
return (field[maze.stx(x0)][maze.sty(y1)] == 0);
case W: // use x0
return (field[maze.stx(x0)][maze.sty(y0)] == 0);
}
} // last there are reversal actions. Generally these are always allowed as well.
else if ((action == N && lastAction == S) ||
(action == S && lastAction == N) ||
(action == E && lastAction == W) ||
(action == W && lastAction == E))
{
return true;
}
return false;
}
Я считаю, что мне нужно использовать что-то вроде поиска BFS, чтобы найти кратчайший путь, я просто не знаю, как это сделать.