我在Java为我的学校开发了一个迷宫导航器。它工作得很好,而且还能穿过迷宫。程序每次在迷宫中循环以设置下一个位置时都会打印到屏幕上。注意:只有一个路径,因为我还没有实现多路径算法。有没有办法让这个更优雅、更有效率?我希望减少的主要事情是(如果可能的话):
欢迎任何和所有建议/改进。
public class MazeAI {
//maze layout below
static int[][] maze =
{{1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1},
{1,0,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,0,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1},
{1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,0,0,0,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1},
{1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,1},
{1,1,0,0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1},
{1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1},
{1,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1},
{1,1,1,0,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},
{1,1,1,1,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};
public static void main() {
MazeAI m = new MazeAI();
m.runAI(23,11); //where S is
}
void printMaze() {
System.out.println(" MAZE ");
System.out.println();
for(int i = 0; i < maze.length; i++) {
String output = "";
for(int j = 0; j < 50; j++) {
switch(maze[i][j]) {
case 0: output += " "; break;
case 1: output += "@"; break;
case 2: output += "S"; break;
case 3: output += "E"; break;
}
}
System.out.println(output);
}
System.out.println();
}
void printPath(int[][] array, boolean last) {
System.out.println(" PATH ");
System.out.println();
if(last) {
array[1][1] = 4;
}
for(int i = 0; i < array.length; i++) {
String output = "";
for(int j = 0; j < 50; j++) {
switch(array[i][j]) {
case 0: output += " "; break;
case 1: output += "@"; break;
case 2: output += "S"; break;
case 3: output += "E"; break;
case 4: output += "^"; break;
case 5: output += "v"; break;
case 6: output += "<"; break;
case 7: output += ">"; break;
}
}
System.out.println(output);
}
System.out.println();
}
void runAI(int i, int j) { //S is at (i,j) -> (9,11) | E is at (0,1)
try {
printMaze();
Thread.sleep(3000);
System.out.print('\f');
} catch (Exception e) {
e.printStackTrace();
}
int[][] arr = maze;
int[] currentPos = {i,j};
boolean running = true;
while(running) {
if(foundEnd(currentPos)) {
running = false;
printPath(arr, true);
break;
}
if(canMoveUp(arr, currentPos)) {
arr[currentPos[0]][currentPos[1]] = 4;
currentPos[0] -= 1;
} else if(canMoveDown(arr, currentPos)) {
arr[currentPos[0]][currentPos[1]] = 5;
currentPos[0] += 1;
} else if(canMoveLeft(arr, currentPos)) {
arr[currentPos[0]][currentPos[1]] = 6;
currentPos[1] -= 1;
} else if(canMoveRight(arr, currentPos)) {
arr[currentPos[0]][currentPos[1]] = 7;
currentPos[1] += 1;
}
printPath(arr, false);
try {
Thread.sleep(150);
} catch (Exception e) {
e.printStackTrace();
}
System.out.print('\f');
}
}
boolean canMoveUp(int[][] arr, int[] pos) {
try {
if(arr[pos[0] - 1][pos[1]] == 0) {
return true;
} else {
return false;
}
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
return false;
}
}
boolean canMoveDown(int[][] arr, int[] pos) {
try {
if(arr[pos[0] + 1][pos[1]] == 0) {
return true;
} else {
return false;
}
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
return false;
}
}
boolean canMoveRight(int[][] arr, int[] pos) {
try {
if(arr[pos[0]][pos[1] + 1] == 0) {
return true;
} else {
return false;
}
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
return false;
}
}
boolean canMoveLeft(int[][] arr, int[] pos) {
try {
if(arr[pos[0]][pos[1] - 1] == 0) {
return true;
} else {
return false;
}
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
return false;
}
}
boolean foundEnd(int[] pos) {
if(pos[0] == 1 && pos[1] == 1) {
return true;
} else {
return false;
}
}
}发布于 2019-01-11 07:47:18
到目前为止干得不错!我有一些意见,希望你能找到有用的。
请参阅维基百科的这篇文章,其中列出了解决迷宫的可能算法:
https://en.wikipedia.org/wiki/Maze_解_算法
此开关块在代码中出现1.5次。考虑让它成为一种方法。
case 0: output += " "; break;
case 1: output += "@"; break;
case 2: output += "S"; break;
case 3: output += "E"; break;
case 4: output += "^"; break;
case 5: output += "v"; break;
case 6: output += "<"; break;
case 7: output += ">"; break;你用这个:
if(arr[pos[0]][pos[1] - 1] == 0) {
return true;
} else {
return false;
}可以重写到:
return arr[pos[0]][pos[1] - 1] == 0;这对我来说更清楚了:)
您目前让canMove抛出一个ArrayIndexOutOfBoundsException。有些人认为这种做法不好,因为这是“正常”的流程。你应该先检查一下你的索引是否有效。
尝试使用+操作符来防止字符串连接。它创建了许多不必要的中间对象。
另见此处:https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8
您的内存模型是一个int[][]。您的代码使用测试int值的“神奇值”。char也非常适合作为网格中的值使用,然后您可以直接打印和测试这些char值。构建网格可以从带有Strings的toCharArray()列表开始,代码中的迷宫看起来与控制台上的输出完全相同。
(否则,至少在int语句中为if S创建可读的常量)
中编写说明
enum Direction {
UP(0,-1), LEFT(-1,0), RIGHT(1,0), DOWN(0,1);
int dx;
int dy;
Direction(dx, dy)
{
this.dx=dx;
this.dy=dy;
}
}
for (Direction d : Direction.values())
{
if (canMove(arr, currentPos, direction))
{
markMove(arr, currentPos, direction);
}
}就像这样:
boolean canMove(int[][] arr, int[] pos, Direction d) {
try {
return arr[pos[0] + d.dx][pos[1] + d.dy] == 0
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
return false;
}
}https://codereview.stackexchange.com/questions/211261
复制相似问题