Workers try to build roads utilizing existing roads, and railroads overriding existing roads

This commit is contained in:
Yair Morgenstern 2023-06-14 09:31:26 +03:00
parent 46a84c23b0
commit e558ebcc59
2 changed files with 12 additions and 4 deletions

View File

@ -221,13 +221,15 @@ class WorkerAutomation(
if (candidateCities.none()) return false // do nothing. if (candidateCities.none()) return false // do nothing.
val isCandidateTilePredicate: (Tile) -> Boolean = { it.isLand && unit.movement.canPassThrough(it) } val isCandidateTilePredicate: (Tile) -> Boolean = { it.isLand && unit.movement.canPassThrough(it) }
val getTilePriority: (Tile) -> Int = { it.roadStatus.ordinal }
val currentTile = unit.getTile() val currentTile = unit.getTile()
val cityTilesToSeek = ArrayList(tilesOfConnectedCities.sortedBy { it.aerialDistanceTo(currentTile) }) val cityTilesToSeek = ArrayList(tilesOfConnectedCities.sortedBy { it.aerialDistanceTo(currentTile) })
for (toConnectCity in candidateCities) { for (toConnectCity in candidateCities) {
val toConnectTile = toConnectCity.getCenterTile() val toConnectTile = toConnectCity.getCenterTile()
val bfs: BFS = bfsCache[toConnectTile.position] ?: val bfs: BFS = bfsCache[toConnectTile.position] ?:
BFS(toConnectTile, isCandidateTilePredicate).apply { BFS(toConnectTile, getTilePriority, isCandidateTilePredicate).apply {
maxSize = HexMath.getNumberOfTilesInHexagon( maxSize = HexMath.getNumberOfTilesInHexagon(
WorkerAutomationConst.maxBfsReachPadding + WorkerAutomationConst.maxBfsReachPadding +
tilesOfConnectedCities.minOf { it.aerialDistanceTo(toConnectTile) } tilesOfConnectedCities.minOf { it.aerialDistanceTo(toConnectTile) }
@ -238,6 +240,7 @@ class WorkerAutomation(
while (true) { while (true) {
for (cityTile in cityTilesToSeek.toList()) { // copy since we change while running for (cityTile in cityTilesToSeek.toList()) { // copy since we change while running
if (!bfs.hasReachedTile(cityTile)) continue if (!bfs.hasReachedTile(cityTile)) continue
// we have a winner! // we have a winner!
val pathToCity = bfs.getPathTo(cityTile) val pathToCity = bfs.getPathTo(cityTile)
val roadableTiles = pathToCity.filter { it.getUnpillagedRoad() < bestRoadAvailable } val roadableTiles = pathToCity.filter { it.getUnpillagedRoad() < bestRoadAvailable }

View File

@ -1,14 +1,15 @@
package com.unciv.logic.map package com.unciv.logic.map
import com.unciv.logic.map.tile.Tile import com.unciv.logic.map.tile.Tile
import kotlin.collections.ArrayDeque
/** /**
* Defines intermediate steps of a breadth-first search, for use in either get shortest path or get connected tiles. * Defines intermediate steps of a breadth-first search, for use in either get shortest path or get connected tiles.
*/ */
class BFS( class BFS(
val startingPoint: Tile, val startingPoint: Tile,
private val predicate : (Tile) -> Boolean /** The *higher* the number, the *greater* the priority */
private val priorityFunction: ((Tile) -> Int)? = null,
private val predicate : (Tile) -> Boolean,
) { ) {
/** Maximum number of tiles to search */ /** Maximum number of tiles to search */
var maxSize = Int.MAX_VALUE var maxSize = Int.MAX_VALUE
@ -50,7 +51,11 @@ class BFS(
fun nextStep() { fun nextStep() {
if (tilesReached.size >= maxSize) { tilesToCheck.clear(); return } if (tilesReached.size >= maxSize) { tilesToCheck.clear(); return }
val current = tilesToCheck.removeFirstOrNull() ?: return val current = tilesToCheck.removeFirstOrNull() ?: return
for (neighbor in current.neighbors) {
val sortedNeighbors = if (priorityFunction==null) current.neighbors
else current.neighbors.sortedByDescending(priorityFunction)
for (neighbor in sortedNeighbors) {
if (neighbor !in tilesReached && predicate(neighbor)) { if (neighbor !in tilesReached && predicate(neighbor)) {
tilesReached[neighbor] = current tilesReached[neighbor] = current
tilesToCheck.add(neighbor) tilesToCheck.add(neighbor)