mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-29 23:10:39 -04:00
Better AI coordination - try and attack the area around the closest city to ours.
Also improves performance as AI only try and head towards a specific subset of cities.
This commit is contained in:
parent
505a78182c
commit
87e2764733
@ -387,25 +387,43 @@ object UnitAutomation {
|
|||||||
private fun tryHeadTowardsEnemyCity(unit: MapUnit): Boolean {
|
private fun tryHeadTowardsEnemyCity(unit: MapUnit): Boolean {
|
||||||
if (unit.civInfo.cities.isEmpty()) return false
|
if (unit.civInfo.cities.isEmpty()) return false
|
||||||
|
|
||||||
var enemyCities = unit.civInfo.gameInfo.civilizations.asSequence()
|
// only focus on *attacking* 1 enemy at a time otherwise you'll lose on both fronts
|
||||||
.filter { unit.civInfo.isAtWarWith(it) }
|
|
||||||
.flatMap { it.cities }
|
val enemies = unit.civInfo.getKnownCivs().filter { unit.civInfo.isAtWarWith(it) && it.cities.isNotEmpty() }
|
||||||
.filter { it.location in unit.civInfo.exploredTiles }
|
|
||||||
|
val ourCities = unit.civInfo.cities
|
||||||
|
|
||||||
|
var closestEnemyCity:CityInfo?=null
|
||||||
|
var closestDistance = 10000
|
||||||
|
for (enemy in enemies) {
|
||||||
|
val knownEnemyCities = enemy.cities.filter { it.location in unit.civInfo.exploredTiles }
|
||||||
|
if (knownEnemyCities.isEmpty()) continue
|
||||||
|
for(enemyCity in knownEnemyCities) {
|
||||||
|
val distanceToClosestCityOfOurs = ourCities.minOf {
|
||||||
|
it.getCenterTile().aerialDistanceTo(enemyCity.getCenterTile())
|
||||||
|
}
|
||||||
|
if (distanceToClosestCityOfOurs < closestDistance){
|
||||||
|
closestDistance = distanceToClosestCityOfOurs
|
||||||
|
closestEnemyCity = enemyCity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (closestEnemyCity==null) return false // no attackable cities found
|
||||||
|
|
||||||
|
// Our main attack target is the closest city, but we're fine with deviating from that a bit
|
||||||
|
var enemyCitiesByPriority = closestEnemyCity.civInfo.cities
|
||||||
|
.associateWith { it.getCenterTile().aerialDistanceTo(closestEnemyCity.getCenterTile()) }
|
||||||
|
.filterNot { it.value > 10 } // anything 10 tiles away from the target is irrelevant
|
||||||
|
.asSequence().sortedBy { it.value }.map { it.key } // sort the list by closeness to target - least is best!
|
||||||
|
|
||||||
if (unit.baseUnit.isRanged()) // ranged units don't harm capturable cities, waste of a turn
|
if (unit.baseUnit.isRanged()) // ranged units don't harm capturable cities, waste of a turn
|
||||||
enemyCities = enemyCities.filterNot { it.health == 1 }
|
enemyCitiesByPriority = enemyCitiesByPriority.filterNot { it.health == 1 }
|
||||||
|
|
||||||
val closestReachableEnemyCity = enemyCities
|
val closestReachableEnemyCity = enemyCitiesByPriority
|
||||||
.map { it.getCenterTile() }
|
.firstOrNull { unit.movement.canReach(it.getCenterTile()) }
|
||||||
.sortedBy { cityCenterTile ->
|
|
||||||
// sort enemy cities by closeness to our cities, and only then choose the first reachable - checking canReach is comparatively very time-intensive!
|
|
||||||
unit.civInfo.cities.asSequence()
|
|
||||||
.map { cityCenterTile.aerialDistanceTo(it.getCenterTile()) }.minOrNull()!!
|
|
||||||
}
|
|
||||||
.firstOrNull { unit.movement.canReach(it) }
|
|
||||||
|
|
||||||
if (closestReachableEnemyCity != null) {
|
if (closestReachableEnemyCity != null) {
|
||||||
return headTowardsEnemyCity(unit, closestReachableEnemyCity)
|
return headTowardsEnemyCity(unit, closestReachableEnemyCity.getCenterTile())
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user