diff --git a/core/src/com/unciv/logic/city/managers/CityExpansionManager.kt b/core/src/com/unciv/logic/city/managers/CityExpansionManager.kt index d6d9ffdbd8..2b77fe146a 100644 --- a/core/src/com/unciv/logic/city/managers/CityExpansionManager.kt +++ b/core/src/com/unciv/logic/city/managers/CityExpansionManager.kt @@ -171,7 +171,7 @@ class CityExpansionManager : IsPartOfGameInfoSerialization { * @param tile The tile to take over */ fun takeOwnership(tile: Tile) { - if (tile.isCityCenter()) throw Exception("What?!") + check(!tile.isCityCenter()) { "Trying to found a city in a tile that already has one" } if (tile.getCity() != null) tile.getCity()!!.expansion.relinquishOwnership(tile) diff --git a/tests/src/com/unciv/logic/city/managers/CityExpansionManagerTest.kt b/tests/src/com/unciv/logic/city/managers/CityExpansionManagerTest.kt new file mode 100644 index 0000000000..24195f2115 --- /dev/null +++ b/tests/src/com/unciv/logic/city/managers/CityExpansionManagerTest.kt @@ -0,0 +1,228 @@ +package com.unciv.logic.city.managers + +import com.badlogic.gdx.math.Vector2 +import com.unciv.logic.city.City +import com.unciv.logic.civilization.Civilization +import com.unciv.testing.GdxTestRunner +import com.unciv.testing.TestGame +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Assert.fail +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(GdxTestRunner::class) +class CityExpansionManagerTest { + + private lateinit var civ: Civilization + private lateinit var city: City + private val cityExpansionManager = CityExpansionManager() + + private val testGame = TestGame() + + @Before + fun setUp() { + testGame.makeHexagonalMap(6) + civ = testGame.addCiv() + city = testGame.addCity(civ, testGame.getTile(Vector2.Zero), initialPopulation = 1) + cityExpansionManager.city = city + } + + @Test + fun `should claim new tile when enough culture is stored`() { + // given + val cultureToNextTile = cityExpansionManager.getCultureToNextTile() + assertEquals(7, city.tiles.size) // city center + surrounding tiles + + // when + cityExpansionManager.nextTurn(cultureToNextTile.toFloat()) + + // then + assertEquals(8, city.tiles.size) + } + + @Test + fun `should claim max one tile per turn due to culture`() { + // given + assertEquals(7, city.tiles.size) // city center + surrounding tiles + + // when + cityExpansionManager.nextTurn(10_000f) + + // then + assertEquals(8, city.tiles.size) + } + + @Test + fun `should store excess culture for next tile`() { + // given + val cultureToNextTile = cityExpansionManager.getCultureToNextTile() + + // when + cityExpansionManager.nextTurn(cultureToNextTile + 10f) + + // then + assertEquals(10, cityExpansionManager.cultureStored) + } + + @Test + fun `should increase tile culture cost the more tiles a city has claimed by culture`() { + // given + val cultureToNextTile = cityExpansionManager.getCultureToNextTile() + + // when + cityExpansionManager.nextTurn(cultureToNextTile.toFloat()) + + // then + val cultureToNextTileAfterExpansion = cityExpansionManager.getCultureToNextTile() + assertTrue(cultureToNextTile < cultureToNextTileAfterExpansion) + } + + @Test + fun `should increase tile culture culture cost the more tiles a city has bought`() { + // given + val cultureToNextTile = cityExpansionManager.getCultureToNextTile() + civ.addGold(500) + + // when + cityExpansionManager.buyTile(testGame.getTile(Vector2(2f, 0f))) + + // then + val cultureToNextTileAfterExpansion = cityExpansionManager.getCultureToNextTile() + assertTrue(cultureToNextTile < cultureToNextTileAfterExpansion) + } + + @Test + fun `should increase tile culture costs for city states`() { + // given + val cityStateCiv = testGame.addCiv(cityStateType = "Militaristic") + val cityState = testGame.addCity(cityStateCiv, testGame.getTile(Vector2(4f, 0f))) + val cityStateExpansionManager = CityExpansionManager() + cityStateExpansionManager.city = cityState + + val cultureToNextTileCiv = cityExpansionManager.getCultureToNextTile() + + + // when + val cultureToNextTileCityState = cityStateExpansionManager.getCultureToNextTile() + + // then + assertTrue(cultureToNextTileCityState > cultureToNextTileCiv) + } + + @Test + fun `should change tile culture cost due to uniques`() { + // given + val uniqueCiv = testGame.addCiv("[-25]% Culture cost of natural border growth [in all cities]") + val uniqueCity = testGame.addCity(uniqueCiv, testGame.getTile(Vector2(4f, 0f))) + val cityUniqueExpansionManager = CityExpansionManager() + cityUniqueExpansionManager.city = uniqueCity + + val cultureToNextTile = cityExpansionManager.getCultureToNextTile() + + // when + val cultureToNextTileUnique = cityUniqueExpansionManager.getCultureToNextTile() + + // then + assertTrue(cultureToNextTileUnique < cultureToNextTile) + } + + @Test + fun `should change tile gold cost due to uniques`() { + // given + val uniqueCiv = testGame.addCiv("[-25]% Gold cost of acquiring tiles [in all cities]") + val uniqueCity = testGame.addCity(uniqueCiv, testGame.getTile(Vector2(4f, 0f))) + val cityUniqueExpansionManager = CityExpansionManager() + cityUniqueExpansionManager.city = uniqueCity + + val goldCost2TileDistance = cityExpansionManager.getGoldCostOfTile(testGame.getTile(Vector2(2f, 0f))) + + // when + val goldCost2TileDistanceWithUniques = cityUniqueExpansionManager.getGoldCostOfTile(testGame.getTile(Vector2(4f, -2f))) + + // then + assertTrue(goldCost2TileDistanceWithUniques < goldCost2TileDistance) + } + + @Test + fun `should be able to buy neighbour tile`() { + // given + val tileToBuy = testGame.getTile(Vector2(2f, 0f)) + civ.addGold(500) + assertFalse(city.tiles.contains(Vector2(2f, 0f))) + + // when + cityExpansionManager.buyTile(tileToBuy) + + // then + assertEquals(8, city.tiles.size) + assertTrue(city.tiles.contains(Vector2(2f, 0f))) + } + + @Test + fun `should not be able to buy not-neighbour tile`() { + // given + val tileToBuy = testGame.getTile(Vector2(3f, 0f)) + + // when + try { + cityExpansionManager.buyTile(tileToBuy) + } catch (e: Exception) { + // then + assertEquals("$city tried to buy $tileToBuy, but it owns none of the neighbors", e.message) + return + } + + fail() + } + + @Test + fun `should not be able to buy tile without enough gold`() { + // given + val tileToBuy = testGame.getTile(Vector2(2f, 0f)) + + // when + try { + cityExpansionManager.buyTile(tileToBuy) + } catch (e: Exception) { + // then + e.message?.let { assertTrue(it.contains("$city tried to buy $tileToBuy, but lacks gold")) } + return + } + + fail() + } + + @Test + fun `should increase gold cost the more a tile is farther from the city center`() { + // given + val tileToBuyNear = testGame.getTile(Vector2(2f, 0f)) // two tiles distance + val tileToBuyFar = testGame.getTile(Vector2(3f, 0f)) // three tiles distance + + // when + val nearTileCost = cityExpansionManager.getGoldCostOfTile(tileToBuyNear) + val farTileCost = cityExpansionManager.getGoldCostOfTile(tileToBuyFar) + + // then + assertTrue(nearTileCost < farTileCost) + } + + @Test + fun `should increase gold cost the more tiles a city has claimed`() { + // given + val tileBought = testGame.getTile(Vector2(-2f, 0f)) // two tiles distance + val tileToBuy = testGame.getTile(Vector2(2f, 0f)) // still two tiles distance + val tileBoughtCost = cityExpansionManager.getGoldCostOfTile(tileBought) + + civ.addGold(500) + + // when + cityExpansionManager.buyTile(tileBought) + + // then + val tileToBuyCost = cityExpansionManager.getGoldCostOfTile(tileToBuy) + assertTrue(tileBoughtCost < tileToBuyCost) + } +} diff --git a/tests/src/com/unciv/logic/city/managers/CityFounderTest.kt b/tests/src/com/unciv/logic/city/managers/CityFounderTest.kt index 03d0bf0729..805106f488 100644 --- a/tests/src/com/unciv/logic/city/managers/CityFounderTest.kt +++ b/tests/src/com/unciv/logic/city/managers/CityFounderTest.kt @@ -8,6 +8,7 @@ import com.unciv.testing.TestGame import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue +import org.junit.Assert.fail import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -178,4 +179,19 @@ class CityFounderTest { assertEquals(5, uniqueCiv.gold) } + @Test + fun `should not be able to found city in same tile of another city`() { + // given + cityFounder.foundCity(civ, Vector2.Zero) + + // when + try { + cityFounder.foundCity(civ, Vector2.Zero) + } catch (e: IllegalStateException) { + assertEquals("Trying to found a city in a tile that already has one", e.message) + return + } + fail() + } + }