Added "explored tiles" to civinfo, moved worker automation to separate class

This commit is contained in:
Yair Morgenstern 2018-04-25 22:09:24 +03:00
parent 9d7399dd48
commit 9816cd57da
15 changed files with 96 additions and 74 deletions

View File

@ -11,6 +11,11 @@
cities:["Athens","Sparta","Corinth","Argos","Knossos","Mycenae","Pharsalos","Ephesus","Halicarnassus","Rhodes",
"Eretria","Pergamon","Miletos","Megara","Phocaea"]
},
{
name:"Chinese",
RGB:[ 101, 253, 155],
cities:["Beijing","Shanghai","Guangzhou","Nanjing","Xian","Chengdu","Hangzhou","Tianjin","Macau","Shandong"]
},
{
name:"Barbarians",
RGB:[200,200,200]

View File

@ -8,31 +8,14 @@ import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.UnitMovementAlgorithms
import com.unciv.logic.map.UnitType
import com.unciv.models.gamebasics.Building
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.TileImprovement
import com.unciv.ui.utils.getRandom
import com.unciv.ui.worldscreen.unit.UnitActions
class Automation {
private fun findTileToWork(currentTile: TileInfo, civInfo: CivilizationInfo): TileInfo {
val selectedTile = currentTile.tileMap.getTilesInDistance(currentTile.position, 4)
.filter {
(it.unit == null || it == currentTile)
&& it.improvement == null
&& (it.getCity()==null || it.getCity()!!.civInfo == civInfo) // don't work tiles belonging to another civ
&& it.canBuildImprovement(chooseImprovement(it), civInfo)
&& UnitMovementAlgorithms(currentTile.tileMap) // the tile is actually reachable - more difficult than it seems!
.getShortestPath(currentTile.position, it.position, 2f, 2, civInfo).isNotEmpty()
}
.maxBy { getPriority(it, civInfo) }
if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile
else return currentTile
}
internal fun rankTile(tile: TileInfo, civInfo: CivilizationInfo): Float {
val stats = tile.getTileStats(null, civInfo)
@ -48,46 +31,6 @@ class Automation {
return rank
}
private fun getPriority(tileInfo: TileInfo, civInfo: CivilizationInfo): Int {
var priority = 0
if (tileInfo.isWorked()) priority += 3
if (tileInfo.getOwner() == civInfo) priority += 2
if (tileInfo.hasViewableResource(civInfo)) priority += 1
else if (tileInfo.neighbors.any { it.getOwner() != null }) priority += 1
return priority
}
private fun chooseImprovement(tile: TileInfo): TileImprovement {
val improvementString = when {
tile.improvementInProgress != null -> tile.improvementInProgress
tile.terrainFeature == "Forest" -> "Lumber mill"
tile.terrainFeature == "Jungle" -> "Trading post"
tile.terrainFeature == "Marsh" -> "Remove Marsh"
tile.resource != null -> tile.tileResource.improvement
tile.baseTerrain == "Hill" -> "Mine"
tile.baseTerrain == "Grassland" || tile.baseTerrain == "Desert" || tile.baseTerrain == "Plains" -> "Farm"
tile.baseTerrain == "Tundra" -> "Trading post"
else -> null
}
return GameBasics.TileImprovements[improvementString]!!
}
fun automateWorkerAction(unit: MapUnit) {
var tile = unit.getTile()
val tileToWork = findTileToWork(tile, unit.civInfo)
if (tileToWork != tile) {
tile = unit.headTowards(tileToWork.position)
unit.doPreTurnAction(tile)
return
}
if (tile.improvementInProgress == null) {
val improvement = chooseImprovement(tile)
if (tile.canBuildImprovement(improvement, unit.civInfo))
// What if we're stuck on this tile but can't build there?
tile.startWorkingOnImprovement(improvement, unit.civInfo)
}
}
fun rankTileAsCityCenter(tileInfo: TileInfo, civInfo: CivilizationInfo): Float {
val bestTilesFromOuterLayer = tileInfo.tileMap.getTilesAtDistance(tileInfo.position,2)
.sortedByDescending { rankTile(it,civInfo) }.take(2)
@ -137,7 +80,7 @@ class Automation {
}
if (unit.name == "Worker") {
Automation().automateWorkerAction(unit)
WorkerAutomation().automateWorkerAction(unit)
return
}
@ -258,4 +201,5 @@ class Automation {
}
}
}
}

View File

@ -39,6 +39,7 @@ class GameInfo {
// maybe one of them has a wonder that affects the stats of all the rest of the cities
for (civInfo in civilizations){
civInfo.getViewableTiles() // adds explored tiles for auto civs
if(!civInfo.isPlayerCivilization())
Automation().automateCivMoves(civInfo)
for (city in civInfo.cities)

View File

@ -0,0 +1,68 @@
package com.unciv.logic
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo
import com.unciv.logic.map.UnitMovementAlgorithms
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.TileImprovement
public class WorkerAutomation(){
fun automateWorkerAction(unit: MapUnit) {
var tile = unit.getTile()
val tileToWork = findTileToWork(tile, unit.civInfo)
if (tileToWork != tile) {
tile = unit.headTowards(tileToWork.position)
unit.doPreTurnAction(tile)
return
}
if (tile.improvementInProgress == null) {
val improvement = chooseImprovement(tile)
if (tile.canBuildImprovement(improvement, unit.civInfo))
// What if we're stuck on this tile but can't build there?
tile.startWorkingOnImprovement(improvement, unit.civInfo)
}
}
private fun findTileToWork(currentTile: TileInfo, civInfo: CivilizationInfo): TileInfo {
val selectedTile = currentTile.tileMap.getTilesInDistance(currentTile.position, 4)
.filter {
(it.unit == null || it == currentTile)
&& it.improvement == null
&& (it.getCity()==null || it.getCity()!!.civInfo == civInfo) // don't work tiles belonging to another civ
&& it.canBuildImprovement(chooseImprovement(it), civInfo)
&& UnitMovementAlgorithms(currentTile.tileMap) // the tile is actually reachable - more difficult than it seems!
.getShortestPath(currentTile.position, it.position, 2f, 2, civInfo).isNotEmpty()
}
.maxBy { getPriority(it, civInfo) }
if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile
else return currentTile
}
private fun getPriority(tileInfo: TileInfo, civInfo: CivilizationInfo): Int {
var priority = 0
if (tileInfo.isWorked()) priority += 3
if (tileInfo.getOwner() == civInfo) priority += 2
if (tileInfo.hasViewableResource(civInfo)) priority += 1
else if (tileInfo.neighbors.any { it.getOwner() != null }) priority += 1
return priority
}
private fun chooseImprovement(tile: TileInfo): TileImprovement {
val improvementString = when {
tile.improvementInProgress != null -> tile.improvementInProgress
tile.terrainFeature == "Forest" -> "Lumber mill"
tile.terrainFeature == "Jungle" -> "Trading post"
tile.terrainFeature == "Marsh" -> "Remove Marsh"
tile.resource != null -> tile.tileResource.improvement
tile.baseTerrain == "Hill" -> "Mine"
tile.baseTerrain == "Grassland" || tile.baseTerrain == "Desert" || tile.baseTerrain == "Plains" -> "Farm"
tile.baseTerrain == "Tundra" -> "Trading post"
else -> null
}
return GameBasics.TileImprovements[improvementString]!!
}
}

View File

@ -21,7 +21,8 @@ class CityCombatant(val city: CityInfo) : ICombatant {
override fun getAttackingStrength(defender: ICombatant): Int = getCityStrength()
override fun getDefendingStrength(attacker: ICombatant): Int = getCityStrength()
fun getCityStrength(): Int {
private fun
getCityStrength(): Int {
val baseStrength = 10
// as tech progresses so does city strength
val techsPercentKnown: Float = city.civInfo.tech.techsResearched.count().toFloat() /
@ -37,9 +38,9 @@ class CityCombatant(val city: CityInfo) : ICombatant {
// 10% bonus foreach pop
val strengthWithPop = (baseStrength + strengthFromTechs) * (1 + 0.1*city.population.population)
return strengthWithPop.toInt() * 100 // *100 because a city is always at 100% strength
}
override fun toString(): String {return city.name} // for debug
}

View File

@ -33,6 +33,7 @@ class CivilizationInfo {
var scienceVictory = ScienceVictoryManager()
var cities = ArrayList<CityInfo>()
var exploredTiles = ArrayList<Vector2>()
fun getCivilization(): Civilization {return GameBasics.Civilizations[civName]!!}
@ -173,6 +174,7 @@ class CivilizationInfo {
viewablePositions += gameInfo.tileMap.values
.filter { it.unit != null && it.unit!!.owner == civName }
.flatMap { it.getViewableTiles(2)} // Tiles within 2 tiles of units
viewablePositions.map { it.position }.filterNot { exploredTiles.contains(it) }.toCollection(exploredTiles)
return viewablePositions
}

View File

@ -1,7 +1,7 @@
package com.unciv.logic.map
import com.badlogic.gdx.math.Vector2
import com.unciv.logic.Automation
import com.unciv.logic.WorkerAutomation
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.Unit
@ -50,7 +50,7 @@ class MapUnit {
return
}
if (action == "automation") Automation().automateWorkerAction(this)
if (action == "automation") WorkerAutomation().automateWorkerAction(this)
}
private fun doPostTurnAction(tile: TileInfo) {

View File

@ -22,7 +22,6 @@ class TileInfo {
var improvementInProgress: String? = null
var roadStatus = RoadStatus.None
var explored = false
var turnsToImprovement: Int = 0
fun getCity(): CityInfo? = tileMap.gameInfo.civilizations.flatMap { it.cities }.firstOrNull{it.tiles.contains(position)}

View File

@ -44,6 +44,8 @@ class UnitMovementAlgorithms(val tileMap: TileMap){
fun getShortestPath(origin: Vector2, destination: Vector2, currentMovement: Float, maxMovement: Int, civInfo: CivilizationInfo): List<TileInfo> {
if(origin.equals(destination)) return listOf(tileMap[origin]) // edge case that's needed, so that workers will know that they can reach their own tile. *sigh*
var tilesToCheck: List<TileInfo> = listOf(tileMap[origin])
val movementTreeParents = HashMap<TileInfo, TileInfo?>() // contains a map of "you can get from X to Y in that turn"
movementTreeParents[tileMap[origin]] = null

View File

@ -153,7 +153,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
val allTiles = Group()
for (tileInfo in game.gameInfo.tileMap.getTilesInDistance(cityInfo.location, 5)) {
if (!tileInfo.explored) continue // Don't even bother to display it.
if (!city.civInfo.exploredTiles.contains(tileInfo.position)) continue // Don't even bother to display it.
val group = CityTileGroup(cityInfo, tileInfo)
group.addClickListener {
selectedTile = tileInfo

View File

@ -52,9 +52,9 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
open fun update(isViewable: Boolean) {
if (!tileInfo.explored) {
//hexagon.color = Color.BLACK
//return
if (!tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)) {
// hexagon.color = Color.BLACK
// return
}
updateTerrainFeatureImage()

View File

@ -47,7 +47,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
override fun update(isViewable: Boolean) {
super.update(isViewable)
if (!tileInfo.explored) return
//if (!tileInfo.explored) return
if (populationImage != null) removePopulationIcon()
@ -94,7 +94,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
unitImage = null
}
if (tileInfo.unit != null && isViewable) { // Tile is visible
if (tileInfo.unit != null /*&& isViewable*/) { // Tile is visible
val unit = tileInfo.unit!!
unitImage = getUnitImage(unit.name, unit.civInfo.getCivilization().getColor())
addActor(unitImage!!)

View File

@ -31,7 +31,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
if (worldScreen.tileMapHolder.selectedTile == null) return
val selectedTile = worldScreen.tileMapHolder.selectedTile!!
val defender: ICombatant
if (selectedTile.explored && selectedTile.isCityCenter && selectedTile.getOwner() != worldScreen.civInfo)
if (attacker.getCivilization().exploredTiles.contains(selectedTile.position)
&& selectedTile.isCityCenter && selectedTile.getOwner() != worldScreen.civInfo)
defender = CityCombatant(selectedTile.getCity()!!)
else if (selectedTile.unit != null
&& selectedTile.unit!!.owner != worldScreen.civInfo.civName // enemy unit on selected tile,

View File

@ -27,7 +27,7 @@ class TileInfoTable(private val worldScreen: WorldScreen, internal val civInfo:
val skin = CameraStageBaseScreen.skin
if (tile.explored) {
if (civInfo.exploredTiles.contains(tile.position)) {
add(Label(tile.toString(), skin)).colspan(2)
row()

View File

@ -94,7 +94,6 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
.filter { tileGroups.containsKey(it) }) {
tileGroups[string]!!.run {
tileInfo.explored = true
update(true)
}
}