Skip to content

Commit 5e37818

Browse files
authored
Merge pull request #3 from AutumnPizazz/my-test
my-test
2 parents df39961 + da3e91d commit 5e37818

File tree

2 files changed

+64
-23
lines changed

2 files changed

+64
-23
lines changed

core/src/com/unciv/models/ruleset/unique/Countables.kt

+62-23
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import kotlin.math.pow
88
object Countables {
99

1010
fun getCountableAmount(countable: String, stateForConditionals: StateForConditionals): Int? {
11-
if (!countable.contains('[') && !countable.contains(']')) {
12-
return simpleCountableAmount(countable, stateForConditionals)
11+
if (isExpression(countable)) {
12+
return evaluateExpression(countable, stateForConditionals)
1313
}
14-
return evaluateExpression(countable, stateForConditionals)
14+
return simpleCountableAmount(countable, stateForConditionals)
1515
}
1616

1717
private fun simpleCountableAmount(countable: String, stateForConditionals: StateForConditionals): Int? {
@@ -30,29 +30,54 @@ object Countables {
3030
if (countable == "Cities") return civInfo.cities.size
3131

3232
val placeholderParameters = countable.getPlaceholderParameters()
33-
if (countable.equalsPlaceholderText("[] Cities"))
34-
return civInfo.cities.count { it.matchesFilter(placeholderParameters[0]) }
33+
if (countable.equalsPlaceholderText("[] Cities")) {
34+
val filter = placeholderParameters[0]
35+
return civInfo.cities.count { it.matchesFilter(filter) }
36+
}
3537

3638
if (countable == "Units") return civInfo.units.getCivUnitsSize()
37-
if (countable.equalsPlaceholderText("[] Units"))
38-
return civInfo.units.getCivUnits().count { it.matchesFilter(placeholderParameters[0]) }
39+
if (countable.equalsPlaceholderText("[] Units")) {
40+
val filter = placeholderParameters[0]
41+
return civInfo.units.getCivUnits().count { it.matchesFilter(filter) }
42+
}
3943

40-
if (countable.equalsPlaceholderText("[] Buildings"))
41-
return civInfo.cities.sumOf { it.cityConstructions.getBuiltBuildings()
42-
.count { it.matchesFilter(placeholderParameters[0]) } }
44+
if (countable.equalsPlaceholderText("[] Buildings")) {
45+
val filter = placeholderParameters[0]
46+
var totalBuildings = 0
47+
for (city in civInfo.cities) {
48+
val builtBuildings = city.cityConstructions.getBuiltBuildings()
49+
totalBuildings += builtBuildings.count { it.matchesFilter(filter) }
50+
}
51+
return totalBuildings
52+
}
4353

44-
if (countable.equalsPlaceholderText("Remaining [] Civilizations"))
45-
return gameInfo.civilizations.filter { !it.isDefeated() }
46-
.count { it.matchesFilter(placeholderParameters[0]) }
54+
if (countable.equalsPlaceholderText("Remaining [] Civilizations")) {
55+
val filter = placeholderParameters[0]
56+
var remainingCivs = 0
57+
for (civ in gameInfo.civilizations) {
58+
if (!civ.isDefeated() && civ.matchesFilter(filter)) {
59+
remainingCivs++
60+
}
61+
}
62+
return remainingCivs
63+
}
4764

48-
if (countable.equalsPlaceholderText("Completed Policy branches"))
65+
if (countable.equalsPlaceholderText("Completed Policy branches")) {
4966
return civInfo.getCompletedPolicyBranchesCount()
67+
}
5068

51-
if (countable.equalsPlaceholderText("Owned [] Tiles"))
52-
return civInfo.cities.sumOf { it.getTiles().count { it.matchesFilter(placeholderParameters[0]) } }
69+
if (countable.equalsPlaceholderText("Owned [] Tiles")) {
70+
val filter = placeholderParameters[0]
71+
var totalTiles = 0
72+
for (city in civInfo.cities) {
73+
totalTiles += city.getTiles().count { it.matchesFilter(filter) }
74+
}
75+
return totalTiles
76+
}
5377

54-
if (gameInfo.ruleset.tileResources.containsKey(countable))
78+
if (gameInfo.ruleset.tileResources.containsKey(countable)) {
5579
return stateForConditionals.getResourceAmount(countable)
80+
}
5681

5782
return null
5883
}
@@ -65,15 +90,22 @@ object Countables {
6590
}
6691

6792
private fun parseExpression(expression: String): List<String> {
68-
val regex = Regex("([+\\-*/%^()]|\\[[^]]+]|\\b\\w+\\b)")
93+
val regex = Regex(
94+
"(?:^|(?<=]))\\s*(\\[[^\\[\\]]*(?:\\[[^\\[\\]]*][^\\[\\]]*)*])|([+\\-*/%^()])|(\\d+)"
95+
)
6996
val matches = regex.findAll(expression)
7097
val tokens = mutableListOf<String>()
7198
for (match in matches) {
72-
tokens.add(match.value)
99+
val token = match.groups.asSequence()
100+
.filter { it != null && it.value.isNotEmpty() }
101+
.firstOrNull()?.value
102+
?.trim()
103+
if (!token.isNullOrEmpty()) {
104+
tokens.add(token)
105+
}
73106
}
74107
return tokens
75108
}
76-
77109
private fun calculateExpression(tokens: List<String>, stateForConditionals: StateForConditionals): Int? {
78110
val outputQueue = mutableListOf<String>()
79111
val operatorStack = mutableListOf<String>()
@@ -83,7 +115,7 @@ object Countables {
83115
outputQueue.add(token)
84116
} else if (token.startsWith("[") && token.endsWith("]")) {
85117
val innerToken = token.substring(1, token.length - 1)
86-
val value = getCountableAmount(innerToken, stateForConditionals)
118+
val value = simpleCountableAmount(innerToken, stateForConditionals)
87119
if (value == null) return null
88120
outputQueue.add(value.toString())
89121
} else if (token == "(") {
@@ -105,6 +137,7 @@ object Countables {
105137
}
106138
}
107139

140+
108141
while (operatorStack.isNotEmpty()) {
109142
outputQueue.add(operatorStack.removeLast())
110143
}
@@ -122,8 +155,8 @@ object Countables {
122155
"+" -> a + b
123156
"-" -> a - b
124157
"*" -> a * b
125-
"/" -> if (b == 0) return null else a / b
126-
"%" -> if (b == 0) return null else a % b
158+
"/" -> if (b == 0) return 0 else a / b
159+
"%" -> if (b == 0) return 0 else a % b
127160
"^" -> a.toDouble().pow(b.toDouble()).toInt()
128161
else -> return null
129162
}
@@ -150,4 +183,10 @@ object Countables {
150183
else -> 0
151184
}
152185
}
186+
187+
private fun isExpression(countable: String): Boolean {
188+
return countable.contains(' ') || countable.contains('+') || countable.contains('-') ||
189+
countable.contains('*') || countable.contains('/') || countable.contains('%') ||
190+
countable.contains('^') || countable.contains('(') || countable.contains(')')
191+
}
153192
}

docs/Modders/Unique-parameters.md

+2
Original file line numberDiff line numberDiff line change
@@ -363,3 +363,5 @@ Allowed *complex* values:
363363
- `[complex value] ^ [complex value]` - such as `[Cities] ^ 2`
364364

365365
In addition, complex nested expressions can also be used, such as: `([Cities] + [turns]) * 2 + [Units]`. Note that the precedence of the five operations follows mathematical intuition: exponentiation has the highest precedence, followed by multiplication, division, and modulus, and then addition and subtraction have the lowest precedence. If you need to adjust the precedence, please use parentheses.
366+
367+
Specifically, when calculating n/0 or n%0 , although these operations are meaningless, we still compute them as 0.

0 commit comments

Comments
 (0)