arupocoのメモ帳

ツイッターに書ききれないこととか

リヴリーエサ計算機のアルゴリズムについて

cinzanono.hatenablog.com

これのアルゴリズムを自分で書いてて「これ一週間後の自分が訳分からなくなりそうだな……」と思ったので自分向けにメモするけど、一応何かの役に立つかもなので公開しとく。

数学とか統計とかの知識あったらもっと効率よくなりそうな気もするけどまあええやろ。

 

前提条件

・テントウ・バッタ・コガネは上がる色が+4、それ以外が-2。いずれもRGBの合計値は変わらない

・3色の幼虫は上がる色のみ+7、RGBの合計値+7

・カブトムシの幼虫は全色+2、RGBの合計値+6

・アリは全色-2、RGBの合計値-6

→RGBの合計値を上げるときはカブトムシの幼虫*3よりも3色の幼虫それぞれ1つずつのが効率的。満腹度や値段なども考え、カブトムシの幼虫を考慮に入れないことに(微調整する時はカブトムシの幼虫を使った方が効率的かもしれないけど)

 

以下、「幼虫」と言ったら3色の幼虫のどれかを、「成虫」と言ったらテントウ・バッタ・コガネを指す。

 

誤差ありの場合

まず目標値までのRGBの合計値がどれくらい差があるかを計算する。足りないなら足りない色を優先して幼虫をあげる。余分ならアリをあげる(合計値を下げるのがアリしかいないので)

合計量の誤差は±2に抑える。各色につき±2許容なので±3くらいもでもいいけど思ったけど足りない量が[+3,+1,-1]の時にハマるので妥協した。

幼虫とアリで合計量の誤差を±2に抑えたら成虫で足りない色を上げて余分な色を下げれば完了。

(一応後述の余分なエサを消す処理も後に行うが、引っかかることはまずない。あっても成虫すべて1つ以上あげているのを引いてるくらい)

 

誤差なしの場合

以下、全て赤色を上げる場合で例示する。他の色を上げる場合は赤緑青を入れ替える。

まず1色ずつ以下の方法で+7,+1,-6,-1していき、正確な値を作る。

(1):+7…赤幼虫をあげる

(2):+1…赤幼虫・アリ・緑成虫・青成虫をあげる

(3):-6…アリ・緑成虫・青成虫をあげる

(4):-1…赤成虫1・赤幼虫1・青幼虫2・緑幼虫2・アリ6をあげる

 

その後、以下の法則で不要なエサを消せなくなるまでどんどん消していく。

(変換1):赤幼虫・アリ7 → 赤成虫7

(変換2):赤成虫5・緑幼虫4・青幼虫4・アリ7 → 緑成虫2・青成虫2・赤幼虫2

(変換3):赤成虫8・緑成虫1・青幼虫6 → 青成虫6・赤幼虫6

(変換4):緑成虫4・青幼虫4・赤幼虫4 → 赤成虫3・緑幼虫2・青幼虫2

(打消1):成虫全色 → (無し)

(打消2):幼虫全色2ずつ・アリ7 → (無し)

 

備考

誤差あり・なしでアルゴリズムを変えているのは、アリと幼虫の合計を最小に抑えるため。

 

限界値を考慮するなら、以下のような考え方で更にエサの量を削減できる。(未実装)

・どれか1つが+255の場合(例:赤)

 他の色で余分な値があれば赤成虫をあげ続けて+1~+2になるまで下げる。(2ずつ下がるので絶対この範囲に収まる)

 → 他の色で足りない色があれば幼虫をあげ続けて-2~+4になるまで下げる。(7ずつ上がるので絶対この範囲に収まる)

 → 赤以外が-2~+4の範囲になる。片方or両方が+3~+4なら成虫1個あげれば範囲内に収まる

 → あとは赤幼虫をあげ続けて253以上にする

 

・どれか2つが+255の場合:限界値にしない色をアリ使わずに適当に調整してから幼虫あげまくるだけ

 

・全部+255:幼虫

 

-255はいくつあっても多分普通の誤差ありと変わらないはず。

 

限界値考慮は、細かくRGBを盛ろうとする人はRGBどれかを限界値にする人は少ないんじゃね? と思い、実装の優先度を下げています。現実装の計算値と理論値の差もそこまで大きくないはずだし、誤差なしの方に至ってはエサをケチらない人が多いし。