如何正确填充我的自定义数据结构以用于A *算法? (警告:长)

时间:2018-02-05 22:54:52

标签: java algorithm a-star

如果你想要没有上下文的TLDR: 我需要帮助找出如何正确定义和填充2D数组中的数据结构以获得路径寻找算法。滚动到我代码的底部。

我正在开发一款游戏(早期版本可用于查看/播放我的github)对于那些对地图制作程序特别好奇的人来说,这里是link to that directory on my github

如果你只是想看看游戏的功能如何更好地掌握,这里是video demo

游戏本身使用LUA加载地图,我制作了一个简单的地图制作工具,使用Java中的Swing library生成Lua。

基本前提:

Ice Runner in 2 Player Mode

  1. 从指定的起始位置导航到地图的目标。
  2. 一旦玩家开始移动,你就无法停止或改变方向,直到你碰到一堵墙。你也不能沿对角线移动。

    Pokemon Ice Tunnel

  3. 玩家可以制作自己的地图并挑战他们的朋友。
  4. 我想限制玩家只制作有效的(可赢)地图以避免沮丧。 - 我认为如何才能最好地完成此任务?

    我相信A *算法是我这样一个方法的最佳起点。但是,我需要围绕定义一个有效的路径。

    我在Java中的地图目前表示为图像图标的 2D数组。 (现在)

    按钮可以包含4个属性中的一个:

    1. 空 - 代表地板,IE是地图的正常可导航部分。
    2. 墙 - 代表墙,玩家将在接触时停止。
    3. 开始 - 表示玩家将在地图上开始的位置。
    4. 目标 - 代表玩家完成地图的图块。
    5. 这就是我所拥有的(算法未包含,因为它目前与wiki上的典型示例没什么不同)

          class Tile {
      
              JLabel payload = null; // wall, empty, goal, start
              Tile up = null;
              Tile down = null;
              Tile left = null;
              Tile right = null;
          }
      
      // Fill and return a list with the information for each tile on the map
      public static ArrayList<Tile> checkMapStatus(JLabel[][] map){
          ArrayList<Tile> mapList = new ArrayList<Tile>();
      
          for(int i = 0; i < map.length; i++){
              for(int j = 0; j < map.length; j++){
      
              // create the surrounding tiles around the current tile (needs fixing)
              Tile tile = new Tile();
              Tile tileUp = new Tile();
              Tile tileDown = new Tile();
              Tile tileLeft = new Tile();
              Tile tileRight = new Tile();
      
              tile.payload = map[i][j];
      
              if(map[j + 1] != null) // prevent accessing inexistant array position
              tileUp.payload = map[i][j+1]; 
      
              if(j > 0) // prevent accessing inexistant array position
              tileDown.payload = map[i][j-1];
      
              if(i > 0) // prevent accessing inexistant array position
              tileLeft.payload = map[i-1][j];
      
              if(map[i + 1] != null) // prevent accessing inexistant array position
              tileRight.payload = map[i+1][j];
      
              tile.up = tileUp;
              tile.down = tileDown;
              tile.left = tileLeft;
              tile.right = tileRight;
      
              mapList.add(tile);
      
              }
          }
              return mapList;
      }
      

      上述代码的问题:

      我创建的瓷砖对象在技术上并非相互连接吗?也就是说,上下左右的图块一旦创建就不会被再次引用,所以我创建了5个图块,而实际上我只应该创建1并引用现有图块。我如何在Java中解决这个问题?

      提高效率的可能性?对于我来说,仅仅定义墙,目标和起始区块是否更好?因为其他区域在技术上是空的空间?

1 个答案:

答案 0 :(得分:2)

我要做的是从一个Tile[][] temp变量开始,以帮助引用彼此的对象,并在你去的时候展平它。它的效率稍差,但不足以担心这只是为了初始化事物。

public static ArrayList<Tile> checkMapStatus(JLabel[][] map){
    ArrayList<Tile> mapList = new ArrayList<Tile>();
    Tile[][] temp = new Tile[map.length][];

    for(int i = 0; i < map.length; i++){
        temp[i] = new Tile[map[i].length];
        for(int j = 0; j < map.length; j++){

        // create the surrounding tiles around the current tile (needs fixing)
        Tile tile = new Tile();
        temp[i][j] = tile;

        tile.payload = map[i][j];
        //Just look up and to the left, populate the existing Tiles as you populate the current one
        if(i > 0 && j < temp[i-1].length){
            tile.up = temp[i-1][j];
            temp[i-1][j].down = tile;
        }
        if(j > 0){
            tile.left = temp[i][j-1];
            temp[i][j-1].right = tile;
        }


        mapList.add(tile);

        }
    }
    return mapList;
}