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:
Yair Morgenstern
2019-07-14 23:33:16 +03:00
parent 23c221abd3
commit 5ba172f71b
2 changed files with 44 additions and 4 deletions

View File

@ -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)
}
}

View File

@ -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
}
}