Javascript 随机路径总是被卡住

Javascript 随机路径总是被卡住,javascript,algorithm,path,grid,Javascript,Algorithm,Path,Grid,嗨,我想写一个塔防游戏。 我目前正试图建立一条暴徒们将遵循的道路 但我的路总是被自己卷起来 路径的工作方式是使用二维阵列、栅格。由包含iPath属性的单元格对象组成的40行40列 我创建路径的方法是选择一个随机方向,然后检查我们试图访问的单元是否已经是路径的一部分,并且它不会与多个单元(它来自的单元)发生碰撞。我还要看看我是否在第一列,我们不想向左走,因为下一个单元格将在最后一列的上排结束。在最后一列向右走也是一样 以下是我为路径算法编写的内容: function createPath(){

嗨,我想写一个塔防游戏。 我目前正试图建立一条暴徒们将遵循的道路

但我的路总是被自己卷起来

路径的工作方式是使用二维阵列、栅格。由包含iPath属性的单元格对象组成的40行40列

我创建路径的方法是选择一个随机方向,然后检查我们试图访问的单元是否已经是路径的一部分,并且它不会与多个单元(它来自的单元)发生碰撞。我还要看看我是否在第一列,我们不想向左走,因为下一个单元格将在最后一列的上排结束。在最后一列向右走也是一样

以下是我为路径算法编写的内容:

function createPath(){

var indexesOfCellsInLastCol = new Array();
for(var o = NumberOfRow; o < (NumberOfRow * NumberOfRow); o+= NumberOfRow)
    indexesOfCellsInLastCol.push(o);

var indexesOfCellsInFirstCol = new Array();
for(var k = 1; k < (NumberOfRow * NumberOfRow); k+= NumberOfRow)
    indexesOfCellsInFirstCol.push(k);

var usedDirection = [];

var x = 0;
var y = 0;

 // random walk without crossing
 for(var i = 0; i < 50000; i++){
    var direction = Math.floor((Math.random()*4));

    //always start the same way
    if(i < 10){
        if(i == 9){
            grid[2][i].isPath = true;
            grid[1][i].isPath = true;
            x = i;
            y = 2;
        }
        grid[0][i].isPath = true;
    }   
    else
    {
        switch(direction){
            //left
            case 0: 
                if(!contains(usedDirection, 0)){
                    if(collideDirection(y,x - 1) == 1){
                        //check if you are not in first col, because if you go left while you're in first                     col you go back to last row.
                        if(!contains(indexesOfCellsInFirstCol, x) && !grid[y][x - 1].isPath){
                            grid[y][x - 1].isPath = true;
                            x--;
                            usedDirection = [];
                        }
                        else
                            usedDirection.push(0);
                    }
                }
            break;
            //up
            case 1:
                if(!contains(usedDirection, 1)){
                    if(collideDirection(y - 1,x) == 1){
                        if(y - 1 > 1 && !grid[y - 1][x].isPath){
                            grid[y - 1][x].isPath = true;
                            y--;
                            usedDirection = [];
                        }
                        else
                            usedDirection.push(1);
                    }
                }                   
            break;
            //right
            case 2:
                if(!contains(usedDirection, 2)){                
                    if(collideDirection(y,x + 1) == 1){
                        //same as going left whil you're on the first col
                        if(!contains(indexesOfCellsInLastCol, x) && !grid[y][x + 1].isPath){
                            grid[y][x + 1].isPath = true;
                            x++;
                            usedDirection = [];
                        }
                        //don't be no fool and try to repeat your self
                        else
                            usedDirection.push(2);
                    }
                }                   
            break
            //down
            case 3:
                if(!contains(usedDirection, 3)){
                    if(collideDirection(y + 1,x) == 1 ){
                        if((y + 1 < (NumberOfRow - 1)) && !grid[y + 1][x].isPath){
                            grid[y + 1][x].isPath = true;
                            y++;
                            usedDirection = [];
                        }
                        else
                            usedDirection.push(3);
                    }   
                }                   
            break;
        }
    }
 }
函数createPath(){
var indexesOfCellsInLastCol=新数组();
对于(变量o=NumberOfRow;o<(NumberOfRow*NumberOfRow);o+=NumberOfRow)
最后柱推力(o)的单元指数;
var indexesOfCellsInFirstCol=新数组();
对于(变量k=1;k<(NumberOfRow*NumberOfRow);k+=NumberOfRow)
第一列单元的指数(k);
var usedDirection=[];
var x=0;
var y=0;
//无交叉随机行走
对于(变量i=0;i<50000;i++){
var direction=Math.floor((Math.random()*4));
//总是以同样的方式开始
如果(i<10){
如果(i==9){
网格[2][i].isPath=true;
网格[1][i].isPath=true;
x=i;
y=2;
}
网格[0][i]。isPath=true;
}   
其他的
{
开关(方向){
//左
案例0:
如果(!contains(usedDirection,0)){
如果(碰撞方向(y,x-1)==1){
//检查你们是否在第一列,因为若你们在第一列时向左走,你们会回到最后一行。
如果(!contains(indexesOfCellsInFirstCol,x)&&!grid[y][x-1].isPath){
网格[y][x-1]。isPath=true;
x--;
usedDirection=[];
}
其他的
usedDirection.push(0);
}
}
打破
//向上
案例1:
如果(!contains(usedDirection,1)){
如果(碰撞方向(y-1,x)==1){
如果(y-1>1&&!网格[y-1][x].isPath){
网格[y-1][x].isPath=true;
y--;
usedDirection=[];
}
其他的
使用方向。推(1);
}
}                   
打破
//对
案例2:
如果(!contains(usedDirection,2)){
如果(碰撞方向(y,x+1)==1){
//就像你在第一个山口向左走一样
如果(!contains(indexesOfCellsInLastCol,x)&&!grid[y][x+1].isPath){
网格[y][x+1]。isPath=true;
x++;
usedDirection=[];
}
//别傻了,试着重复你自己
其他的
使用方向。推(2);
}
}                   
打破
//向下
案例3:
如果(!contains(usedDirection,3)){
如果(碰撞方向(y+1,x)==1){
如果((y+1<(NumberOfRow-1))&&!网格[y+1][x].isPath){
网格[y+1][x].isPath=true;
y++;
usedDirection=[];
}
其他的
使用方向。推(3);
}   
}                   
打破
}
}
}
}

我已经把我所有的代码放在一个js小提琴

我不需要一个代码,也许只是一个提示,告诉我应该去哪里或者我应该做什么

我想看一看,如果这条路左转超过3次,那么它就必须向右走。但我认为它会沿着一条过于线性的路径上升

有什么想法吗


谢谢你的支持

下面是一个在二维网格上随机行走的Java实现,没有交叉点。关于它的一些注意事项:

1) 我没有重复处理不同方向的代码,而是使用一个预定义的4个方向的列表([-1,0],[0,1],[1,0],[0,1]),并在每次扫描所有可能的方向时将其洗牌以继续

2) 你的解决方案似乎失败了,因为它不涉及任何回溯-每次你到达一个死胡同,你应该回到上一步,并尝试采取另一个方向。我使用递归使回溯变得简单

