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

View File

@ -1,14 +1,15 @@
package com.unciv.logic.map
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.
*/
class BFS(
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 */
var maxSize = Int.MAX_VALUE
@ -50,7 +51,11 @@ class BFS(
fun nextStep() {
if (tilesReached.size >= maxSize) { tilesToCheck.clear(); 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)) {
tilesReached[neighbor] = current
tilesToCheck.add(neighbor)