fork(883) download
  1. -- スプラトゥーン攻撃力計算機 v1.1
  2. -- twitter @acple
  3.  
  4. -- 自身の攻撃ギア数と相手の防御ギア数を与えると実際のダメージ値を計算します。
  5.  
  6. -- 実ダメージは攻撃ギア値と防御ギア値から算出した実際に相手に与えるダメージ値を表します。
  7. -- ブキ毎のリミッター値設定も反映しています。
  8.  
  9. -- 確定数変化防御値は指定した攻撃ギア値に対して確定数が変化する防御ギア値を表します。
  10. -- ギアパワー値は メインギア数 * 10 + サブギア数 * 3 で算出されるものです。
  11. -- Nothingは確定数を減らせる防御値が存在しないことを表します。
  12.  
  13. -- この計算式では、極小の誤差が発生します。
  14. -- おそらく、計算途中の丸め処理や、浮動小数の処理系の違いによるものと思われます。
  15. -- 単精度での演算や計算途中での切り捨て処理など、いくつかの計算パターンを試しましたが、
  16. -- 現時点で全ての誤差を埋めるパターンは見つかりませんでした。
  17. -- もし視認できる範囲で誤差を全て消すことが出来たとしても、
  18. -- 目に見えない誤差が存在する可能性は残ります。
  19.  
  20. -- この計算式に適用している係数や、計算手法自体は正しいものであると思われます。
  21. -- 確認可能な全てのブキとギアパワーの組み合わせで誤差がほぼ発生しないことは確認していますが、
  22. -- あくまで参考程度としてよろしくお願いします。
  23.  
  24. -- もしその他計算違いや誤差の処理方法などを見つけた場合、報告いただけると助かります。
  25.  
  26. module Main ( main ) where
  27.  
  28. import System.IO
  29. import Data.List (intercalate)
  30.  
  31. -- ↓イカの4つを好きな値に変更してね↓ --
  32.  
  33. -- 自分のメイン攻撃ギア数
  34. mainAttackGear = 1
  35.  
  36. -- 自分のサブ攻撃ギア数
  37. subAttackGear = 2
  38.  
  39. -- 相手のメイン防御ギア数
  40. mainDefendGear = 1
  41.  
  42. -- 相手のサブ防御ギア数
  43. subDefendGear = 0
  44.  
  45. -- ↑-------書き換えここまで--------↑ --
  46.  
  47. -- イカは出力用コード
  48.  
  49. mainAttackGear :: Int
  50. subAttackGear :: Int
  51. mainDefendGear :: Int
  52. subDefendGear :: Int
  53.  
  54. data Weapon = Weapon String -- ブキ名
  55. Double -- 基本攻撃力
  56.  
  57. instance Show Weapon where
  58. show (Weapon name damage) = "{"
  59. ++ " ブキ: " ++ name
  60. ++ ", 基本攻撃力: " ++ show damage
  61. ++ ", 実ダメージ: " ++ show (calculateDamage damage atk def)
  62. ++ ", 確定数変化防御値: " ++ show (happyDefendPower damage atk)
  63. ++ " }"
  64. where atk = gearPower mainAttackGear subAttackGear
  65. def = gearPower mainDefendGear subDefendGear
  66. showList = (++) . intercalate "\n" . map show
  67.  
  68. weapons :: [Weapon]
  69. weapons = [ Weapon "わかばシューター" 28.0
  70. , Weapon "スプラシューター" 36.0
  71. , Weapon "プライムシューター" 42.0
  72. , Weapon "プロモデラー" 24.5
  73. , Weapon "N-ZAP85" 28.0
  74. , Weapon ".52ガロン" 52.0
  75. , Weapon ".96ガロン" 62.0
  76. , Weapon "ジェットスイーパー" 31.0
  77. , Weapon "デュアルスイーパー" 28.0
  78. , Weapon "シャープマーカー" 26.0
  79. , Weapon "ボールドマーカー" 38.0
  80. , Weapon "L3リールガン" 29.0
  81. , Weapon "ホットブラスター" 125.0
  82. , Weapon "ブラスター爆風外周" 50.0
  83. , Weapon "ラピッドブラスター" 80.0
  84. , Weapon "ラピッド爆風外周" 25.0
  85. , Weapon "スプラチャージャー" 160.0
  86. , Weapon "スクイックリン" 140.0
  87. , Weapon "リッター3K" 180.0
  88. , Weapon "ノーチャージャー" 40.0
  89. , Weapon "バケットスロッシャー" 70.0
  90. , Weapon "スロッシャー根元" 40.0
  91. , Weapon "バレルスピナー" 28.0
  92. , Weapon "ボム" 180.0
  93. , Weapon "ボム爆風外周" 30.0
  94. , Weapon "クイックボム直撃" 25.0
  95. , Weapon "クイック爆風(近)" 35.0
  96. , Weapon "クイック爆風(遠)" 20.0
  97. , Weapon "チェイス爆風(近)" 80.0
  98. , Weapon "チェイス爆風(遠)" 20.0
  99. , Weapon "スプラッシュシールド" 50.0
  100. , Weapon "スプリンクラー" 30.0
  101. , Weapon "スーパーショット" 150.0
  102. , Weapon "ダイオウイカ" 160.0 ]
  103.  
  104. main :: IO ()
  105. main = do
  106. hSetEncoding stdout utf8
  107. putStrLn $ "自攻撃ギアパワー: " ++ show (gearPower mainAttackGear subAttackGear)
  108. ++ ", 敵防御ギアパワー: " ++ show (gearPower mainDefendGear subDefendGear)
  109. print weapons
  110.  
  111. -- イカは計算式
  112.  
  113. -- ギアパワー値を返す
  114. gearPower :: Int -> Int -> Int
  115. gearPower mainGear subGear = mainGear * 10 + subGear * 3
  116.  
  117. -- 実ダメージを返す
  118. calculateDamage :: Double -> Int -> Int -> Double
  119. calculateDamage dmg atk def = limiting (limitDamage dmg) (dmg * rate atk def)
  120. where limiting Nothing result = result
  121. limiting (Just limit) result = min limit result
  122.  
  123. -- ダメージの変動率を返す
  124. rate :: Int -> Int -> Double
  125. rate atk def = 1.0 + correct (calculatePower atk - calculatePower def)
  126. where correct x | x < 0 = x / 1.8
  127. | otherwise = x
  128.  
  129. -- ギアパワーの補正率を返す
  130. calculatePower :: Int -> Double
  131. calculatePower i = ((0.99 * n) - (0.09 * n) ^ (2 :: Int)) / 100.0
  132. where n = fromIntegral i
  133.  
  134. -- 攻撃力のリミット値を返す
  135. limitDamage :: Double -> Maybe Double
  136. limitDamage x | 100.0 <= x = Nothing
  137. | otherwise = Just $ floorN 1 $ 99.9 / fromIntegral (over100Damage x - 1)
  138.  
  139. -- 攻撃の確定数を返す
  140. over100Damage :: Double -> Int
  141. over100Damage = length . takeWhile (< 100.0) . scanl (+) 0.0 . repeat
  142.  
  143. -- 攻撃の確定数を減らせる防御値を返す
  144. happyDefendPower :: Double -> Int -> Maybe Int
  145. happyDefendPower dmg atk | 58 <= count = Nothing
  146. | otherwise = Just count
  147. where count = (+ 1) . length . takeWhile id $ zipWith (==) list (tail list)
  148. list = map over100Damage $ defendDamageList dmg atk
  149.  
  150. -- 各防御値に対する実ダメージのリストを返す
  151. defendDamageList :: Double -> Int -> [Double]
  152. defendDamageList dmg atk = map (calculateDamage dmg atk) [0..57]
  153.  
  154. -- 小数点第n位までで切り捨てを行った値を返す
  155. floorN :: Int -> Double -> Double
  156. floorN = roundWith floor
  157.  
  158. -- 小数点第n位までで切り上げを行った値を返す
  159. ceilingN :: Int -> Double -> Double
  160. ceilingN = roundWith ceiling
  161.  
  162. -- 小数点第n位までで偶数丸めを行った値を返す
  163. roundN :: Int -> Double -> Double
  164. roundN = roundWith round
  165.  
  166. -- 指定した丸め関数を使用し小数点第n位までで丸めを行った値を返す
  167. roundWith :: (RealFrac a) => (a -> Integer) -> Int -> a -> a
  168. roundWith rounder n = (/ x) . fromInteger . rounder . (* x)
  169. where x = 10 ^ n
  170.  
