Coverage Summary for Class: RankThreshold (core)

Class Class, % Method, % Branch, % Line, % Instruction, %
RankThreshold 100% (1/1) 100% (1/1) 100% (5/5) 100% (22/22)


 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)
 }