ということで、大富豪をAI(DLR利用)に対応
以下、簡単な説明。ufcpp.netの方にちゃんとした説明書かなきゃなぁ。こんな実装でいいんでしょうか。LL派な人からご意見もらえるとうれしい。
大富豪のルール的な話
基本的にニコッとタウンの大富豪ルールに準拠。
ローカルルール
- 同ランク複数枚あり
- 同色連番あり
- スイート縛り(2人目が初手と同じスイートを出したら、以後そのスイートしか出せない)あり
- 連番縛り(階段: 初手が同スイート連番で、2人目がさらに初手と連番になるようにカードを出したら、以後、ぴったり連番でないと出せない)あり
- 革命はJoker含めて4枚以上場に出たら起こる
実のところ未完成。以下の欠陥あり。
- 2やJokerで普通に上がれる
- 大富豪⇔大貧民、富豪⇔貧民間のカード交換実装してない
- 勝負が終わっても順位表とか表示されない
WPFアプリ
- 手動でカードを選んでプレイも可能
- でも、全員分のカードが見えている状態なので、手動でプレイしても面白くない
- 「auto」ボタンを押すと、AIが自動でカードを選ぶ
スクリプトの仕様
ちなみに、実装上、DLRを呼び出してるのはソースファイル中の DaifugouWpf\ScripAi.cs
スクリプトへの入力
スクリプトが実行される直前に、C#側で以下の変数を設定します
- hand: 今現在の手札一覧(Card型の配列)
- table: 今、場に出ているカード一覧(Card型の配列)
- rank: 今、場に出ているカードのランク(int、複数枚出ている場合はそのうち最大のランク)
- suit: (スイート縛り状態の場合のみ)どのスイートで縛られているか(enum Suit)
- mode: 今現在のモード(enum Mode: ビットフラグ。詳細は後述)
- revolution: 革命状態かどうか(bool)
- history: 過去1ターンの履歴(History型。詳細は口述)
あと、System.Randomクラスのインスタンスが rand という名前の変数に格納してあります。
mode は以下のような enum。
[Flags] public enum Mode { // 初手。なんでも出せる状態。 First = 0, // 通常。 Normal = 1, // 同ランク複数枚。 Multiple = 2, // 同スイート連番。 Sequence = 4, // スイート縛り。 // 初手の人と2番目の人が同じスイートのカードを出したら次からそのスイートしか出せなくなるやつ。 SuitBound = 8, // いわゆる「階段」状態。 // 初手 { 3, 4 } の直後に { 5, 6 } が出たら次は { 7, 8 } しか出せないってやつ。 SequenceBound = 16, }
Histroy型は、他のプレイヤーからも見える情報(VisibleInfo型)のリスト。
VisibleInfo は以下のような感じ。
/// <summary> /// プレイヤーの状態のうち、他のプレイヤーからも見える情報。 /// </summary> public class VisibleInfo { /// <summary> /// プレイヤーの手札の残り枚数。 /// </summary> public int Count { set; get; } /// <summary> /// プレイヤーが前回出したカード。 /// </summary> public IEnumerable<Card> Previous { set; get; } }
デフォルトAI
AIスクリプトを登録しなかった場合、以下のような挙動をするデフォルトAIが使われます。
- 出せる範囲で一番ランクが低いカードを出す
- 同ランク複数枚、連番にも対応
- ただ、未実装なので、連番縛り(階段)状態にされると対処できない
- Jokerも惜しみなく使う
- Jokerを含めた同ランク複数枚、連番も出してくる
- 出せるのにあえてパスしたりしない
- 初手は一番ランクの低いカードを全部出す(3が3枚あるなら、それを3枚とも出す)
- 連番は出さない
ちなみに、実装はソースファイル中の Daifugou\SampleAI.cs