summaryrefslogtreecommitdiff
path: root/sw-common-model
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@gmail.com>2021-06-18 00:18:53 +0200
committerJoffrey Bion <joffrey.bion@gmail.com>2021-06-19 19:06:30 +0200
commitf00cb4f968e0fb7050bae4145e1327e206e268e2 (patch)
tree2a8a0a42944ffa6c69dcbf75c3e152466cac91f3 /sw-common-model
parentUpgrade setup-java Github action to v2 (diff)
downloadseven-wonders-f00cb4f968e0fb7050bae4145e1327e206e268e2.tar.gz
seven-wonders-f00cb4f968e0fb7050bae4145e1327e206e268e2.tar.bz2
seven-wonders-f00cb4f968e0fb7050bae4145e1327e206e268e2.zip
Fix ex-aequo ranks
When 2 players are ex-aequo, the rank of the next player is still supposed to take into account the 2 players in front of thim. So if 2 players are 2nd ex-aequo, the next guy is supposed to be 4th, not 3rd.
Diffstat (limited to 'sw-common-model')
-rw-r--r--sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/score/Score.kt14
-rw-r--r--sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/score/ScoreBoardTest.kt62
2 files changed, 68 insertions, 8 deletions
diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/score/Score.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/score/Score.kt
index 36d0857f..9b0c5fb6 100644
--- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/score/Score.kt
+++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/score/Score.kt
@@ -4,18 +4,16 @@ import kotlinx.serialization.Serializable
@Serializable
data class ScoreBoard(val scores: List<PlayerScore>) {
+ init {
+ require(scores.sortedDescending() == scores) { "Scores must be sorted highest-to-lowest" }
+ }
@OptIn(ExperimentalStdlibApi::class)
val ranks: List<Int>
- get() = buildList {
- var r = 1
+ get() = buildList<Int> {
add(1)
- for (i in 1..scores.lastIndex) {
- if (scores[i] < scores[i - 1]) {
- add(++r)
- } else {
- add(r)
- }
+ scores.zipWithNext { prev, current -> current.compareTo(prev) == 0 }.forEach { exAequoWithPrev ->
+ add(if (exAequoWithPrev) last() else size + 1)
}
}
}
diff --git a/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/score/ScoreBoardTest.kt b/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/score/ScoreBoardTest.kt
new file mode 100644
index 00000000..0e3d904b
--- /dev/null
+++ b/sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/score/ScoreBoardTest.kt
@@ -0,0 +1,62 @@
+package org.luxons.sevenwonders.model.score
+
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class ScoreBoardTest {
+
+ @Test
+ fun ranks_simpleOrder() {
+ val playerScores = listOf(
+ PlayerScore(1, 4, mapOf(ScoreCategory.CIVIL to 2, ScoreCategory.GOLD to 1)),
+ PlayerScore(2, 4, mapOf(ScoreCategory.CIVIL to 5, ScoreCategory.GOLD to 1)),
+ PlayerScore(3, 4, mapOf(ScoreCategory.SCIENCE to 4, ScoreCategory.GOLD to 1)),
+ )
+ val sortedScores = playerScores.sortedDescending()
+ val scoreBoard = ScoreBoard(sortedScores)
+ assertEquals(listOf(2, 3, 1), sortedScores.map { it.playerIndex })
+ assertEquals(listOf(1, 2, 3), scoreBoard.ranks)
+ }
+
+ @Test
+ fun ranks_tiesBrokenByGoldPoints() {
+ val playerScores = listOf(
+ PlayerScore(1, 4, mapOf(ScoreCategory.CIVIL to 2, ScoreCategory.GOLD to 1)),
+ PlayerScore(2, 9, mapOf(ScoreCategory.CIVIL to 5, ScoreCategory.GOLD to 3)),
+ PlayerScore(3, 4, mapOf(ScoreCategory.SCIENCE to 4, ScoreCategory.GOLD to 1)),
+ PlayerScore(4, 4, mapOf(ScoreCategory.SCIENCE to 7, ScoreCategory.GOLD to 1)),
+ )
+ val sortedScores = playerScores.sortedDescending()
+ val scoreBoard = ScoreBoard(sortedScores)
+ assertEquals(listOf(2, 4, 3, 1), sortedScores.map { it.playerIndex })
+ assertEquals(listOf(1, 2, 3, 4), scoreBoard.ranks)
+ }
+
+ @Test
+ fun ranks_tiesBrokenByGoldAmount() {
+ val playerScores = listOf(
+ PlayerScore(1, 4, mapOf(ScoreCategory.CIVIL to 2, ScoreCategory.GOLD to 1)),
+ PlayerScore(2, 6, mapOf(ScoreCategory.CIVIL to 5, ScoreCategory.GOLD to 2)),
+ PlayerScore(3, 4, mapOf(ScoreCategory.SCIENCE to 12, ScoreCategory.GOLD to 1)),
+ PlayerScore(4, 8, mapOf(ScoreCategory.SCIENCE to 5, ScoreCategory.GOLD to 2)),
+ )
+ val sortedScores = playerScores.sortedDescending()
+ val scoreBoard = ScoreBoard(sortedScores)
+ assertEquals(listOf(3, 4, 2, 1), sortedScores.map { it.playerIndex })
+ assertEquals(listOf(1, 2, 3, 4), scoreBoard.ranks)
+ }
+
+ @Test
+ fun ranks_actualTie() {
+ val playerScores = listOf(
+ PlayerScore(1, 4, mapOf(ScoreCategory.CIVIL to 2, ScoreCategory.GOLD to 1)),
+ PlayerScore(2, 6, mapOf(ScoreCategory.CIVIL to 5, ScoreCategory.GOLD to 2)),
+ PlayerScore(3, 4, mapOf(ScoreCategory.SCIENCE to 12, ScoreCategory.GOLD to 1)),
+ PlayerScore(4, 6, mapOf(ScoreCategory.SCIENCE to 5, ScoreCategory.GOLD to 2)),
+ )
+ val sortedScores = playerScores.sortedDescending()
+ val scoreBoard = ScoreBoard(sortedScores)
+ assertEquals(listOf(3, 2, 4, 1), sortedScores.map { it.playerIndex })
+ assertEquals(listOf(1, 2, 2, 4), scoreBoard.ranks)
+ }
+}
bgstack15