[英]A* in Javascript (with p5.js) not working
我正在為位於二維正方形陣列中的玩家編寫尋路算法。 我想找到從a到b的最短路徑,並有效地做到這一點。 之前我在Java(處理)中工作,而我的功能也很好。
boolean findPath(PVector down, PVector up, Square[][] board) {
PVector start = up;
PVector goal = down;
ArrayList<Square> closedSet = new ArrayList<Square>();
ArrayList<Square> openSet = new ArrayList<Square>();
HashMap<Square, Square> cameFrom = new HashMap<Square, Square>((int)Math.pow(squares, 2));
HashMap<Square, Float> gScore = new HashMap<Square, Float>((int)Math.pow(squares, 2));
HashMap<Square, Float> fScore = new HashMap<Square, Float>((int)Math.pow(squares, 2));
for (int i = 0; i<dungeon.floors.get(currentFloor).numSquares; i++) {
for (int j = 0; j<dungeon.floors.get(currentFloor).numSquares; j++) {
gScore.put(board[i][j], 1000.0);
}
}
gScore.put(board[(int)start.x][(int)start.y], 0.0);
fScore.put(board[(int)start.x][(int)start.y], heuristic(start, goal));
openSet.add(board[(int)start.x][(int)start.y]);
while (!openSet.isEmpty()) {
Square current = board[(int)start.x][(int)start.y];
float lowest = 1000;
for (Square s : openSet) {
if (fScore.get(s)<lowest) {
lowest = fScore.get(s);
current = s;
}
}
if (current.locX == goal.x && current.locY == goal.y) {
while (cameFrom.containsKey(current)) {
current = cameFrom.get(current);
}
board[(int)start.x][(int)start.y].squareType = -3;
return true;
}
openSet.remove(current);
closedSet.add(current);
//neighbors() returns an ArrayList of valid neighbors
for (Square s : current.neighbors(board)) {
if (closedSet.contains(s)) {
} else {
float tempG = gScore.get(current) + 1;
if (!openSet.contains(s)) {
openSet.add(s);
}
if (tempG < gScore.get(s)) {
cameFrom.put(s, current);
gScore.put(s, tempG);
fScore.put(s, gScore.get(s) + heuristic(new PVector(s.locX, s.locY), goal));
}
}
}
}
return false;
}
float heuristic(PVector start, PVector goal) {
return dist(start.x, start.y, goal.x, goal.y);
}
但是我正在將游戲遷移到Javascript,但是我無法確定我的代碼出了什么問題。 它被卡在一個正方形上,並將其永久添加到closedSet中(數十萬次)。 這是我的Javascript代碼-
this.findPath = function(f, _start, _goal) {
var start = _start;
var goal = _goal;
var closedSet = [];
var openSet = [];
var squareScores = [];
var startSquare = (start.x * numSquares) + start.y;
for (var i = 0; i < numSquares; i++) {
for (var j = 0; j < numSquares; j++) {
squareScores.push(new MapSquare(dungeon.floors[f].board[i][j], 10000, 10000));
}
}
squareScores[startSquare].gScore = 0;
squareScores[startSquare].fScore = this.heuristic(start, goal);
openSet.push(squareScores[startSquare]);
while (openSet.length > 0) {
var current = squareScores[startSquare];
var lowest = 9999;
for (var s = 0; s < squareScores.length; s++) {
if (squareScores[s].fScore < lowest) {
lowest = squareScores[s].fScore;
current = squareScores[s];
}
}
if (current.square.x == goal.x && current.square.y == goal.y) {
return true;
}
openSet.splice(openSet.indexOf(current.square));
closedSet.push(current.square);
var currentNeighbors = current.square.neighbors(dungeon.floors[f].board);
for (var i = 0; i < currentNeighbors.length; i++) {
var skip = false;
for (let c of closedSet) {
if (c.x == currentNeighbors[i].x && c.y == currentNeighbors[i].y) {
skip = true;
}
}
if (skip) {
continue;
}
else {
var tempG = current.gScore + 1;
var dontAdd = false;
for (let o of openSet) {
if (o.x == currentNeighbors[i].x && o.y == currentNeighbors[i].y) {
dontAdd = true;
}
}
if (!dontAdd) {
openSet.push(currentNeighbors[i]);
}
var index = (currentNeighbors[i].x * numSquares) + currentNeighbors[i].y;
if (tempG < squareScores[index].gScore) {
//cameFrom.push(gScore[i]);
console.log("update");
squareScores[index].gScore = tempG;
squareScores[index].fScore = squareScores[index].gScore + this.heuristic(squareScores[index].square.x, squareScores[index].square.y, goal.x, goal.y);
}
}
}
}
return false;
};
//dist from player to goal
this.heuristic = function(_x1, _y1, _x2, _y2) {
return dist(_x1, _y1, _x2, _y2);
};
我的Javascript代碼看起來有些不同,因為我已經嘗試修復了幾天,但是我無法弄清楚。 我究竟做錯了什么? 如果需要澄清代碼,請詢問。
您將不得不調試代碼。 該鏈接與處理中的調試有關,但是相同的思想也適用於JavaScript和P5.js。
具體來說,您需要准確確定代碼的執行時間與預期的執行時間不同。
您可以通過添加做到這一點console.log()
語句要弄清楚的變量,它的功能被稱為以什么順序的價值,無論是if
語句輸入,多少次的循環迭代,等等。
如果這不起作用,您還可以使用調試器逐步執行代碼。 每個瀏覽器都帶有JavaScript調試器,該調試器可讓您單步執行代碼並檢查每個變量的值。 再次,目標是弄清楚代碼什么時候做了與您期望的不同的事情。
當您將問題縮小到幾行時,如果仍然不知道如何解決它,則可以創建一個MCVE來隔離問題,而無需解決所有額外的代碼。 到那時,為您提供幫助將更加容易。 祝好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.