mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-22 22:00:24 +07:00
AI now knows to pathfind multiple cities for air units and to move fighters towards enemy cities with many air units
This commit is contained in:
@ -170,16 +170,42 @@ class SpecificUnitAutomation{
|
||||
if(enemyAirUnitsInRange.isNotEmpty()) return // we need to be on standby in case they attack
|
||||
if(UnitAutomation().tryAttackNearbyEnemy(unit)) return
|
||||
|
||||
val reachableCities = tilesInRange
|
||||
val immediatelyReachableCities = tilesInRange
|
||||
.filter { it.isCityCenter() && it.getOwner()==unit.civInfo && unit.movement.canMoveTo(it)}
|
||||
|
||||
for(city in reachableCities){
|
||||
for(city in immediatelyReachableCities){
|
||||
if(city.getTilesInDistance(unit.getRange())
|
||||
.any { UnitAutomation().containsAttackableEnemy(it,MapUnitCombatant(unit)) }) {
|
||||
unit.movement.moveToTile(city)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val pathsToCities = unit.movement.getArialPathsToCities()
|
||||
if(pathsToCities.size==1) return // can't actually move anywhere else
|
||||
|
||||
val citiesByNearbyAirUnits = pathsToCities.keys
|
||||
.groupBy { it.getTilesInDistance(unit.getRange())
|
||||
.count{it.airUnits.size>0 && it.airUnits.first().civInfo.isAtWarWith(unit.civInfo)} }
|
||||
|
||||
if(citiesByNearbyAirUnits.keys.any { it!=0 }){
|
||||
val citiesWithMostNeedOfAirUnits = citiesByNearbyAirUnits.maxBy { it.key }!!.value
|
||||
val chosenCity = citiesWithMostNeedOfAirUnits.minBy { pathsToCities[it]!!.size }!! // city with min path = least turns to get there
|
||||
val firstStepInPath = pathsToCities[chosenCity]!!.first()
|
||||
unit.movement.moveToTile(firstStepInPath)
|
||||
return
|
||||
}
|
||||
|
||||
// no city needs fighters to defend, so let's attack stuff from the closest possible location
|
||||
val citiesThatCanAttackFrom = pathsToCities.keys
|
||||
.filter { it.getTilesInDistance(unit.getRange())
|
||||
.any { UnitAutomation().containsAttackableEnemy(it,MapUnitCombatant(unit)) } }
|
||||
if(citiesThatCanAttackFrom.isEmpty()) return
|
||||
|
||||
val closestCityThatCanAttackFrom = citiesThatCanAttackFrom.minBy { pathsToCities[it]!!.size }!!
|
||||
val firstStepInPath = pathsToCities[closestCityThatCanAttackFrom]!!.first()
|
||||
unit.movement.moveToTile(firstStepInPath)
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -311,11 +311,12 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
|
||||
fun getDistanceToTiles() = getDistanceToTilesWithinTurn(unit.currentTile.position,unit.currentMovement)
|
||||
|
||||
fun getArialMovementBfsTree(startingTile: TileInfo): HashMap<TileInfo, TileInfo> {
|
||||
fun getArialPathsToCities(): HashMap<TileInfo, ArrayList<TileInfo>> {
|
||||
var tilesToCheck = ArrayList<TileInfo>()
|
||||
/** each tile reached points to its parent tile, where we got to it from */
|
||||
val tilesReached = HashMap<TileInfo, TileInfo>()
|
||||
|
||||
val startingTile = unit.currentTile
|
||||
tilesToCheck.add(startingTile)
|
||||
tilesReached[startingTile] = startingTile
|
||||
|
||||
@ -333,6 +334,19 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
}
|
||||
tilesToCheck=newTilesToCheck
|
||||
}
|
||||
return tilesReached
|
||||
|
||||
val pathsToCities = HashMap<TileInfo, ArrayList<TileInfo>>()
|
||||
|
||||
for(city in tilesReached.keys){
|
||||
val path = ArrayList<TileInfo>()
|
||||
var currentCity = city
|
||||
while(currentCity!=startingTile){ // we don't add the "starting tile" to the arraylist
|
||||
path.add(currentCity)
|
||||
currentCity = tilesReached[currentCity]!! // go to parent
|
||||
}
|
||||
path.reverse()
|
||||
pathsToCities[city] = path
|
||||
}
|
||||
return pathsToCities
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user