Created
October 31, 2015 23:29
-
-
Save torao/69844eeb2a922f31fcda to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copy & paste to scala REPL | |
trait Mod { val name:String; val rarity:Int } | |
class HeatSink(val name:String, val effect:Double, val rarity:Int) extends Mod | |
case object CHS extends HeatSink("CHS", 0.3, 1) | |
case object RHS extends HeatSink("RHS", 0.5, 2) | |
case object VRHS extends HeatSink("VRHS", 0.7, 3) | |
val heatSink = Seq(CHS, RHS, VRHS) | |
class MultiHack(val name:String, val effect:Int, val rarity:Int) extends Mod | |
case object CMH extends MultiHack("CMH", 4, 1) | |
case object RMH extends MultiHack("RMH", 8, 2) | |
case object VRMH extends MultiHack("VRMH", 12, 3) | |
val multiHack = Seq(CMH, RMH, VRMH) | |
case class Slots(mods:Seq[Mod]){ | |
lazy val hackCount = mods.collect{ case mh:MultiHack => mh }.sortBy{ - _.rarity }.toList match { | |
case Nil => 4 | |
case mh :: Nil => 4 + mh.effect | |
case head :: rest => 4 + head.effect + rest.map{ _.effect / 2 }.sum | |
} | |
lazy val cooldown = mods.collect{ case hs:HeatSink => hs }.sortBy{ - _.rarity }.toList match { | |
case Nil => 5 * 60.0 | |
case hs :: Nil => 5 * 60.0 * (1 - hs.effect) | |
case head :: rest => 5 * 60.0 * (1 - head.effect) * rest.map{ x => (1 - x.effect / 2.0) }.product | |
} | |
lazy val rarity = mods.map{ _.rarity }.sum | |
override def toString = mods.mkString(",") | |
} | |
val allSlotPatterns:Seq[Slots] = { | |
val mods = (heatSink ++ multiHack) | |
def select(rest:Int):Seq[Seq[Mod]] = if(rest == 0) Seq(Seq()) else { | |
select(rest - 1).flatMap { t => | |
mods.map{ _ +: t } | |
} | |
} | |
(0 to 4).flatMap { maxMods => select(maxMods) }.map{ s => new Slots(s.sortBy{ _.name }.reverse) }.distinct | |
} | |
case class Hack(name:String, cost:Int, effect:Double) | |
val hackBonus = (1.625+0.5+0.4)/2 // 1.625 | |
val glyphHack = Hack("glyph", 30, 1 + hackBonus) | |
val normalHack = Hack("normal", 5, 1.0) | |
val slotSpace = 0 | |
(1 to 13).foreach{ portals => | |
(1 to 3).foreach{ frackers => | |
Seq(normalHack, glyphHack).foreach{ hack => | |
val limit = frackers * 10.0 * 60.0 | |
val hacks = allSlotPatterns.map{ slot => | |
val interval = math.max(0, slot.cooldown - (portals - 1) * hack.cost) // 1周ごとに必要な待ち | |
val cycle = limit / (portals * hack.cost + interval) | |
val hackCount = math.min(cycle * portals, slot.hackCount * portals) | |
(hackCount, interval, slot) | |
} | |
hacks.filter{ _._3.mods.size <= 4 - slotSpace }.groupBy{ _._1 }.maxBy{ _._1 }._2.groupBy{ _._3.rarity }.minBy{ _._1 }._2.distinct.foreach{ case (hackCount, interval, slot) => | |
println(f"$portals\t$frackers\t${hack.name}\t$slot\t${slot.cooldown}%.0f\t$interval%.0f\t$hackCount%.0f\t${hackCount*hack.effect*2}%.0f\t${150/(hackCount/frackers/portals)}%.1f") | |
} | |
} | |
} | |
} | |
// -------------------------------- | |
(1 to 20).foreach{ portals => | |
println(portals + "\t" + | |
Seq(normalHack, Hack("glyph(0%)", 30, 1 + 0.4), Hack("glyph(50%)", 30, 1 + hackBonus), Hack("glyph(100%)", 30, 1 + 1.625+0.5)).map{ hack => | |
val limit = 5 * 10.0 * 60.0 | |
val hacks = allSlotPatterns.map{ slot => | |
val interval = math.max(0, slot.cooldown - (portals - 1) * hack.cost) // 1周ごとに必要な待ち | |
val cycle = limit / (portals * hack.cost + interval) | |
val hackCount = math.min(cycle * portals, slot.hackCount * portals) | |
(hackCount, interval, slot) | |
} | |
hacks.filter{ _._3.mods.size <= 4 - slotSpace }.groupBy{ _._1 }.maxBy{ _._1 }._2.groupBy{ _._3.rarity }.minBy{ _._1 }._2.distinct.head match { case (hackCount, interval, slot) => | |
f"${hackCount*hack.effect*2}%.0f" | |
} | |
}.mkString("\t")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment