Refactor
authorTheSaminator <thesaminator@users.noreply.github.com>
Tue, 5 Jul 2022 20:28:45 +0000 (16:28 -0400)
committerTheSaminator <thesaminator@users.noreply.github.com>
Tue, 5 Jul 2022 20:28:45 +0000 (16:28 -0400)
src/commonMain/kotlin/net/starshipfights/game/util.kt
src/jvmMain/kotlin/net/starshipfights/campaign/cluster_fleets.kt
src/jvmMain/kotlin/net/starshipfights/campaign/cluster_test.kt
src/jvmMain/kotlin/net/starshipfights/data/admiralty/admirals.kt

index e53fc7b6fa8bd55ead2033f8da0567105e2165f6..72dfbcbfcd4c85caa2021a4d29b9d8223d98e7ed 100644 (file)
@@ -12,6 +12,7 @@ import kotlin.math.abs
 import kotlin.math.exp
 import kotlin.math.pow
 import kotlin.math.roundToInt
+import kotlin.random.Random
 
 val jsonSerializer = Json {
        classDiscriminator = "\$ktClass"
@@ -57,3 +58,22 @@ inline fun <T : FlowOrPhrasingContent> T.foreign(language: String, crossinline b
        style = "font-style: italic"
        block()
 }
+
+fun Random.nextIrwinHallInteger(max: Int): Int {
+       require(max > 0) { "Random.nextIrwinHallInteger must take positive max parameter, got $max!" }
+       return (1 until max).sumOf { (0..1).random(this) }
+}
+
+fun Random.nextDiminishingInteger(max: Int, increaseChance: Double = 0.5): Int {
+       require(max > 0) { "Random.nextDiminishingInteger must take positive max parameter, got $max!" }
+       
+       var curr = 0
+       while (curr + 1 < max && nextDouble() < increaseChance)
+               curr++
+       return curr
+}
+
+fun <T> Iterable<T>.repeatForever(): Sequence<T> = sequence {
+       while (true)
+               yieldAll(this@repeatForever)
+}
index 9af7fa33c6b10ec62504f4e9468d0c5fb17cd10e..763c1b5b1c61e867d03b76627687c2c239a32c6a 100644 (file)
@@ -37,7 +37,7 @@ val FactionFlavor.shipSource: Faction
        }
 
 fun generateNPCFleet(owner: FactionFlavor, rank: AdmiralRank): Map<Id<Ship>, Ship> {
-       val battleSize = BattleSize.values().filter { rank >= it.minRank }.associateWith { 100.0 / it.numPoints }.weightedRandom()
+       val battleSize = BattleSize.values().filter { rank.maxShipTier >= it.maxTier }.associateWith { 100.0 / it.numPoints }.weightedRandom()
        
        val possibleShips = ShipType.values().filter { it.faction == owner.shipSource && it.weightClass.tier <= battleSize.maxTier }
        val maxPoints = battleSize.numPoints
index 78b8c39347206e80bac821b6e435d6b3bc0b4a17..7379eae22defc7bd43c061108ca485420b544d8d 100644 (file)
@@ -5,27 +5,26 @@ import net.starshipfights.data.admiralty.AdmiralNameFlavor
 import net.starshipfights.data.admiralty.AdmiralNames
 import net.starshipfights.data.invoke
 import net.starshipfights.data.space.generateFleetName
-import net.starshipfights.game.AdmiralRank
-import net.starshipfights.game.FactionFlavor
+import net.starshipfights.game.*
 import kotlin.random.Random
 
 fun StarClusterView.testPostProcess(): StarClusterView {
-       val flavors = FactionFlavor.values().toList().shuffled()
-       val ownerFlavors = sequence {
-               while (true)
-                       for (flavor in flavors)
-                               yield(flavor)
-       }.take(systems.size).toList()
+       val ownerFlavors = FactionFlavor.values()
+               .toList()
+               .shuffled()
+               .repeatForever()
+               .take(systems.size)
+               .toList()
        
        val ownedSystems = (systems.toList().shuffled() zip ownerFlavors).associate { (systemWithId, flavor) ->
                val (systemId, system) = systemWithId
                
-               val numOfFleets = (0..1).random() + (0..1).random() + (0..1).random()
+               val numOfFleets = 3 - Random.nextDiminishingInteger(4)
                if (numOfFleets == 0)
                        return@associate systemId to system
                
                val fleets = (1..numOfFleets).associate { _ ->
-                       val admiralRank = AdmiralRank.values().random()
+                       val admiralRank = AdmiralRank.values()[Random.nextIrwinHallInteger(AdmiralRank.values().size)]
                        val admiralIsFemale = flavor == FactionFlavor.FELINAE_FELICES || Random.nextBoolean()
                        val admiralFleet = generateNPCFleet(flavor, admiralRank)
                        
index e5806f49d9db6d0c7e49bdd5bdc2b3c8686a4bc6..19dfc90f6b30136dec0db65ce92a54360ef5ddc0 100644 (file)
@@ -146,16 +146,13 @@ suspend fun getAdmiralsShips(admiralId: Id<Admiral>): Map<Id<Ship>, Ship> {
 
 fun generateFleet(admiral: Admiral, flavor: FactionFlavor = FactionFlavor.defaultForFaction(admiral.faction)): List<ShipInDrydock> = ShipWeightClass.values()
        .flatMap { swc ->
-               val shipTypes = ShipType.values().filter { st ->
+               ShipType.values().filter { st ->
                        st.weightClass == swc && st.faction == admiral.faction
-               }.shuffled()
-               
-               if (shipTypes.isEmpty())
-                       emptyList()
-               else
-                       (0 until ((admiral.rank.maxShipTier.ordinal - swc.tier.ordinal + 1) * 2).coerceAtLeast(0)).map { i ->
-                               shipTypes[i % shipTypes.size]
-                       }
+               }.shuffled().takeIf { it.isNotEmpty() }?.let { shipTypes ->
+                       val wcCount = (admiral.rank.maxShipTier.ordinal - swc.tier.ordinal + 1) * 2
+                       
+                       shipTypes.repeatForever().take(wcCount).toList()
+               }.orEmpty()
        }
        .let { shipTypes ->
                val now = Instant.now().minusMillis(100L)