Success #stdin #stdout 0s 4752KB
stdin
Standard input is empty
stdout
自攻撃ギアパワー: 16, 敵防御ギアパワー: 10
{ ブキ: わかばシューター, 基本攻撃力: 28.0, 実ダメージ: 29.309392, 確定数変化防御値: Nothing }
{ ブキ: スプラシューター, 基本攻撃力: 36.0, 実ダメージ: 37.683504, 確定数変化防御値: Just 42 }
{ ブキ: プライムシューター, 基本攻撃力: 42.0, 実ダメージ: 43.964088, 確定数変化防御値: Nothing }
{ ブキ: プロモデラー, 基本攻撃力: 24.5, 実ダメージ: 24.9, 確定数変化防御値: Nothing }
{ ブキ: N-ZAP85, 基本攻撃力: 28.0, 実ダメージ: 29.309392, 確定数変化防御値: Nothing }
{ ブキ: .52ガロン, 基本攻撃力: 52.0, 実ダメージ: 54.431728, 確定数変化防御値: Just 27 }
{ ブキ: .96ガロン, 基本攻撃力: 62.0, 実ダメージ: 64.899368, 確定数変化防御値: Nothing }
{ ブキ: ジェットスイーパー, 基本攻撃力: 31.0, 実ダメージ: 32.449684, 確定数変化防御値: Nothing }
{ ブキ: デュアルスイーパー, 基本攻撃力: 28.0, 実ダメージ: 29.309392, 確定数変化防御値: Nothing }
{ ブキ: シャープマーカー, 基本攻撃力: 26.0, 実ダメージ: 27.215864, 確定数変化防御値: Just 27 }
{ ブキ: ボールドマーカー, 基本攻撃力: 38.0, 実ダメージ: 39.777032, 確定数変化防御値: Nothing }
{ ブキ: L3リールガン, 基本攻撃力: 29.0, 実ダメージ: 30.356156, 確定数変化防御値: Nothing }
{ ブキ: ホットブラスター, 基本攻撃力: 125.0, 実ダメージ: 130.8455, 確定数変化防御値: Nothing }
{ ブキ: ブラスター爆風外周, 基本攻撃力: 50.0, 実ダメージ: 52.3382, 確定数変化防御値: Just 17 }
{ ブキ: ラピッドブラスター, 基本攻撃力: 80.0, 実ダメージ: 83.74112, 確定数変化防御値: Nothing }
{ ブキ: ラピッド爆風外周, 基本攻撃力: 25.0, 実ダメージ: 26.1691, 確定数変化防御値: Just 17 }
{ ブキ: スプラチャージャー, 基本攻撃力: 160.0, 実ダメージ: 167.48224, 確定数変化防御値: Nothing }
{ ブキ: スクイックリン, 基本攻撃力: 140.0, 実ダメージ: 146.54696, 確定数変化防御値: Nothing }
{ ブキ: リッター3K, 基本攻撃力: 180.0, 実ダメージ: 188.41752, 確定数変化防御値: Nothing }
{ ブキ: ノーチャージャー, 基本攻撃力: 40.0, 実ダメージ: 41.87056, 確定数変化防御値: Nothing }
{ ブキ: バケットスロッシャー, 基本攻撃力: 70.0, 実ダメージ: 73.27348, 確定数変化防御値: Nothing }
{ ブキ: スロッシャー根元, 基本攻撃力: 40.0, 実ダメージ: 41.87056, 確定数変化防御値: Nothing }
{ ブキ: バレルスピナー, 基本攻撃力: 28.0, 実ダメージ: 29.309392, 確定数変化防御値: Nothing }
{ ブキ: ボム, 基本攻撃力: 180.0, 実ダメージ: 188.41752, 確定数変化防御値: Nothing }
{ ブキ: ボム爆風外周, 基本攻撃力: 30.0, 実ダメージ: 31.40292, 確定数変化防御値: Nothing }
{ ブキ: クイックボム直撃, 基本攻撃力: 25.0, 実ダメージ: 26.1691, 確定数変化防御値: Just 17 }
{ ブキ: クイック爆風(近), 基本攻撃力: 35.0, 実ダメージ: 36.63674, 確定数変化防御値: Just 30 }
{ ブキ: クイック爆風(遠), 基本攻撃力: 20.0, 実ダメージ: 20.93528, 確定数変化防御値: Just 17 }
{ ブキ: チェイス爆風(近), 基本攻撃力: 80.0, 実ダメージ: 83.74112, 確定数変化防御値: Nothing }
{ ブキ: チェイス爆風(遠), 基本攻撃力: 20.0, 実ダメージ: 20.93528, 確定数変化防御値: Just 17 }
{ ブキ: スプラッシュシールド, 基本攻撃力: 50.0, 実ダメージ: 52.3382, 確定数変化防御値: Just 17 }
{ ブキ: スプリンクラー, 基本攻撃力: 30.0, 実ダメージ: 31.40292, 確定数変化防御値: Nothing }
{ ブキ: スーパーショット, 基本攻撃力: 150.0, 実ダメージ: 157.0146, 確定数変化防御値: Nothing }
{ ブキ: ダイオウイカ, 基本攻撃力: 160.0, 実ダメージ: 167.48224, 確定数変化防御値: Nothing }