Coverage Summary for Class: RankThresholdKt (core)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| RankThresholdKt |
100%
(1/1)
|
100%
(3/3)
|
70%
(7/10)
|
100%
(13/13)
|
92.6%
(125/135)
|
package core
/**
* Guild rank progression threshold and scaling parameters.
*
* ## Role
* - Defines the contract completion requirements and resource multipliers for each guild rank.
* - Used by progression logic to determine rank-ups and daily generation scaling.
*
* @property rankOrdinal Guild rank ordinal (1=F, 2=E, ..., 7=S).
* @property contractsRequired Cumulative completed contracts needed to reach this rank.
* @property inboxMultiplier Multiplier for daily inbox draft generation at this rank.
* @property heroesMultiplier Multiplier for daily hero arrivals at this rank.
*/
data class RankThreshold(
val rankOrdinal: Int,
val contractsRequired: Int,
val inboxMultiplier: Int,
val heroesMultiplier: Int
)
/**
* Progression table defining thresholds for all guild ranks.
*
* ## Contract
* - Ordered by `rankOrdinal` ascending (F=1 through S=7).
* - Each entry specifies the cumulative contracts needed and resource multipliers.
*
* ## Invariants
* - `contractsRequired` values are strictly increasing.
* - `rankOrdinal` values are unique and sequential (1..7).
*/
val RANK_THRESHOLDS = listOf(
RankThreshold(rankOrdinal = 1, contractsRequired = 0, inboxMultiplier = 1, heroesMultiplier = 1), // F
RankThreshold(rankOrdinal = 2, contractsRequired = 10, inboxMultiplier = 2, heroesMultiplier = 2), // E
RankThreshold(rankOrdinal = 3, contractsRequired = 30, inboxMultiplier = 3, heroesMultiplier = 3), // D
RankThreshold(rankOrdinal = 4, contractsRequired = 60, inboxMultiplier = 4, heroesMultiplier = 4), // C
RankThreshold(rankOrdinal = 5, contractsRequired = 100, inboxMultiplier = 5, heroesMultiplier = 5), // B
RankThreshold(rankOrdinal = 6, contractsRequired = 150, inboxMultiplier = 6, heroesMultiplier = 6), // A
RankThreshold(rankOrdinal = 7, contractsRequired = 250, inboxMultiplier = 7, heroesMultiplier = 7) // S
)
/**
* Computes guild rank progression based on completed contract count.
*
* ## Contract
* - Finds highest threshold where `completedContracts >= contractsRequired`.
* - Returns new rank ordinal and contracts needed for the next rank.
*
* ## Preconditions
* - `completedContracts >= 0`
*
* ## Postconditions
* - First element is the new rank ordinal (1..7).
* - Second element is the contract threshold for the next rank (or `Int.MAX_VALUE` if maxed).
*
* ## Determinism
* - Pure function; same inputs always produce same outputs.
*
* ## Complexity
* - Time: O(n) where n = number of rank thresholds.
* - Memory: O(1)
*
* @param completedContracts Total lifetime completed contracts.
* @param _currentRankOrdinal Current rank (unused; progression is history-based).
* @return Pair of (newRankOrdinal, contractsForNextRank).
*/
fun calculateNextRank(completedContracts: Int, _currentRankOrdinal: Int): Pair<Int, Int> {
// Find highest threshold <= completedContracts
val newRankThreshold = RANK_THRESHOLDS.lastOrNull { completedContracts >= it.contractsRequired } ?: RANK_THRESHOLDS.first()
val newRank = newRankThreshold.rankOrdinal
// Determine next threshold (contracts required for next rank)
val nextThreshold = RANK_THRESHOLDS.firstOrNull { it.rankOrdinal > newRank } ?: RANK_THRESHOLDS.last()
val contractsForNext = if (nextThreshold.rankOrdinal == newRank) Int.MAX_VALUE else nextThreshold.contractsRequired
return Pair(newRank, contractsForNext)
}