アーキテクチャをスマートに。

株式会社ネオジニア代表。ITアーキテクトとしてのお仕事や考えていることなどをたまに綴っています。(記事の内容は個人の見解に基づくものであり、所属組織を代表するものではありません)

ネオ富豪の開催にあたって(5)プレイヤープログラムの制作〜大会終了後

ネオ爺の制作

プレイヤープログラムの着手にあたっては、当初から C++ で組んでAndroidアプリとしてパッケージングするつもりだったのでナポレオンアプリのプログラムの構造を大きく流用しました。
ただ、今回は WebSocket に対応しないといけないので、それを C++ でやれるか、ダメだったときの保険としてJava側をメインにして WebSocket の制御はそっちでやればいいかなと考えていました。libwebsockets のビルドでそれなりに苦労しましたが、なんとかなったので C++ メインですんなり決定しました。

ナポレオンと同様、人工知能的アプローチで作りたいと思っていたので、アルゴリズムの試行錯誤に手こずり、めちゃめちゃ時間がかかりました。

最終的にできたのが以下のようなアルゴリズム

  1. 手札のカードの組み合わせから、出すことが出来る手をすべて列挙する。
  2. 場に出たカードをもとに、流せる手と流せない手に分類する。
  3. 流せる手を出してから流せない手を出す、という組み合わせで手順の木構造を展開し、勝利確定手順がないかを幅優先探索で求める。
  4. 勝利確定手順が見つからない場合は、一手出した後の残りの手札を評価し、もっともよい評価値になる手を出す。
  • 手札の評価は、そのカードより強いカードが何枚残っているか等を得点式で計算しているため、得点が低いほうがよい手札となる。
  • ジョーカーや必ず流せる手は評価値がマイナスとなるようにし、無駄遣いすると評価値が上がるようにした。
  • また、局面の進行状況に合わせて、カード1枚の評価基準値が変動するようにし、序盤は温存型で、終盤では挑戦的になるようパラメータ調整したが、
  • 本戦では様々な対戦相手と状況に対応し切れておらず、まだまだ改善の余地があると思う。

また、単に C++ じゃなくて新しい C++11 の習得も目標に含めてやりました。久しぶりに C++ 触ったけど、C++11でかなり良くなったと思います。ラムダ式型推論、foreach風のfor文がいい感じです。新しいライブラリでは unique_ptr が活用できました。

それから「ネオ爺」というプログラムの命名は、まぁあんまり深い意味はありません。いくつか案があったんですが、ゴロがいいのと酔拳の達人みたいで強そうだったのでこれに決めました。セリフによるキャラクター付けもやりやすかったし。

再現観戦

これは大会終了後に実装した機能ですが、対戦ログをもとにゲーム画面を再現するような機能です。
駆け込みでマスタサーバにログ出力の機能を追加してあったので、なんとかなるだろうと高をくくってたんですが、いざ大会が終わってログを集めてみると恐ろしく粒度が荒く、そのままではとてもじゃないけど再現観戦なんてできませんでした。考えが甘かったです。
しかたないので、ログアナライザを作って、実際にマスタサーバで対戦をシミュレートする機能を実装し、ログデータを補正しながら対戦結果データを再収集しました。
これが結構大変でした。マスタサーバのログ出力機能を適当に終わらせてしまったのがマズかったです。反省。

所感

もちろん通常業務をこなしながら、時間を作りながら少しずつこの企画を進めないといけないので、とにかく大変でした。
再現観戦機能を完成し、大会結果のページをアップしたときは、大きな達成感とやりきった感がありました。
やはり、ナポレオンアプリのプログラム資産と設計経験があったのが非常に大きな礎となりました。プログラム開発の段階では全体のクラス構成のイメージが最初から既に頭の中にありました。

11月中旬から準備を始め、1月25日の大会当日まで、さらにそのあとの大会結果のページの制作まで全部を含め、今回の企画の遂行に要した時間は合計250時間でした。SI業界の工数換算でいくと2人月ちょいですね。(笑