インタラクティブ・ゲーム制作 <プログラミングコース> 第10回 AI設計入門 (最終課題アナウンス)
先週は本当にごめんなさい ご覧の有様です 私が身体を張って皆さんに伝えたいのは次の2つ カルシウムは大事 焦るとあんまりいいことない
授業の再リスケジュール 海外出張キャンセル Kinectを来週に ラスト2回前は、 AIにも使えそうな ところを中心に 最終回で対決 海外でこの足はね… なので当初の予定通り Kinectを来週に ラスト2回前は、 AIにも使えそうな ところを中心に 最終回で対決 AI設計入門 Kinect体験 Boostと数学 オセロAI対決
今日の内容 AIの作り方を考えていく コーディングよりも考え方メイン 雑魚AIを試しに作ってみる
今回のプロジェクトの変更点 決着が付くようになっている 盤面の状況そのものを表すデータを BoardInfoクラスに分離 それに伴いいくつか関数追加 先々週ライブコーディングした内容の反映 盤面の状況そのものを表すデータを BoardInfoクラスに分離 AI実装を見越しての変更
まずは考え方から AI設計入門
AI(人工知能) 本当はゲームの思考ルーチン程度を 人工知能呼ばわりすると怒られる 確率によって適当な選択をするもの 選択肢に対するリスクやリターンを考えて、 選択をするもの
そもそも選択肢とは トランプや将棋のような思考AI アクションゲームなどの場合 手番単位で進行していくので分かりやすい 完全情報ゲームに分類される もっと言うと二人零和有限確定完全情報ゲーム アクションゲームなどの場合 フレーム単位での選択肢はキー操作 だがキー操作単位で行動制御すると不審な挙動に 戦術・戦略レベルでの状態によって管理
まずは選択肢を列挙しよう これをしないと打てないところに 打とうとするクソAIになってしまう まずは実装 幸い、前回の時点でBoard::isPuttable()という関数は作ったので、これを利用したい まずは実装
まずは初級編 今の状態だけで判断する
選択肢が列挙できたので… とりあえず最初の選択肢を選ぶ 適当に選ぶ 端っこが取れそうなら取りたい 思考放棄型その1 思考放棄型その2 だが、何となく人間味は出る そして超級に通じる方法だったりする 端っこが取れそうなら取りたい 多少強くなる、かもしれない
乱数の使い方 srand()で種を初期化 rand()が0~RAND_MAXの値を返す もっといい乱数が必要な場合 その時点での時刻を使うのが一般的 srand((unsigned int)time(NULL)); rand()が0~RAND_MAXの値を返す 実数にキャストして0.0~1.0の値にする もしくは%演算子で好みの範囲の値にする ただし、バラツキが出るようになるので注意 もっといい乱数が必要な場合 メルセンヌ・ツイスター法などを利用
中級~上級といったところ 先読みして判断する
実際に置いたらどうなるか 考えて手を決める 一番たくさんひっくり返せる手 目先の欲を追う型 次の自分の番で選択肢が一番多くなる手 オセロのセオリーにのっとる型 特に2.では「相手の手を推測する」というロジックが必要になるので、 これをどうしようか?
ミニマックス法 (ネガマックス法とも) 取り得る選択肢に評価点を付けて、 自分に有利、相手に不利になるような 選択肢を選ぶ 評価基準は、個数か、置ける場所数か、 あるいはその複合かで好きに選ぶ これなら数手先まで深読みが可能
超級 賢くはないが、腕尽くで
モンテカルロ法 乱数でシミュレーションを進める総称 オセロの場合 ある手を打つ その後勝負が付くまでお互いランダムに打つ これを数百回~数千回繰り返し、手ごとに 勝率を出す 一番勝率の高い手を採用する
最終回にむけて ルール確認
ルール(1) 来週月曜に対決用プロジェクトを公開 AIBaseクラスを継承し、 自分のアルゴリズムを実装 それ以外のファイルには手を加えては いけない getHand()で渡されてくる情報以外は 参照禁止 1手の計算に使える時間は30秒まで 私のMBAでの経過時間基準
ルール(2) 難易度は4段階用意 提出期限は7/23(火)23:59まで 自分に合った難易度で挑戦してね! Sチャレンジができるのは最高難易度 漏れなくライブで実況します 提出期限は7/23(火)23:59まで 組み込みチェックなどが必要なので、 それ以降は受け付けません
To be continued…