mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-14 17:59:11 +07:00
AI no longer tries to construct work boats that can't reach their intended destination
This commit is contained in:
@ -7,6 +7,7 @@ import com.unciv.logic.city.CityConstructions
|
|||||||
import com.unciv.logic.city.PerpetualConstruction
|
import com.unciv.logic.city.PerpetualConstruction
|
||||||
import com.unciv.logic.civilization.CityAction
|
import com.unciv.logic.civilization.CityAction
|
||||||
import com.unciv.logic.civilization.PlayerType
|
import com.unciv.logic.civilization.PlayerType
|
||||||
|
import com.unciv.logic.map.BFS
|
||||||
import com.unciv.models.ruleset.Building
|
import com.unciv.models.ruleset.Building
|
||||||
import com.unciv.models.ruleset.VictoryType
|
import com.unciv.models.ruleset.VictoryType
|
||||||
import com.unciv.models.stats.Stat
|
import com.unciv.models.stats.Stat
|
||||||
@ -29,13 +30,6 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
|||||||
val cities = civInfo.cities.size
|
val cities = civInfo.cities.size
|
||||||
val allTechsAreResearched = civInfo.tech.getNumberOfTechsResearched() >= civInfo.gameInfo.ruleSet.technologies.size
|
val allTechsAreResearched = civInfo.tech.getNumberOfTechsResearched() >= civInfo.gameInfo.ruleSet.technologies.size
|
||||||
|
|
||||||
val buildableWorkboatUnits = cityInfo.cityConstructions.getConstructableUnits()
|
|
||||||
.filter { it.uniques.contains("May create improvements on water resources") }
|
|
||||||
val canBuildWorkboat = buildableWorkboatUnits.any()
|
|
||||||
&& !cityInfo.getTiles().any { it.civilianUnit?.hasUnique("May create improvements on water resources")==true }
|
|
||||||
val needWorkboat = canBuildWorkboat
|
|
||||||
&& cityInfo.getTiles().any { it.isWater && it.hasViewableResource(civInfo) && it.improvement == null }
|
|
||||||
|
|
||||||
val isAtWar = civInfo.isAtWar()
|
val isAtWar = civInfo.isAtWar()
|
||||||
val preferredVictoryType = civInfo.victoryType()
|
val preferredVictoryType = civInfo.victoryType()
|
||||||
|
|
||||||
@ -119,9 +113,25 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun addWorkBoatChoice() {
|
private fun addWorkBoatChoice() {
|
||||||
if (needWorkboat) {
|
val buildableWorkboatUnits = cityInfo.cityConstructions.getConstructableUnits()
|
||||||
addChoice(relativeCostEffectiveness, buildableWorkboatUnits.minBy { it.cost }!!.name, 0.6f)
|
.filter { it.uniques.contains("May create improvements on water resources") }
|
||||||
|
val canBuildWorkboat = buildableWorkboatUnits.any()
|
||||||
|
&& !cityInfo.getTiles().any { it.civilianUnit?.hasUnique("May create improvements on water resources") == true }
|
||||||
|
if (!canBuildWorkboat) return
|
||||||
|
val tilesThatNeedWorkboat = cityInfo.getTiles()
|
||||||
|
.filter { it.isWater && it.hasViewableResource(civInfo) && it.improvement == null }.toList()
|
||||||
|
if (tilesThatNeedWorkboat.isEmpty()) return
|
||||||
|
|
||||||
|
// If we can't reach the tile we need to improve within 10 turns, it's probably unreachable.
|
||||||
|
val bfs = BFS(cityInfo.getCenterTile()) { (it.isWater || it.isCityCenter()) && it.isFriendlyTerritory(civInfo) }
|
||||||
|
for (i in 1..10) {
|
||||||
|
bfs.nextStep()
|
||||||
|
if (tilesThatNeedWorkboat.any { bfs.hasReachedTile(it) })
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
if (tilesThatNeedWorkboat.none { bfs.hasReachedTile(it) }) return
|
||||||
|
|
||||||
|
addChoice(relativeCostEffectiveness, buildableWorkboatUnits.minBy { it.cost }!!.name, 0.6f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addWorkerChoice() {
|
private fun addWorkerChoice() {
|
||||||
|
@ -6,31 +6,33 @@ import java.util.ArrayDeque
|
|||||||
/**
|
/**
|
||||||
* Defines intermediate steps of a breadth-first search, for use in either get shortest path or get onnected tiles.
|
* Defines intermediate steps of a breadth-first search, for use in either get shortest path or get onnected tiles.
|
||||||
*/
|
*/
|
||||||
class BFS(val startingPoint: TileInfo, val predicate : (TileInfo) -> Boolean){
|
class BFS(val startingPoint: TileInfo, val predicate : (TileInfo) -> Boolean) {
|
||||||
var tilesToCheck = ArrayDeque<TileInfo>()
|
var tilesToCheck = ArrayDeque<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>()
|
||||||
|
|
||||||
init{
|
init {
|
||||||
tilesToCheck.add(startingPoint)
|
tilesToCheck.add(startingPoint)
|
||||||
tilesReached[startingPoint] = startingPoint
|
tilesReached[startingPoint] = startingPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stepToEnd(){
|
fun stepToEnd() {
|
||||||
while(tilesToCheck.isNotEmpty())
|
while (tilesToCheck.isNotEmpty())
|
||||||
nextStep()
|
nextStep()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun stepUntilDestination(destination: TileInfo): BFS {
|
fun stepUntilDestination(destination: TileInfo): BFS {
|
||||||
while(!tilesReached.containsKey(destination) && tilesToCheck.isNotEmpty())
|
while (!tilesReached.containsKey(destination) && tilesToCheck.isNotEmpty())
|
||||||
nextStep()
|
nextStep()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nextStep(){
|
fun nextStep() {
|
||||||
val current = tilesToCheck.remove()
|
val current = tilesToCheck.remove()
|
||||||
for(neighbor in current.neighbors){
|
for (neighbor in current.neighbors) {
|
||||||
if(predicate(neighbor) && !tilesReached.containsKey(neighbor)){
|
if (predicate(neighbor) && !tilesReached.containsKey(neighbor)) {
|
||||||
tilesReached[neighbor] = current
|
tilesReached[neighbor] = current
|
||||||
tilesToCheck.add(neighbor)
|
tilesToCheck.add(neighbor)
|
||||||
}
|
}
|
||||||
@ -41,7 +43,7 @@ class BFS(val startingPoint: TileInfo, val predicate : (TileInfo) -> Boolean){
|
|||||||
val path = ArrayList<TileInfo>()
|
val path = ArrayList<TileInfo>()
|
||||||
path.add(destination)
|
path.add(destination)
|
||||||
var currentNode = destination
|
var currentNode = destination
|
||||||
while(currentNode != startingPoint) {
|
while (currentNode != startingPoint) {
|
||||||
val parent = tilesReached[currentNode]
|
val parent = tilesReached[currentNode]
|
||||||
if (parent == null) return ArrayList()// destination is not in our path
|
if (parent == null) return ArrayList()// destination is not in our path
|
||||||
currentNode = parent
|
currentNode = parent
|
||||||
|
Reference in New Issue
Block a user