3) 该算法是递归的,因此对于长路径,它可能会因StackOverflower错误而失败。如果需要长路径工作,请考虑使用堆栈来模拟递归。

4) 该算法不处理边界矩形。这需要稍作修改

public class RandomPathCreator {
  private final static List<Location> DIRECTIONS = Arrays.asList(new Location[]{new Location(-1, 0), new Location(0, -1), new Location(1, 0), new Location(0, 1)});

  public static Path randomPath(int len) {
    Path path = new Path();
    path.append(new Location(0,0)); //The random walk starts from [0,0]
    findPath(len, path);
    return path;
  }

  ///////////////////////////////
  // The main logic is here
  ///////////////////////////////
  private static boolean findPath(int len, Path path) {
    if (path.size() == len)
      return true;

    Location lastPos = path.getLast();
    Collections.shuffle(DIRECTIONS);
    for (Location dir : DIRECTIONS) {
      Location newPos = lastPos.add(dir);
      if (path.append(newPos)) {
        if (findPath(len, path))
          return true;
        path.removeLast();
      }      
    }
    return false;
  }

  private static class Location {
    public final int x;
    public final int y;

    public Location(int x, int y) {
      this.x = x;
      this.y = y;
    }

    public Location add(Location other) {
      return new Location(x + other.x, y + other.y);
    }

    @Override
    public int hashCode() {
      return 31 * (31 + x) + y;
    }

    @Override
    public boolean equals(Object obj) {
      Location other = (Location) obj;
      return (x == other.x && y == other.y); 
    }

    @Override
    public String toString() {
      return "Location [x=" + x + ", y=" + y + "]";
    }
  }

  private static class Path {
    private List<Location> list = new ArrayList<Location>();
    private Set<Location> set = new HashSet<Location>();

    public boolean append(Location l) {
      if (set.add(l)) {
        list.add(l);
        return true;
      }
      return false;
    }

    public Location getLast() {
      return list.get(list.size() - 1);
    }

    public void removeLast() {
      Location last = list.remove(list.size() - 1);
      set.remove(last);
    }

    public int size() {
      return list.size();
    }

    @Override
    public String toString() {
      return list.toString();
    }
  }
}
公共类RandomPathCreator{
私有最终静态列表方向=Arrays.asList(新位置[]{new Location(-1,0),新位置(0,-1),新位置(1,0),新位置(0,1)});
公共静态路径随机路径(int len){
路径路径=新路径();
append(新位置(0,0));//随机游动从[0,0]开始
findPath(len,path);
返回路径;
}
///////////////////////////////
//主要的逻辑在这里
///////////////////////////////
私有静态布尔findPath(int len,Path){
if(path.size()==len)
返回true;
Location lastPos=path.getLast();
收藏。洗牌(方向);