From d2d6fc4dd45cc672b9ff4ded43f51a1b7b1779db Mon Sep 17 00:00:00 2001 From: Bryson Zimmerman Date: Thu, 14 Nov 2024 13:22:38 -0500 Subject: [PATCH] Moved fValue functions into the pathfinding algorithms and pass it to TileHeap for use --- src/main/kotlin/ArrayBackedPathfinder.kt | 17 +++++++++++++---- src/main/kotlin/MapBackedPathfinder.kt | 12 +++++++++++- src/main/kotlin/data/TileHeap.kt | 16 ++++------------ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/ArrayBackedPathfinder.kt b/src/main/kotlin/ArrayBackedPathfinder.kt index 3263fc0..3c6f01d 100644 --- a/src/main/kotlin/ArrayBackedPathfinder.kt +++ b/src/main/kotlin/ArrayBackedPathfinder.kt @@ -3,6 +3,8 @@ package technology.zim import technology.zim.data.Directions import technology.zim.data.Tile import technology.zim.data.TileHeap +import technology.zim.data.TileNavigatedArray +import kotlin.math.abs //A* pathfinder backed by an array to improve efficiency @@ -11,7 +13,7 @@ import technology.zim.data.TileHeap object ArrayBackedPathfinder { //TODO: Replace with array for coordinate lookups for speed, do it in a separate pathfinder class to demonstrate the difference - val gVals = HashMap() + val gVals = TileNavigatedArray() //work along the path, marking tiles with VISITED along the way //if marking with visited is too expensive, just make the path and finalize it fun generatePath(start: Tile, end: Tile) { @@ -24,10 +26,10 @@ object ArrayBackedPathfinder { return } - val frontier = TileHeap(end, gVals) + val frontier = TileHeap(end, this::fValue) //Prime the things - gVals.put(start, 0) + gVals.set(start, 0) frontier.insert(start) var current: Tile @@ -44,7 +46,7 @@ object ArrayBackedPathfinder { if(candidateTile.isInBounds() && candidateG == -1) { //Otherwise, the tile has been reached and this path is not better, so carry on - gVals.put(candidateTile, currentG + 1) + gVals.set(candidateTile, currentG + 1) frontier.insert(candidateTile) World.update(candidateTile, candidateTile.getProperties() +Directions.FRONTIER) } @@ -74,4 +76,11 @@ object ArrayBackedPathfinder { World.update(start, start.getProperties() + Directions.INPATH) } + private fun fValue(prospect: Tile, end: Tile): Int { + return hValue(prospect, end).plus(MapBackedPathfinder.gVals.get(prospect) ?: 0) + } + + private fun hValue(prospect: Tile, end:Tile): Int { + return abs(prospect.x() - end.x()) + abs(prospect.y() - end.y()) + } } \ No newline at end of file diff --git a/src/main/kotlin/MapBackedPathfinder.kt b/src/main/kotlin/MapBackedPathfinder.kt index a953b37..9d27c5a 100644 --- a/src/main/kotlin/MapBackedPathfinder.kt +++ b/src/main/kotlin/MapBackedPathfinder.kt @@ -3,6 +3,7 @@ package technology.zim import technology.zim.data.Directions import technology.zim.data.Tile import technology.zim.data.TileHeap +import kotlin.math.abs //A* to be upgraded with hierarchies @@ -23,7 +24,7 @@ object MapBackedPathfinder { return } - val frontier = TileHeap(end, gVals) + val frontier = TileHeap(end, this::fValue) //Prime the things gVals.put(start, 0) @@ -52,6 +53,15 @@ object MapBackedPathfinder { //At this point, a path is found println("Path found!") + markPath(start, end) + } + + private fun fValue(prospect: Tile, end: Tile): Int { + return hValue(prospect, end).plus(gVals.get(prospect) ?: 0) + } + + private fun hValue(prospect: Tile, end:Tile): Int { + return abs(prospect.x() - end.x()) + abs(prospect.y() - end.y()) } fun markPath(start: Tile, end:Tile) { diff --git a/src/main/kotlin/data/TileHeap.kt b/src/main/kotlin/data/TileHeap.kt index 9f53cbd..36b4e26 100644 --- a/src/main/kotlin/data/TileHeap.kt +++ b/src/main/kotlin/data/TileHeap.kt @@ -6,7 +6,7 @@ import kotlin.math.abs //Translated code from CS222 MaxHeap homework //Cannot use index 0 due to Integer limitations //TODO: Consider better options than passing in the information this thing needs -class TileHeap(val end: Tile, val gVals: HashMap) { +class TileHeap(val end: Tile, val fValue:(Tile, Tile) -> Int) { val dat = ArrayList() init { //Shove some data into the zero slot @@ -36,7 +36,7 @@ class TileHeap(val end: Tile, val gVals: HashMap) { if(dat.isEmpty()) throw ArrayIndexOutOfBoundsException() - if(fValue(dat[index]) < fValue(dat[parent(index)]) && index > 1) { + if(fValue(dat[index], end) < fValue(dat[parent(index)], end) && index > 1) { swap(index, parent(index)) siftUp(parent(index)) } @@ -47,12 +47,12 @@ class TileHeap(val end: Tile, val gVals: HashMap) { var minValueIndex = index val l = leftChild(index) - if(l < dat.size && fValue(dat[l]) < fValue(dat[minValueIndex]) ) { + if(l < dat.size && fValue(dat[l], end) < fValue(dat[minValueIndex], end) ) { minValueIndex = l } val r = rightChild(index) - if(r < dat.size && fValue(dat[r]) < fValue(dat[minValueIndex])) { + if(r < dat.size && fValue(dat[r], end) < fValue(dat[minValueIndex], end) ) { minValueIndex = r } @@ -78,12 +78,4 @@ class TileHeap(val end: Tile, val gVals: HashMap) { return index > (dat.size / 2) } - private fun fValue(prospect: Tile): Int { - return hValue(prospect).plus(gVals.get(prospect) ?: 0) - } - - private fun hValue(prospect: Tile): Int { - return abs(prospect.x() - end.x()) + abs(prospect.y() - end.y()) - } - } \ No newline at end of file