Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

人狼知能セミナー資料20160507

3,359 views

Published on

人狼知能エージェント作成方法

Published in: Software
  • Be the first to comment

人狼知能セミナー資料20160507

  1. 1. 人狼知能エージェント作成方法
  2. 2. 目次 • 自作Playerを用いた人狼の実行方法 – プロジェクト作成 – ビルド・パスの構成 – ゲームの実行 • 実際にPlayerを実装 – 占い師を実装
  3. 3. 新規プロジェクトの作成(1) ファイル>新規>Javaプロジェクト
  4. 4. 新規プロジェクトの作成(2) • 適当なプロジェクト名を入力して完了(ここで はInabaAgent)
  5. 5. ビルド・パスの構成 • プレイヤー作成に必要なjarファイルをビルド・ パスに追加 – “ http://www.aiwolf.org/ ”から「開発者向け情報>人 狼知能プラットフォーム>aiwolf-ver0.3.3」をダウン ロード – Zipの中身 • 5つの.jarファイル • 4つの.shファイル • 4つの.batファイル • 1つの.iniファイル – 開発に使用するのはaiwolf-client.jar , aiwolf- common.jar, aiwolf-server.jarの3つ
  6. 6. 開発に使うJarファイルの概要 • aiwolf-client – プレイヤーを作成する際に用いる • aiwolf-common – serverとclient両方で用いる • aiwolf-server – ゲームを実行する際に用いる
  7. 7. ちなみに他のファイルは • ゲームを実行するために使用 – StartServer • ゲームサーバーをGUIで起動させるツール – StartClient • サーバーに接続するためのクライアント (人狼知能)を 起動 – StartGUIClient • サーバーに接続するためのクライアントをGUIで起動さ せるツール – AutoStarter • 設定ファイル(.ini)の通りにゲームを実行させるツール
  8. 8. 新規フォルダーの作成(1) プロジェクトを右クリック>新規>フォルダー
  9. 9. 新規フォルダーの作成(2) • 適当なフォルダー名を入力して完了(ここでは lib)
  10. 10. 新規フォルダーの作成(3) • フォルダー内にclient, common, serverの3つ のjarファイルをドラッグ&ドロップ →これらのjarファイルをビルド・パスに追加
  11. 11. ビルド・パスの構成(1) プロジェクトを右クリック>ビルド・パス>ビル ド・パスの構成
  12. 12. ビルド・パスの構成(2) ライブラリー>Jar追加
  13. 13. ビルド・パスの構成(3) フォルダー内に入れた3つのjarファイルを選択 して「OK」
  14. 14. 自作プレイヤーでゲーム実行 1. AbstractRoleAssignPlayerを継承したクラスを 作成 2. ゲーム実行の準備 3. 各役職のPlayerを作成 4. RoleAssignPlayerに各役職のPlayerをセット
  15. 15. 自作プレイヤーでゲーム実行 1. AbstractRoleAssignPlayerを継承したクラスを 作成 2. ゲーム実行の準備 3. 各役職のPlayerを作成 4. RoleAssignPlayerで各役職のPlayerをセット まず実行できる環境を整える
  16. 16. 新規パッケージ作成(1) InabaAgent>srcを右クリック>新規>パッケー ジ
  17. 17. 新規パッケージ作成(2) • パッケージ名を入力して完了 – パッケージ名は自分のアドレスを逆から入力 • 例) myAgent@aiwolf.org → org.aiwolf.myAgent
  18. 18. 新規クラス作成(1) 作成したパッケージを右クリック>新規>クラス
  19. 19. 新規クラス作成(2) スーパークラス>参照から ”AbstractRoleAssignPlayer”を選択
  20. 20. 新規クラス作成(3) • 適当なクラス名を入力して完了(ここでは, InabaRoleAssignPlayer)
  21. 21. Jarファイル作成方法(1) プロジェクトを右クリック>エクスポート
  22. 22. Jarファイル作成方法(2) JAVA>JARファイル を選択して次へ
  23. 23. Jarファイル作成方法(3) • プロジェクト全てを選択 • エクスポート先をaiwolf-ver0.3.3を解凍した フォルダに設定 完了
  24. 24. 実行の構成 1つのサーバに複数のクライアント(人狼知能) プログラムを接続し,ゲームを実行 サンプ ル サンプ ル サンプ ル 自分 ・・・ サーバ
  25. 25. 設定ファイルの記述 • aiwolf-ver0.3.3フォルダ内のAutoStarter.iniを編集 • kaji1~kaji5から始まる行をコメントアウト – 先頭に#をつけるとコメントになる • 以下を末尾に追加 sample1,org.aiwolf.client.base.smpl.SampleRoleAssignPlayer sample2,org.aiwolf.client.base.smpl.SampleRoleAssignPlayer sample3,org.aiwolf.client.base.smpl.SampleRoleAssignPlayer sample4,org.aiwolf.client.base.smpl.SampleRoleAssignPlayer [適当な名前],[自分が作成したパッケージ名].[自分のクラス名 (例:InabaRoleAssignPlayer)] → サンプル4体と自分のエージェント1体でゲームを行う設定
  26. 26. ゲームの実行 • Windowsの場合 :AutoStarter.batをダブルクリック • Mac/Linuxの場合 : AutoStarter.shをダブルクリック
  27. 27. Playerの実装
  28. 28. 自作プレイヤーでゲーム実行 1. AbstractRoleAssignPlayerを継承したクラスを 作成 2. ゲーム実行の準備 3. 各役職のPlayerを作成 4. RoleAssignPlayerで各役職のPlayerをセット 例として占い師を作ってみましょう
  29. 29. 占い師用の新規クラスの作成 • RoleAssignPlayerの作成と同様に新規クラスを 作成(例えばInabaSeer) – スーパークラスはAbstractSeerを選択
  30. 30. RoleAssignPlayerを変更 • RoleAssignPlayerに次のコンストラクタを追加 (InabaRoleAssignPlayerの場合) – 役職として占い師を振り分けられた時に InabaSeerを呼び出す – 他の役職の場合はデフォルトでサンプルプレイ ヤーが呼び出される public InabaRoleAssignPlayer(){ setSeerPlayer(new InabaSeer()); }
  31. 31. ゲーム実行 • もう一度jarをエクスポートし,AutoStarterを 実行して動けばOK • InabaSeerはまだ実装すべきメソッドを実装し ていないから適当な行動をとる 実装すべきメソッドとは?
  32. 32. Playerインターフェース Playerインターフェース内のAbstract Method ゲームの各タイミングでサーバがプレイヤーの これらのメソッドを呼び出す • getName() • update(GameInfo gameinfo) • initialize(GameInfo gameinfo) • dayStart() • talk() • whisper() • vote() • attack() • divine() • guard() • finish()
  33. 33. ゲームの流れ initialize(GameInfo) vote() divine()(占い師のみ) attack()(人狼のみ) guard()(狩人のみ) update(GameInfo) whisper()(人狼のみ) talk() update(GameInfo) dayStart() update(GameInfo) finish() 会話終了 ゲーム終了 1日
  34. 34. 各メソッドの戻り値 • getName() • update(GameInfo gameinfo) • initialize(GameInfo gameinfo) • dayStart() • talk() • whisper() • vote() • attack() • divine() • guard() • finish() 全体,もしくは囁き で発話するメソッド 戻り値:String 対象プレイヤーを選択する メソッド 戻り値:Agent
  35. 35. Seerの実装 • Seer(InabaSeer)が継承したAbstractSeer – 占い師に必要ないメソッド(attack, guard等)を事 前に消してある – 毎朝,サーバから送られた占い結果をListに格納 する 等の簡単な実装がしてある • 実装する必要のあるメソッド – talk(), divine(), vote()の3つ
  36. 36. 実際に実装してみましょう
  37. 37. 実装の流れ 1. voteの実装(1) – ランダムに投票 2. divineの実装 – ランダムに占う 3. voteの実装(2) – 占い結果を考慮して投票 4. talkの実装 – カミングアウト,占い結果の報告
  38. 38. 実装の流れ 1. voteの実装(1) – ランダムに投票 2. divineの実装 – ランダムに占う 3. voteの実装(2) – 占い結果を考慮して投票 4. talkの実装 – カミングアウト,占い結果の報告
  39. 39. vote()の実装 実装例 – 生きているプレイヤーから自分を除いてランダム に投票してみる
  40. 40. @Override public Agent vote(){ //投票対象の候補者リスト List<Agent> voteCandidates = new ArrayList<Agent>(); //生きているプレイヤーを候補者リストに加える voteCandidates.addAll(getLatestDayGameInfo().getAliveAgentList()); //自分自身と白判定のプレイヤーは候補から外す voteCandidates.remove(getMe()); return randomSelect(voteCandidates); } vote()の実装 ↑getLatestDayGameInfo()はAbstractPlayer内のメソッド で,最新のGameInfoを返す GameInfoはサーバから送られてくるゲーム内情報.ロ グや占い結果等の全ての情報はここから取得する 続く
  41. 41. vote()の実装 /** * 引数のAgentのリストからランダムにAgentを選択する * @param agentList * @return */ private Agent randomSelect(List<Agent> agentList){ int num = new Random().nextInt(agentList.size()); return agentList.get(num); }
  42. 42. vote()の実装(全体像) @Override public Agent vote(){ //投票対象の候補者リスト List<Agent> voteCandidates = new ArrayList<Agent>(); //生きているプレイヤーを候補者リストに加える voteCandidates.addAll(getLatestDayGameInfo().getAliveAgentList()); //自分自身と白判定のプレイヤーは候補から外す voteCandidates.remove(getMe()); return randomSelect(voteCandidates); } /** * 引数のAgentのリストからランダムにAgentを選択する * @param agentList * @return */ private Agent randomSelect(List<Agent> agentList){ int num = new Random().nextInt(agentList.size()); return agentList.get(num); } } 次はdivine()を実装してみよう
  43. 43. 実装の流れ 1. voteの実装(1) – ランダムに投票 2. divineの実装 – ランダムに占う 3. voteの実装(2) – 占い結果を考慮して投票 4. talkの実装 – カミングアウト,占い結果の報告
  44. 44. divine()の実装 実装例 – 自分を除いて,まだ占っていないプレイヤーからラ ンダムに選択 ※既に死んでいるプレイヤーから選択しないように注意
  45. 45. divine()の実装 @Override public Agent divine() { //占い対象の候補者リスト List<Agent> divineCandidates = new ArrayList<Agent>(); //生きているプレイヤーを候補者リストに加える divineCandidates.addAll(getLatestDayGameInfo().getAliveAgentList()); //自分自身と既に占ったことのあるプレイヤーは候補から外す divineCandidates.remove(getMe()); for(Judge judge: getMyJudgeList()){ if(divineCandidates.contains(judge.getTarget())){ divineCandidates.remove(judge.getTarget()); } } 続く
  46. 46. divine()の実装 if(divineCandidates.size() > 0){ //候補者リストからランダムに選択 return randomSelect(divineCandidates); }else{ //候補者がいない場合は自分を占い return getMe(); } }
  47. 47. divine()の実装(全体像) @Override public Agent divine() { //占い対象の候補者リスト List<Agent> divineCandidates = new ArrayList<Agent>(); //生きているプレイヤーを候補者リストに加える divineCandidates.addAll(getLatestDayGameInfo().getAliveAgentList()); //自分自身と既に占ったことのあるプレイヤーは候補から外す divineCandidates.remove(getMe()); for(Judge judge: getMyJudgeList()){ if(divineCandidates.contains(judge.getTarget())){ divineCandidates.remove(judge.getTarget()); } } if(divineCandidates.size() > 0){ //候補者リストからランダムに選択 return randomSelect(divineCandidates); }else{ //候補者がいない場合は自分を占い return getMe(); } } 次は占い結果を投票に反映させてみましょう
  48. 48. 実装の流れ 1. voteの実装(1) – ランダムに投票 2. divineの実装 – ランダムに占う 3. voteの実装(2) – 占い結果を考慮して投票 4. talkの実装 – カミングアウト,占い結果の報告
  49. 49. vote()の実装2 実装例 – 占いで人狼を見つけていたらその中からランダム – 人狼を見つけていなければ,自分と白判定が出たプレイ ヤー以外からランダム – まだ占っていない場合は,自分以外からランダム ※既に死んでいるプレイヤーから選択しないように注意
  50. 50. vote()の実装2 @Override public Agent vote() { List<Agent> whiteAgent = new ArrayList<Agent>(), //白判定だったプレイヤー blackAgent = new ArrayList<Agent>(); //黒判定だったプレイヤー //今まで占ったプレイヤーをwhiteAgentとblackAgentに分ける for(Judge judge: getMyJudgeList()){ if(getLatestDayGameInfo().getAliveAgentList().contains(judge.getTarget())){ switch (judge.getResult()) { case HUMAN: whiteAgent.add(judge.getTarget());] break; case WEREWOLF: blackAgent.add(judge.getTarget()); } } } 続く
  51. 51. vote()の実装2 if(blackAgent.size() > 0){ //blackAgentがいればその中から選択 return randomSelect(blackAgent); }else{ //投票対象の候補者リスト List<Agent> voteCandidates = new ArrayList<Agent>(); voteCandidates.addAll(getLatestDayGameInfo().getAliveAgentList()); //生きているプレイヤーを候補者リストに加える //自分自身と白判定のプレイヤーは候補から外す voteCandidates.remove(getMe()); voteCandidates.removeAll(whiteAgent); return randomSelect(voteCandidates); } }
  52. 52. vote()の実装2(全体像) @Override public Agent vote() { List<Agent> whiteAgent = new ArrayList<Agent>(), //白判定だったプレイヤー blackAgent = new ArrayList<Agent>(); //黒判定だったプレイヤー for(Judge judge: getMyJudgeList()){ if(getLatestDayGameInfo().getAliveAgentList().contains(judge.getTarget())){ switch (judge.getResult()) { case HUMAN: whiteAgent.add(judge.getTarget());] break; case WEREWOLF: blackAgent.add(judge.getTarget()); } } } if(blackAgent.size() > 0){ return randomSelect(blackAgent); }else{ //投票対象の候補者リスト List<Agent> voteCandidates = new ArrayList<Agent>(); voteCandidates.addAll(getLatestDayGameInfo().getAliveAgentList()); //生きているプレイヤーを候補者リストに加える //自分自身と白判定のプレイヤーは候補から外す voteCandidates.remove(getMe()); voteCandidates.removeAll(whiteAgent); return randomSelect(voteCandidates); } } 次は占い結果を発話してみましょう
  53. 53. 実装の流れ 1. voteの実装(1) – ランダムに投票 2. divineの実装 – ランダムに占う 3. voteの実装(2) – 占い結果を考慮して投票 4. talkの実装 – カミングアウト,占い結果の報告
  54. 54. talk, whisperでの発話 主な発話は org.aiwolf.client.lib.TemplateTalkFactory(全体用) org.aiwolf.client.lib.TemplateWhisperFactory(囁き用) で簡単に作成可能
  55. 55. TemplateTalkFactoryクラス • estimate(Agent, Role) – Agentの役職はRoleだと思う • comingout(Agent, Role) – AgentがRoleをカミングアウトする • divined(Agent, Species) – Agentを占った結果Speciesだった • inquested(Agent, Species) – Agentの霊能結果がSpeciesだった • guarded(Agent) – Agentを守った • vote(Agent) – Agentに投票する • (dis)agree(TalkType, day, id) – 対象の発話に同意(反対)する • skip() – まだ今日話したいことがある • over() – もう今日は話すことない
  56. 56. TemplateTalkFactoryの使用例 //占いの情報の取得 Judge judge = getLatestDayGameInfo().getDivineResult(); //発話の作成 String talk = TemplateTalkFactory.divined(judge.getTarget(), judge.getResult()); 今日の占い結果を報告する発話を生成
  57. 57. talk()の実装 実装例 – 占いで人狼を見つけたらカミングアウト – カミングアウトした後は占い結果を報告する – 話すことが無ければ”Over” (プレイヤーが全員Overを返せば会話のターンが終了)
  58. 58. talk()の実装 boolean isComingOut = false; //既に役職のカミングアウトをしているか //報告済みのJudgeを格納 List<Judge> myToldJudgeList = new ArrayList<Judge>(); @Override public String talk() { //占いで人狼を見つけたらカミングアウトする if(!isComingOut){ for(Judge judge: getMyJudgeList()){ if(judge.getResult() == Species.WEREWOLF){ //占い結果が人狼の場合 String comingoutTalk = TemplateTalkFactory.comingout(getMe(), getMyRole()); isComingOut = true; return comingoutTalk; } } } 続く
  59. 59. talk()の実装 //カミングアウトした後は,まだ言っていない占い結果を順次報告 else{ for(Judge judge: getMyJudgeList()){ if(!myToldJudgeList.contains(judge)){ //まだ報告していないJudgeの場合 String resultTalk = TemplateTalkFactory.divined(judge.getTarget(), judge.getResult()); myToldJudgeList.add(judge); return resultTalk; } } } //話すことが無ければ会話終了 return Talk.OVER; }
  60. 60. talk()の実装(全体像) boolean isComingOut = false; //既に役職のカミングアウトをしているか //報告済みのJudgeを格納 List<Judge> myToldJudgeList = new ArrayList<Judge>(); @Override public String talk() { //占いで人狼を見つけたらカミングアウトする if(!isComingOut){ for(Judge judge: getMyJudgeList()){ if(judge.getResult() == Species.WEREWOLF){ //占い結果が人狼の場合 String comingoutTalk = TemplateTalkFactory.comingout(getMe(), getMyRole()); isComingOut = true; return comingoutTalk; } } } //カミングアウトした後は,まだ言っていない占い結果を順次報告 else{ for(Judge judge: getMyJudgeList()){ if(!myToldJudgeList.contains(judge)){ //まだ報告していないJudgeの場合 String resultTalk = TemplateTalkFactory.divined(judge.getTarget(), judge.getResult()); myToldJudgeList.add(judge); return resultTalk; } } } //話すことが無ければ会話終了 return Talk.OVER; } 次は他の人の発話を読み込んでみましょう
  61. 61. ログの読み込み ログは GameInfo.getTalkList()でList<Talk>型として取得 Talkクラス内のメソッドは4つ – getAgent():発話したAgentを取得 – getContent():発話内容(String)を取得 – getDay():発話日(int)を取得 – getIdx():その日の何番目の発話か(int)を取得
  62. 62. ログの読み込み Talk.getContent()で得られるStringの中身は “DIVINED Agent[04] HUMAN” のように人狼言語で記載 →Utteranceクラスでパース //Utteranceクラスのコンストラクタの引数に発話内容のStringを入れ ると自動的にパースされる Utterance utterance = new Utterance(talk.getContent());
  63. 63. Utteranceクラスの使い方 戻り値 メソッド名と説明 String getText() 発話内容をそのまま返す Topic getTopic() 発話のTopicを返す(COMINGOUTやDIVINED等) Agent getTarget() 発話内の目的語となるプレイヤーを返す(例えば”DIVINED Agent[01] HUMAN” → Agent[01]) Role getRole() 発話の目的語となる役職を返す(例えば”COMINGOUT Agent[02] SEER” → SEER) Species getResult() 占い(霊能)の結果を返す(例えば”INQUESTED Agent[03] WEREWOLF” → WEREWOLF) TalkType getTalkType() TopicがAGREE,DISAGREEの時,対象発話のTalkType(全体ログor囁き)を返す int getTalkDay() TopicがAGREE,DISAGREEの時,対象発話の発話日を返す int getTalkID() TopicがAGREE,DISAGREEの時,対象発話の発話IDを返す
  64. 64. @Override public void update(GameInfo gameInfo) { super.update(gameInfo); //今日のログを取得 List<Talk> talkList = gameInfo.getTalkList(); for(int i = 0; i < talkList.size(); i++){ Talk talk = talkList.get(i); //発話をパース Utterance utterance = new Utterance(talk.getContent()); //発話のトピックごとに処理 switch (utterance.getTopic()) { case COMINGOUT: //カミングアウトの発話の処理 break; case DIVINED: // 占い結果の発話の処理 break; } } } ログの読み込み このままだと,update()が呼ばれる度に,その日のログを全部読み込む → 一度読み込んだTalkは読まないように変更してみる
  65. 65. ログの読み込み2 //その日のログの何番目まで読み込んだか int readTalkNum = 0; @Override public void dayStart(){ super.dayStart(); readTalkNum = 0; } オレンジ部分:追加 赤部分:修正
  66. 66. @Override public void update(GameInfo gameInfo) { super.update(gameInfo); //今日のログを取得 List<Talk> talkList = gameInfo.getTalkList(); for(int i = readTalkNum; i < talkList.size(); i++){ Talk talk = talkList.get(i); //発話をパース Utterance utterance = new Utterance(talk.getContent()); //発話のトピックごとに処理 switch (utterance.getTopic()) { case COMINGOUT: //カミングアウトの発話の処理 break; case DIVINED: // 占い結果の発話の処理 break; } readTalkNum++; } } オレンジ部分:追加 赤部分:修正 ログの読み込み2
  67. 67. ログの読み込み2(全体像) //その日のログの何番目まで読み込んだか int readTalkNum = 0; @Override public void dayStart(){ super.dayStart(); readTalkNum = 0; } @Override public void update(GameInfo gameInfo) { super.update(gameInfo); //今日のログを取得 List<Talk> talkList = gameInfo.getTalkList(); for(int i = readTalkNum; i < talkList.size(); i++){ Talk talk = talkList.get(i); //発話をパース Utterance utterance = new Utterance(talk.getContent()); //発話のトピックごとに処理 switch (utterance.getTopic()) { case COMINGOUT: //カミングアウトの発話の処理 break; case DIVINED: // 占い結果の発話の処理 break; } readTalkNum++; } } オレンジ部分:追加 赤部分:修正 ←自分以外に占い師COしているプレイヤーを 敵リストに追加してみましょう
  68. 68. //偽占い師COしているプレイヤーのリスト List<Agent> fakeSeerCOAgent = new ArrayList<Agent>(); @Override public void update(GameInfo gameInfo) { super.update(gameInfo); //今日のログを取得 List<Talk> talkList = gameInfo.getTalkList(); for(int i = readTalkNum; i < talkList.size(); i++){ Talk talk = talkList.get(i); //発話をパース Utterance utterance = new Utterance(talk.getContent()); //発話のトピックごとに処理 switch (utterance.getTopic()) { case COMINGOUT: //自分以外で占い師COしているプレイヤーの場合 if(utterance.getRole() == Role.SEER && !talk.getAgent().equals(getMe())){ fakeSeerCOAgent.add(utterance.getTarget()); } break; case DIVINED: // 占い結果の発話の処理 break; } readTalkNum++; } } オレンジ部分:追加 赤部分:修正 ログの読み込み3(全体像)
  69. 69. 補足
  70. 70. Playerの各メソッドの説明 • initialize(GameInfo) – ゲーム開始時に一度だけ 呼ばれる – サーバから送られてくる GameInfoを取得 • update(GameInfo) – 各行動の前に呼ばれる – サーバから送られてくる GameInfoを取得 • dayStart() – 日の初めに呼ばれる • finish() – ゲームが終了した時に呼 ばれる
  71. 71. Playerの各メソッドの説明 • vote() – 投票する相手を選択する • attack() – 襲撃する相手を選択する – 人狼のみ呼ばれる • divine() – 占いする相手を選択する – 占い師のみ呼ばれる • guard() – 護衛する相手を選択する – 狩人のみ呼ばれる 1日の終わりに呼ばれるメソッド Agentを返す必要あり
  72. 72. Playerの各メソッドの説明 • talk() – 全体に対して発話する – 全員呼ばれるメソッド • whisper() – 人狼だけに対して発話す る – 人狼のプレイヤーだけが 使用するメソッド 発話のメソッド Stringを返す必要あり
  73. 73. GameInfoの説明 戻り値 メソッド名と説明 int getDay() 日にちを返す Role getRole() 自分の役職を返す Agent getAgent() 自分(Agent型)を返す List<Agent> getAgentList() 全プレイヤーのリストを返す Species getMediumResult() 霊能結果を返す(霊能者のみ) Species getDivineResult() 占い結果を返す(占い師のみ) Agent getExecutedAgent() 処刑されたプレイヤーを返す Agent getAttackedAgent() 襲撃されたプレイヤーを返す List<Vote> getVoteList() 処刑の際の投票リストを返す List<Vote> getAttackVoteList() 襲撃の際の人狼による投票のリストを返す(人狼のみ) List<Talk> getTalkList() 会話のログを返す List<Talk> getWhisperList() 囁きのログを返す(人狼のみ) List<Agent> getAliveAgentList() 生きているプレイヤーのリストを返す Map<Agent, Status> getStatusMap() 各プレイヤーの生死の状態を返す Map<Agent, Role> getRoleMap() 各プレイヤーの役職を返す.ゲーム中は自分の分かる役職の み(村人なら自分だけ,人狼なら仲間の人狼も) ゲーム終了時は全員の役職が分かる.
  74. 74. 付録:GUIによるゲームの実行
  75. 75. GUIによるゲームの実行 • サーバの起動 – Windowsの場合 : StartServer.batをダブルクリック – Mac/Linuxの場合 : StartSerber.shをダブルクリック
  76. 76. サーバの設定 • Num of playersを5に設定 • Connectをクリックしてサーバを起動
  77. 77. クライアントの接続 (1/3) • クライアント接続用プログラム – Windowsの場合 :StartGuiClient.batを起動 – Mac/Linuxの場合 : StartGuiClient.shを起動
  78. 78. クライアントの接続 (2/3) • 先ほど作成したjarとaiwolf-client.jarをJarFiles 欄にドラッグアンドドロップ
  79. 79. クライアントの接続 (3/3) • Jarファイル,接続するプレイヤークラスを選択 • Connect Agentを選択 • Role欄で役職をリクエストすることもできる
  80. 80. ゲームの実行 • 自分のエージェント1体と SampleRoleAssignPlayerを4体Connect • Server StarterでStart Gameをクリック 5体のエージェントが接続されて いるのを確認(ServerStarter)
  81. 81. 実行結果 • 実行結果が右側の欄に表示される この例では村人側(Villager)の勝利

×