diff options
author | Joffrey Bion <joffrey.bion@gmail.com> | 2021-06-18 00:18:53 +0200 |
---|---|---|
committer | Joffrey Bion <joffrey.bion@gmail.com> | 2021-06-19 19:06:30 +0200 |
commit | f00cb4f968e0fb7050bae4145e1327e206e268e2 (patch) | |
tree | 2a8a0a42944ffa6c69dcbf75c3e152466cac91f3 /sw-common-model | |
parent | Upgrade setup-java Github action to v2 (diff) | |
download | seven-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.kt | 14 | ||||
-rw-r--r-- | sw-common-model/src/commonTest/kotlin/org/luxons/sevenwonders/model/score/ScoreBoardTest.kt | 62 |
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) + } +} |