AI対戦サーバープログラム作成のヒント

Author:[[久住 涼]]

#contents

*はじめに [#q6f389be]

何年もAI対戦を見てきて思ったことと、[[CEDEC2013AIChallengeプロジェクト]]に参戦して便利だと思ったこと、調べたことをまとめたTipsです。~
AI対戦のプログラム作成の役立ててやってください。~

*今までのサーバー―クライアント間通信の手法 [#t664e7e6]

過去のAI対戦では、サーバーとクライアントの情報のやりとりには、次のような手段が使われてきました。

-同じ実行ファイルにまとめる(09,10,12)
-実行時引数に情報を与える(11)

「同じ実行ファイルにまとめる」とは、AIプログラムもサーバプログラム内に入れてコンパイルする手法のことです。~
VC++やVisualStadioで言えば、同じプロジェクトファイル内にサーバプログラムとクライアントプログラムの両方を含めてコンパイルすることで、1つの実行ファイルとして出力、実行します。~

「同じ実行ファイルにまとめる」では、サーバプログラムとクライアントプログラムを別々の.exeファイルで作成します。~
データ通信は、サーバからクライアントへは実行時引数として渡し、クライアントからサーバへはプログラムの返り値を行動としてサーバプログラムに返す手法です。~

これら手法はそれぞれ、プログラムの作成が楽であったり、既知の技術だけで実装できるなどの利点がありますが、以下のような欠点もあります。

*既存手法の欠点 [#x66d9207]

この項では、上にあげた2つの手法の欠点を上げたいと思います。

**同じ実行ファイルにまとめる [#va8de0ca]
この手法では、今までこの問題に苦しめられてきました。~

-無限ループ(実行エラー)
-各自でクライアントをビルド、実行しなくてはならない

サーバとクライアントを同じ実行ファイル内に入れてしまうため、無限ループの検出や実行エラーへの対処はクライアント側に依存していました。~
そのために、苦汁を舐めた人もいました。~
また、AIプログラムを書き換えるたびに全体をコンパイルしなおさなければならず、これは大変な手間となります。~


**実行時引数に情報を与える [#v18a6535]
この手法の欠点には、次が考えられると思います。~

-毎ターンクライアントを実行する必要がある

つまり、各ターンの行動を毎回決めなければならず、数ターン分の行動をまとめて決められないということです。~
モンテカルロ法などのアルゴリズム(詳しくは調べてね)で得られた情報を捨てなければならないのは、クライアントにとって大きな損失です。

*提案したい通信方法 [#a60cdf74]
そこで、これらの欠点を解消する情報の伝達方法として、次を提案します。~

-プロセス間通信による、標準出入力を用いた通信

これは、サーバ(クライアント)の標準出力がクライアント(サーバ)への標準入力となる方法です。~

これには、プロセス間通信について触れる必要がありますが、一度使いこなせれば、非常に心強い武器となります。~
[[CEDEC2013AIChallengeプロジェクト]]や、[[ICPC2013]]でも使われていたものなので、汎用性は高いと思います。~
ここから、プロセス間通信による情報転送のやり方について説明します。

*プロセス間通信 [#c6995209]

ここからは、ある程度C言語を知っている前提で話を進めます。(実装言語はC(あるいはC++)と仮定します)~
また、AI対戦のサーバはwindows上で開発するでしょうから、windowsでの実装の話になります。(Win APIを使用します)~
LINUX系の場合はfork()やexec()などで簡単に代用できるしょうから、適宜調べて、置き換えながら読んでください。%%(余裕あればLINUX対応も執筆するかも)%%~

**記事一覧 [#z97fd676]

あまりにも膨大な記述量となるので、ページ分割しました。~
自分の防備録も兼ねてるので、難易度は低め、のつもりです。

-[[その1 プログラム内で別のプログラムを実行する>AI対戦サーバープログラム作成のヒント/子プロセスの作成]]
-[[その2 パイプを使ってみる>AI対戦サーバープログラム作成のヒント/パイプの生成]]
-[[その3 パイプを使って通信する>AI対戦サーバープログラム作成のヒント/プロセス間通信]]
-[[その4 複数回通信と強制終了>AI対戦サーバープログラム作成のヒント/強制終了]]
-[[その5 タイムアウトと入力検知>AI対戦サーバープログラム作成のヒント/タイムアウト]]

-おまけ AIuno~
これらのまとめと習作として、サーバークライアント方式で動作するCUIのunoを作成しました。
私のdropboxにまとめのフォルダと、フォルダを圧縮したzipがあるので、気になる方は自由にDLして遊んでみてください。~
(ただしサーバーはwindowsオンリーです)

--フォルダ~
https://www.dropbox.com/sh/qdkxvu1rh6o4um5/BSUuuP6HCY
--ZIPファイル~
https://dl.dropboxusercontent.com/u/93859435/AIuno.zip

バグ報告や感想などをコメントに残していただけるとためになります。~
ぜひぜひよろしくお願いします。m(_ _)m

-おまけ2 Sleep関数の使用をやめなさい!
-おまけ3 ファイル入出力でAIを登録する

>9月中に書けたらいいなぁとか思いつつ。~
この辺もAI対戦に実装すると当日の運営が楽になると思いますです。~
(なお、AIunoにも同様の実装を施しました)

-番外編 クライアントサンプルをどこまで書くか?

>パイプ通信でサーバからデータを受け取る関数くらいは作りましょう、という話。~
ついでにAI関数もどこまで作るのが妥当なのか垂れ流したい(願望

*参考元リンク集 [#rf0034a7]
この記事を書く上で参考にしたwebページの一覧です。~

**[[ひしだま's ホームページ:http://www.ne.jp/asahi/hishidama/home/index.html]] [#k2637ca7]
一番参考にしたページ。C言語以外でもさまざまなワンポイントメモを残している。~
この中で参考にしたのは以下。~

-[[CreateProcess:http://www.ne.jp/asahi/hishidama/home/tech/c/windows/CreateProcess.html]]
-[[CreatePipe:http://www.ne.jp/asahi/hishidama/home/tech/c/windows/CreatePipe.html]]

**[[MSDN:http://msdn.microsoft.com/ja-jp/]] [#t3d08658]
MicroSoft公式のリファレンスページ(と思っている)。~
API関数の詳細が知りたければまずこのページ。~
ただし階層構造が理解できないので、関数名で直引きするのが一番早い。~
この記事で使用している関数は大体以下の通り。~
抜けてる関数もあるかもしれませんが、それは各自で調べるか、誰か下に追加してください。~

-[[CreateProcess関数:http://msdn.microsoft.com/ja-jp/library/cc429066.aspx]]
-[[CreatePipe関数:http://msdn.microsoft.com/ja-jp/library/cc429801.aspx]]
-[[WriteFile関数:http://msdn.microsoft.com/ja-jp/library/cc429856.aspx]]
-[[ReadFile関数:http://msdn.microsoft.com/ja-jp/library/cc429679.aspx]]
-[[TerminateProcess関数:http://msdn.microsoft.com/ja-jp/library/cc429376.aspx]]
-[[PeekNamedPipe関数:http://msdn.microsoft.com/ja-jp/library/cc430074.aspx]]
-[[DuplicateHandle関数:http://msdn.microsoft.com/ja-jp/library/cc429766.aspx]]

**[[初心者のためのポイント学習C言語:http://www9.plala.or.jp/sgwr-t/index.html]] [#u76d026d]
APIではない標準ライブラリ関数の検索に役立つサイト。~
[[strtok関数:http://www9.plala.or.jp/sgwr-t/lib/strtok.html]]とかはじめて知りました。~
[[ライブラリ関数一覧:http://www9.plala.or.jp/sgwr-t/lib/libtop.html]]を眺めるだけでもためになります。~

**その他 [#q24ef6da]
ワンポイント的に見たサイトを列挙。~

-[[バッファの内容を強制的に出力(フラッシュ)する:http://www.c-lang.net/general13/index.html]]
-[[起動したアプリケーションを終了させる:http://akky.xrea.jp/mfc/appclose.html]]
-[[プロセスをキル:http://azumaya.s101.xrea.com/wiki/index.php?%B3%D0%BD%F1%2FWin32%20API%2F%A5%D7%A5%ED%A5%BB%A5%B9%A4%F2%A5%AD%A5%EB]]
-[[パイプ処理:http://d.hatena.ne.jp/nepo_n/20051111/p1]](PeekNamedPipe関数)

このTipsとは無関係だが、DXライブラリ関連や関数リファレンスなど~

-[[コンソールへの文字列出力:http://karetta.jp/book-node/game-programming/236114]](DXライブラリ)
-[[コンソールへの入出力:http://eternalwindows.jp/windevelop/console/console02.html]](WINAPI)
-[[時間の計測を行う:http://d.hatena.ne.jp/fuku_dw/20111219/1324289674]] 
おまけその2で書こうとしていた元。Sleepがどう動いているかなどがわかると思います。
-[[C言語関数辞典:http://www.c-tipsref.com]] 上記ライブラリ紹介サイトより登録されている関数の数が豊富


*コメント一覧 [#xcc18fd6]
- 参考リンク集という名の私的ブックマーク。&br;もう少しだけ増やすかも(DXlib使用中のコンソール表示とか) -- [[くずみ>久住 涼]] &new{2013-09-17 (火) 01:34:54};

#comment


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS