Added initial pathfinding tests

This commit is contained in:
Yair Morgenstern 2023-12-08 14:48:48 +02:00
parent cce678800f
commit 2ae5a018de
3 changed files with 67 additions and 2 deletions

View File

@ -65,7 +65,7 @@ class UnitMovement(val unit: MapUnit) {
}
if (!distanceToTiles.containsKey(neighbor) || distanceToTiles[neighbor]!!.totalDistance > totalDistanceToTile) { // this is the new best path
if (totalDistanceToTile < unitMovement- Constants.minimumMovementEpsilon) // We can still keep moving from here!
if (totalDistanceToTile < unitMovement - Constants.minimumMovementEpsilon) // We can still keep moving from here!
updatedTiles += neighbor
else
totalDistanceToTile = unitMovement

View File

@ -0,0 +1,62 @@
package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.tile.Tile
import com.unciv.testing.GdxTestRunner
import com.unciv.testing.TestGame
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(GdxTestRunner::class)
class PathfindingTests {
private lateinit var tile: Tile
private lateinit var civInfo: Civilization
private var testGame = TestGame()
@Before
fun initTheWorld() {
testGame.makeHexagonalMap(5)
tile = testGame.tileMap[0,0]
civInfo = testGame.addCiv()
for (tile in testGame.tileMap.values)
tile.setExplored(civInfo, true)
}
// These are interesting use-cases because it shows that for the *exact same map* for units with *no special uniques*
// we can still have different optimal paths!
@Test
fun shortestPathByTurnsNotSumOfMovements(){
// Naive Djikstra would calculate distance to 0,3 to be 5 movement points through hills, and only 4 by going around hills.
// However, from a *unit turn* perspective, going through the hills is 3 turns, and going around is 4, so through the hills is the correct solution
testGame.setTileTerrain(Vector2(0f,1f), "Hill")
testGame.setTileTerrain(Vector2(0f,2f), "Hill")
val baseUnit = testGame.createBaseUnit()
baseUnit.movement = 1
val unit = testGame.addUnit(baseUnit.name, civInfo, tile)
// expect movement through hills (2 hill tiles plus one default desert)
Assert.assertEquals(3, unit.movement.getShortestPath(testGame.getTile(Vector2(0f, 3f))).size)
}
// Looks like our current movement is actually unoptimized, since it fails this test :)
@Test
fun maximizeRemainingMovementWhenReachingDestination(){
// Moving in a direct path, you'd waste 5 movement points to get there, ending up with 0.
// Moving around the hills, you'd waste 4 movement points, leaving you with one remaining
testGame.setTileTerrain(Vector2(0f,1f), "Hill")
testGame.setTileTerrain(Vector2(0f,2f), "Hill")
val baseUnit = testGame.createBaseUnit()
baseUnit.movement = 5
val unit = testGame.addUnit(baseUnit.name, civInfo, tile)
// val pathToTile = unit.movement.getDistanceToTilesWithinTurn(Vector2(0f, 0f), 5f).getPathToTile(testGame.getTile(Vector2(0f, 3f)))
unit.movement.moveToTile(testGame.getTile(Vector2(0f, 3f)))
Assert.assertEquals(1f, unit.currentMovement)
}
}

View File

@ -183,7 +183,10 @@ class TestGame {
baseUnit.ruleset = ruleset
val mapUnit = baseUnit.getMapUnit(civInfo)
civInfo.units.addUnit(mapUnit)
if (tile!=null) mapUnit.putInTile(tile)
if (tile!=null) {
mapUnit.putInTile(tile)
mapUnit.currentMovement = mapUnit.getMaxMovement().toFloat()
}
return mapUnit
}