二维平面分支中的随机路径生成-Java
我正在制作一个随机棋盘游戏,其中路径是动态生成的。我使用的数据结构是一个2D数组,其中定义了“开始”,并随机查找下一个可用路径(上、右、下、左)。它使用一个加权随机系统,在这个系统中,它有一个沿着最后一个方向笔直前进的“趋势”。“finish”被阻止后,或完成一定数量的行走后,它停止生成 我会使用“迷宫生成算法”,但我认为它不适用于我的情况,因为我的目的不是制作迷宫,而是遍历路径 我的问题是,如何“分支”到新的轨道,生成新的路径,并在块之间留有间距 例如,我的跑步记录如下: 这一个很理想: 我还希望它能够随机地分支到新的路径。什么样的数据结构是可能的?我觉得2D阵列的功能在生成这一点上并不是很强大。任何帮助都会很好 此代码用于查找下一条路径。Tuple是一个包含用于定位的行和列的类二维平面分支中的随机路径生成-Java,java,arrays,random,Java,Arrays,Random,我正在制作一个随机棋盘游戏,其中路径是动态生成的。我使用的数据结构是一个2D数组,其中定义了“开始”,并随机查找下一个可用路径(上、右、下、左)。它使用一个加权随机系统,在这个系统中,它有一个沿着最后一个方向笔直前进的“趋势”。“finish”被阻止后,或完成一定数量的行走后,它停止生成 我会使用“迷宫生成算法”,但我认为它不适用于我的情况,因为我的目的不是制作迷宫,而是遍历路径 我的问题是,如何“分支”到新的轨道,生成新的路径,并在块之间留有间距 例如,我的跑步记录如下: 这一个很理想:
private void nextPath(){
// up, right, down, left
boolean availableNext [] = new boolean[] { false, false, false, false};
//up
if(isEmpty(new Tuple(this.lastPath.getRow() - 1, this.lastPath.getCol()))){
availableNext[0] = true;
//System.out.println("This ran");
}
//right
if(isEmpty(new Tuple(this.lastPath.getRow(), this.lastPath.getCol() + 1))){
availableNext[1] = true;
}
//down
if(isEmpty(new Tuple(this.lastPath.getRow() + 1, this.lastPath.getCol()))){
availableNext[2] = true;
}
//left
if(isEmpty(new Tuple(this.lastPath.getRow(), this.lastPath.getCol() - 1))){
availableNext[3] = true;
}
int numTrue = 0;
for(int i=0; i<availableNext.length; i++){
if(availableNext[i] == true){
numTrue ++;
}
//System.out.println(availableNext[i]);
}//end numTrueTest
if(numTrue == 0 || order == this.terminateNumber){
building = false;
this.im[lastPath.getRow()][lastPath.getCol()] = "Finish";
} else {
boolean chosenC = false;
while(!chosenC) {
int tempWeightedArr [] = new int[100];
int counter = 0;
for(int i=0; i<this.weightedDir.length; i++){
for(int j=0; j<this.weightedDir[i]; j++){
tempWeightedArr[counter] = i;
counter++;
}
}//end for
//int rnd = new Random().nextInt(availableNext.length);
int rnda = new Random().nextInt(tempWeightedArr.length);
int rnd = tempWeightedArr[rnda];
if(availableNext[rnd]){
chosenC = true;
//rnd = 0,1,2,3
if(rnd == 0){
this.im[this.lastPath.getRow() - 1][this.lastPath.getCol()] = Integer.toString(order);
this.lastPath = new Tuple(this.lastPath.getRow()-1, this.lastPath.getCol());
}
if(rnd == 1){
this.im[this.lastPath.getRow()][this.lastPath.getCol()+1] = Integer.toString(order);
this.lastPath = new Tuple(this.lastPath.getRow(), this.lastPath.getCol()+1);
}
if(rnd == 2){
this.im[this.lastPath.getRow() + 1][this.lastPath.getCol()] = Integer.toString(order);
this.lastPath = new Tuple(this.lastPath.getRow()+1, this.lastPath.getCol());
}
if(rnd == 3){
this.im[this.lastPath.getRow()][this.lastPath.getCol()-1] = Integer.toString(order);
this.lastPath = new Tuple(this.lastPath.getRow(), this.lastPath.getCol()-1);
}
for(int i=0; i<4; i++){
this.weightedDir[i] = 15;
}
this.weightedDir[rnd] = 55;
this.lastDir = rnd;
order++;
}//end if
}//end while
}//end else
}
private void nextPath(){
//上、右、下、左
布尔值availableNext[]=新布尔值[]{false,false,false,false};
//向上
if(isEmpty(新元组(this.lastPath.getRow()-1,this.lastPath.getCol())){
availableNext[0]=真;
//System.out.println(“本次运行”);
}
//对
if(isEmpty(新元组(this.lastPath.getRow(),this.lastPath.getCol()+1))){
availableNext[1]=真;
}
//向下
if(isEmpty(新元组(this.lastPath.getRow()+1,this.lastPath.getCol())){
availableNext[2]=真;
}
//左
if(isEmpty(新元组(this.lastPath.getRow(),this.lastPath.getCol()-1))){
availableNext[3]=真;
}
int numTrue=0;
对于(int i=0;i使用递归求解,构建一个启发式函数测试下一个位置
package testingforan;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class NewInnerMap {
public static final int MAX_ROWS = 20;
public static final int MIN_ROWS = 19;
public static final int MAX_COLS = 21;
public static final int MIN_COLS = 18;
public static final int MAX_LENGTH = 30;
private String [][] im;
private int numRow;
private int numCol;
private Tuple startingPosition;
public NewInnerMap(){
this.init();
}
private void init(){
this.numRow = randomBetween(NewInnerMap.MIN_ROWS, NewInnerMap.MAX_ROWS);
this.numCol = randomBetween(NewInnerMap.MIN_COLS, NewInnerMap.MAX_COLS);
this.im = new String[numRow][numCol];
this.startingPosition = this.getRandomStartingPosition();
this.generateMap();
}//end init
private void generateMap(){
this.setStringToMap("Start", startingPosition);
this.nextPath(startingPosition, -1, 0);
}
private int [] getHeuristics(Tuple pos, int lastDirection){
//top, right, bottom, left
int [] heuristic = new int[] {0,0,0,0};
Tuple top = new Tuple(pos.getRow() - 1, pos.getCol());
Tuple right = new Tuple(pos.getRow(), pos.getCol()+ 1);
Tuple bottom = new Tuple(pos.getRow() + 1, pos.getCol());
Tuple left = new Tuple(pos.getRow(), pos.getCol() - 1);
//top
if(pos.getRow() - 1 >= 0){
heuristic[0] += this.getHeuristicForPositionBasedOnNumSurroundings(top);
//heuristic for going straight is given a random chance
if(lastDirection == 0){
heuristic[0] += randomBetween(0,3);
}//end if
}
if(pos.getCol()+1 < im[0].length){
//right
heuristic[1] += this.getHeuristicForPositionBasedOnNumSurroundings(right);
if(lastDirection == 1){
heuristic[1] += randomBetween(0,3);
}
}
if(pos.getRow()+1 < im.length){
//bottom
heuristic[2] += this.getHeuristicForPositionBasedOnNumSurroundings(bottom);
//heuristic for going straight is given a random chance
if(lastDirection == 2){
heuristic[2] += randomBetween(0,3);
}//end if
}
if(pos.getCol() - 1 >= 0){
//left
heuristic[3] += this.getHeuristicForPositionBasedOnNumSurroundings(left);
//heuristic for going straight is given a random chance
if(lastDirection == 3){
heuristic[3] += randomBetween(0,3);
}//end if
}
return heuristic;
}//emnd getHeuristics
/*
exists piece -> -1
no empty surrounding -> -1
1 empty surrounding -> -1
2 empty surrounding -> -1
3 empty surrounding -> 10
*/
private int getHeuristicForPositionBasedOnNumSurroundings(Tuple pos){
if(this.im[pos.getRow()][pos.getCol()] != null ||
this.numEmptySurrounding(pos) == 1 ||
this.numEmptySurrounding(pos) == 2 ){
return -100;
} else {
return 15;
//return this.numEmptySurrounding(pos);
}
}//end getHeuristicForPositionBasedOnNumSurroundings
/*
startPath -> find next possible moves
next possible moves -> store in array, give them a weight
should not border other than previous = max weight
going straight = weighted
if -> this path is 3 empty, possibly branch
*/
public void nextPath(Tuple lastPos, int dir, int depth){
int [] fh = this.getHeuristics(lastPos, dir);
int max = maxFromIntArray(fh);
if(fh[max] <= 5 || depth >= NewInnerMap.MAX_LENGTH){
im[lastPos.getRow()][lastPos.getCol()] = "Finish";
}//end if
else if(im[lastPos.getRow()][lastPos.getCol()] != null){
if(im[lastPos.getRow()][lastPos.getCol()].equals("Start")){
this.nextPath(this.getNextPositionBasedOnDirection(lastPos, max), max, depth+1);
}
}//end else if
else{
im[lastPos.getRow()][lastPos.getCol()] = Integer.toString(depth);
this.nextPath(this.getNextPositionBasedOnDirection(lastPos, max), max, depth+1);
}//end else
}//end
/*
HEURISTIC BUILDERS ------------------
*/
private boolean [] nextEmpty(Tuple pos){
boolean [] availableNext = new boolean[]{false, false, false, false};
//up
if(isEmpty(new Tuple(pos.getRow() - 1, pos.getCol()))){
availableNext[0] = true;
}
//right
if(isEmpty(new Tuple(pos.getRow(), pos.getCol() + 1))){
availableNext[1] = true;
}
//down
if(isEmpty(new Tuple(pos.getRow() + 1, pos.getCol()))){
availableNext[2] = true;
}
//left
if(isEmpty(new Tuple(pos.getRow(), pos.getCol() - 1))){
availableNext[3] = true;
}
return availableNext;
}//end numSurrounding
private int numEmptySurrounding(Tuple pos){
boolean [] avaN = this.nextEmpty(pos);
int emptySurrounding = 0;
/* if(pos.getRow() == 0
|| pos.getRow() == im.length - 1
){
emptySurrounding ++;
}
if(pos.getCol() == 0
|| pos.getCol() == im[0].length - 1
){
emptySurrounding++;
}
*/
for(int i=0; i<avaN.length; i++){
if(avaN[i] == true) { emptySurrounding++; }
}//end for
return emptySurrounding;
}//end numEmptySurrounding
private boolean isEmpty(Tuple testPos){
if(testPos.getRow() >= 0 && testPos.getCol() >= 0 && testPos.getRow() < this.im.length && testPos.getCol() < this.im[0].length) {
if (this.im[testPos.getRow()][testPos.getCol()] == null) {
return true;
}
}//end if
return false;
}//end isEmpty
private Tuple getNextPositionBasedOnDirection(Tuple pos, int dir){
if(dir == 0){
return new Tuple(pos.getRow() - 1, pos.getCol());
}
else if(dir == 1){
return new Tuple(pos.getRow(), pos.getCol() + 1);
}
else if(dir == 2){
return new Tuple(pos.getRow() + 1, pos.getCol());
}
else if (dir == 3){
return new Tuple(pos.getRow(), pos.getCol() -1);
}
return new Tuple(-1,-1);
}
/*
UTILITY CLASSES ----------------------------
*/
private void setStringToMap(String s, Tuple pos){
this.im[pos.getRow()][pos.getCol()] = s;
}
private void setIntToMap(int i, Tuple pos){
this.setStringToMap(Integer.toString(i), pos);
}
private static int randomBetween(int min, int max){
Random r = new Random();
return r.nextInt((max-min)+1) + min;
}//end randomBetween
private Tuple getRandomStartingPosition(){
return new Tuple(randomBetween(0,im.length-1), randomBetween(0,im[0].length-1));
}//end getRandomStartingPosition
private Tuple getRandomStartingPosition(Tuple min, Tuple max){
return new Tuple(randomBetween(min.getRow(),max.getRow()), randomBetween(min.getCol(), max.getCol()));
}//end getRandomStartingPosition
private static int maxFromIntArray(int [] arr){
List <Integer> numMax = new ArrayList<>();
int max = 0;
numMax.add(max);
for(int i=1; i<arr.length; i++){
if(arr[i] > arr[max]){
numMax.removeAll(numMax);
max = i;
numMax.add(i);
} else if(arr[i] == arr[max]){
numMax.add(i);
}
}
return numMax.get(randomBetween(0,numMax.size()-1));
}//end maxFromIntArray
public String [][] getIm(){
return this.im;
}
}//end class
package-testingforan;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.Collections;
导入java.util.List;
导入java.util.Random;
公共类NewInnerMap{
公共静态最终整数最大行数=20;
公共静态最终整数最小行数=19;
公共静态最终整数最大值=21;
公共静态最终整数最小值=18;
公共静态最终整数最大长度=30;
私有字符串[][]im;
私人国际机场;
私有国际货币基金组织;
私有元组起始位置;
公共NewInnerMap(){
this.init();
}
私有void init(){
this.numRow=randomBetween(NewInnerMap.MIN\u行,NewInnerMap.MAX\u行);
this.numCol=randomBetween(NewInnerMap.MIN\u COLS,NewInnerMap.MAX\u COLS);
this.im=新字符串[numRow][numCol];
this.startingPosition=this.getRandomStartingPosition();
这个.generateMap();
}//结束初始化
私有void generateMap(){
此设置字符串映射(“启动”,启动位置);
此.nextPath(起始位置,-1,0);
}
私有int[]getHeuristics(元组位置,int lastDirection){
//上、右、下、左
int[]启发式=新的int[]{0,0,0};
Tuple top=新的Tuple(位置getRow()-1,位置getCol());
元组右=新元组(位置getRow(),位置getCol()+1);
Tuple bottom=新的Tuple(位置getRow()+1,位置getCol());
Tuple left=新元组(pos.getRow(),pos.getCol()-1);
//顶
如果(位置getRow()-1>=0){
启发式[0]+=this.GetHeuristicForPositionBasedOnNumEnvironment(顶部);
//给出了一个随机的机会来进行直线运动
如果(lastDirection==0){
启发式[0]+=介于(0,3)之间的随机数;
}//如果结束
}
if(位置getCol()+1=0){
//左
启发式[3]+=this.GetHeuristicForPositionBasedOnNumEnvironment(左);
//给出了一个随机的机会来进行直线运动
如果(lastDirection==3){
启发式[3]+=介于(0,3)之间的随机数;
}//如果结束
}
返回启发式;
}//emnd启发式
/*
存在件->-1
无空周围->-1
1空周围->-1
2空周围->-1
3空周围->10
*/
私有int GetHeuristicForPositionBasedOnNumEnvironment(元组位置){
如果(this.im[pos.getRow()][pos.getCol()]!=null||
此.numEmptySurrounding(pos)==1||
此.numEmptySurrounding(pos)==2){
返回-100;
}否则{
返回15;
//返回此.numpTysUrounding(pos);
}
}//end GetHeuristicForPositionBasedOnNumEnvironment
/*
开始路径->查找下一步可能的移动
下一步可能的移动->存储在阵列中,给它们一个权重
不应为上一个=最大重量以外的边框
直行=加权
如果->此路径为3空,则可能为分支
*/
public void nextPath(元组lastPos、int dir、int depth){
int[]fh=this.getHeuristics(lastPos,dir);
int max=最大FROMINTARRAY(fh);
if(fh[max]=NewInnerMap.max\u长度){
im[lastPos.getRow()][lastPos.getCol()]=“完成”;
}//如果结束
else if(im[lastPos.getRow()][lastPos.getCol()]!=null){
如果(im[lastPos.getRow()][lastPos.getCol()].equals(“Start”)){
this.nextPath(this.getNextPositionBased