首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >迷宫导航仪AI

迷宫导航仪AI
EN

Code Review用户
提问于 2019-01-10 14:04:59
回答 1查看 134关注 0票数 3

我在Java为我的学校开发了一个迷宫导航器。它工作得很好,而且还能穿过迷宫。程序每次在迷宫中循环以设置下一个位置时都会打印到屏幕上。注意:只有一个路径,因为我还没有实现多路径算法。有没有办法让这个更优雅、更有效率?我希望减少的主要事情是(如果可能的话):

  • 开关/案例陈述
  • 内存(每次重新打印到屏幕上)
  • 使程序更高效/更优雅的代码改进

欢迎任何和所有建议/改进。

代码语言:javascript
运行
复制
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;
        }
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2019-01-11 07:47:18

到目前为止干得不错!我有一些意见,希望你能找到有用的。

尝试不同的算法:)

请参阅维基百科的这篇文章,其中列出了解决迷宫的可能算法:

https://en.wikipedia.org/wiki/Maze_解_算法

重用代码

此开关块在代码中出现1.5次。考虑让它成为一种方法。

代码语言:javascript
运行
复制
               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;

删除不必要的代码

你用这个:

代码语言:javascript
运行
复制
   if(arr[pos[0]][pos[1] - 1] == 0) {
        return true;
   } else {
   return false;
   }

可以重写到:

代码语言:javascript
运行
复制
    return arr[pos[0]][pos[1] - 1] == 0;

这对我来说更清楚了:)

AIOOBE与边界检查

您目前让canMove抛出一个ArrayIndexOutOfBoundsException。有些人认为这种做法不好,因为这是“正常”的流程。你应该先检查一下你的索引是否有效。

字符串级联

尝试使用+操作符来防止字符串连接。它创建了许多不必要的中间对象。

另见此处:https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8

考虑直接使用char

您的内存模型是一个int[][]。您的代码使用测试int值的“神奇值”。char也非常适合作为网格中的值使用,然后您可以直接打印和测试这些char值。构建网格可以从带有StringstoCharArray()列表开始,代码中的迷宫看起来与控制台上的输出完全相同。

(否则,至少在int语句中为if S创建可读的常量)

考虑在enum :

中编写说明

代码语言:javascript
运行
复制
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);
   }
}

就像这样:

代码语言:javascript
运行
复制
  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;
        }
    }
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/211261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档