mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-29 23:10:39 -04: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:
parent
23c221abd3
commit
5ba172f71b
@ -170,16 +170,42 @@ class SpecificUnitAutomation{
|
|||||||
if(enemyAirUnitsInRange.isNotEmpty()) return // we need to be on standby in case they attack
|
if(enemyAirUnitsInRange.isNotEmpty()) return // we need to be on standby in case they attack
|
||||||
if(UnitAutomation().tryAttackNearbyEnemy(unit)) return
|
if(UnitAutomation().tryAttackNearbyEnemy(unit)) return
|
||||||
|
|
||||||
val reachableCities = tilesInRange
|
val immediatelyReachableCities = tilesInRange
|
||||||
.filter { it.isCityCenter() && it.getOwner()==unit.civInfo && unit.movement.canMoveTo(it)}
|
.filter { it.isCityCenter() && it.getOwner()==unit.civInfo && unit.movement.canMoveTo(it)}
|
||||||
|
|
||||||
for(city in reachableCities){
|
for(city in immediatelyReachableCities){
|
||||||
if(city.getTilesInDistance(unit.getRange())
|
if(city.getTilesInDistance(unit.getRange())
|
||||||
.any { UnitAutomation().containsAttackableEnemy(it,MapUnitCombatant(unit)) }) {
|
.any { UnitAutomation().containsAttackableEnemy(it,MapUnitCombatant(unit)) }) {
|
||||||
unit.movement.moveToTile(city)
|
unit.movement.moveToTile(city)
|
||||||
return
|
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 getDistanceToTiles() = getDistanceToTilesWithinTurn(unit.currentTile.position,unit.currentMovement)
|
||||||
|
|
||||||
fun getArialMovementBfsTree(startingTile: TileInfo): HashMap<TileInfo, TileInfo> {
|
fun getArialPathsToCities(): HashMap<TileInfo, ArrayList<TileInfo>> {
|
||||||
var tilesToCheck = ArrayList<TileInfo>()
|
var tilesToCheck = ArrayList<TileInfo>()
|
||||||
/** each tile reached points to its parent tile, where we got to it from */
|
/** each tile reached points to its parent tile, where we got to it from */
|
||||||
val tilesReached = HashMap<TileInfo, TileInfo>()
|
val tilesReached = HashMap<TileInfo, TileInfo>()
|
||||||
|
|
||||||
|
val startingTile = unit.currentTile
|
||||||
tilesToCheck.add(startingTile)
|
tilesToCheck.add(startingTile)
|
||||||
tilesReached[startingTile] = startingTile
|
tilesReached[startingTile] = startingTile
|
||||||
|
|
||||||
@ -333,6 +334,19 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
|||||||
}
|
}
|
||||||
tilesToCheck=newTilesToCheck
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user