見出し画像

OFCソルバーの作り方

まず各ファンタジーの点数換算での価値を適当に決める
以下の関数を実装する

evaluate_13

13枚置かれた状態を受け取ってその点数を返す
ファンタジー成立であればその価値も足した値を返す

put_11

11枚置かれた状態とドローの3枚を受け取る
全ての置き方のevaluate_13の中で最大のものを返す

evaluate_11

11枚置かれた状態を受け取る
残りのカードから3枚引くことを繰り返し、put_11の平均値を返す

あとはevaluateとputを繰り返し実装していく

高速化

各段のハンド情報の持ち方

数字情報とスート情報のタプルで表す
スート情報はRainbowと各スーツ4つ
数字情報はカードの数字nをn番目の素数に変換してそれらの積で表す
積で持つことでカードを加えたり除いたりするのが早くなる(多分)

ハンド判定

evaluate_13で各段のハンドを毎回評価すると遅いので、あらかじめハンドのハッシュに対する強さと点数のマップを作っておく
ハッシュは上記の積の後ろにスーテッドかどうかのビットを加えるだけ
強さは75432rを1として1ずつ増やしていく
Wを含む場合、強さのソート済みリストを持たせる

盤面のキャッシュ

完全に同一と見なせる盤面の結果はキャッシュする
特に各段がRainbowの場合は同一盤面が多くなり効果が大きい

モンテカルロ法

3手目から計算する場合は全てのドローに対して計算が可能(多分3分くらい)
初期配置から計算する場合、全てのドローに対して計算するのは多分不可能なのでランダムに何通りかの場合について計算して確率的に評価値を求める


この記事が気に入ったらサポートをしてみませんか?