69
人狼知能エージェント作成方法 東京大学工学系研究科 システム創成学専攻 大橋・鳥海研究室 梶原健吾

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

Embed Size (px)

DESCRIPTION

How to make AIWolf agent

Citation preview

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

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

東京大学工学系研究科 システム創成学専攻

大橋・鳥海研究室

梶原健吾

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

目次

• 自作Playerを用いた人狼の実行方法

–ビルド・パスの構成,実行の構成

• 実際にPlayerを実装

–占い師を実装

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

新規プロジェクトの作成

ファイル>新規>Javaプロジェクト

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

新規プロジェクトの作成

• 適当なプロジェクト名を入力して完了(ここではMyAgent)

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

ビルド・パスの構成

• プレイヤー作成に必要なjarファイルをビルド・パスに追加

– http://www.aiwolf.org/から「資料>人狼知能サーバ>aiwolf-ver0.1.13」をダウンロード

–中身は3つのjarファイル

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

Jarファイルの概要

• aiwolf-client

–プレイヤーを作成する際に用いる

• aiwolf-common

– serverとclient両方で用いる

• aiwolf-server

–ゲームを実行する際に用いる

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

新規フォルダーの作成

プロジェクトを右クリック>新規>フォルダー

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

新規フォルダーの作成

• 適当なフォルダー名を入力して完了

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

新規フォルダーの作成

• フォルダー内に3つのjarファイルをドラッグ&ドロップ

→これらのjarファイルをビルド・パスに追加

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

ビルド・パスの構成

プロジェクトを右クリック>ビルド・パス>ビルド・パスの構成

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

ビルド・パスの構成

ライブラリー>Jar追加

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

ビルド・パスの構成

フォルダー内に入れた3つのjarファイルを選択して「OK」

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

自作プレイヤーでゲーム実行

1. AbstractRoleAssignPlayerを継承したクラスを作成

2. 実行の構成を変更

3. 各役職のPlayerを作成

4. RoleAssignPlayerで各役職のPlayerをセット

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

自作プレイヤーでゲーム実行

1. AbstractRoleAssignPlayerを継承したクラスを作成

2. 実行の構成を変更

3. 各役職のPlayerを作成

4. RoleAssignPlayerで各役職のPlayerをセット

まず実行できる環境を整える

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

新規パッケージ作成

MyAgent>srcを右クリック>新規>パッケージ

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

新規パッケージ作成

• 適当なパッケージ名を入力して完了

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

新規クラス作成

作成したパッケージを右クリック>新規>クラス

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

新規クラス作成

スーパークラス>参照から

”AbstractRoleAssignPlayer”を選択

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

新規クラス作成

• 適当なクラス名を入力して完了

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

実行の構成

プロジェクトを右クリック>実行>実行の構成

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

実行の構成

• メイン・クラス>検索から

“RoleRequestStarter”を選択

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

実行の構成

引数>プログラムの引数に下記を入力

「-n 11 -c org.aiwolf.myAgent.MyRoleAssignPlayer SEER」

プレイヤー数 パッケージ名 クラス名 希望役職

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

実行の構成

10人のサンプルプレイヤーと自分のプレイヤーでゲームを行う状態(自分は占い師だと設定)

プレイヤー

プレイヤー

プレイヤー

自分・・・

サーバ

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

実行結果

• 適用→実行 を押すと実行結果が表示されてゲームが実行出来る状態に

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

Playerの実装

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

自作プレイヤーでゲーム実行

1. AbstractRoleAssignPlayerを継承したクラスを作成

2. 実行の構成を変更

3. 各役職のPlayerを作成

4. RoleAssignPlayerで各役職のPlayerをセット

例として占い師を作ってみよう

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

新規クラスの作成

• MyRoleAssignPlayerの作成と同様に新規クラスを作成

–スーパークラスはAbstractSeerPlayerを選択

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

MyRoleAssignPlayerを変更

• MyRoleAssignPlayerに次のようなコンストラクタを追加

–役職として占い師を振り分けられた時にMySeerPlayerを呼び出す

–他の役職の場合はデフォルトでサンプルプレイヤーが呼び出される

public MyRoleAssignPlayer(){setSeerPlayer(new MySeerPlayer());

}

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

ゲーム実行

• もう一度ゲームを実行→エラーが出ればOK

• MySeerPlayerはまだ実装すべきメソッドを実装していないからエラーが発生

実装すべきメソッドとは?

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

Playerインターフェース

Playerインターフェース内のAbstract Method

ゲームの各タイミングでサーバがプレイヤーのこれらのメソッドを呼び出す

• getName()• update(GameInfo gameinfo)• initialize(GameInfo gameinfo)• dayStart()• talk()• whisper()

• vote()• attack()• divine()• guard()• finish()

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

ゲームの流れinitialize(GameInfo)

vote()

divine()(占い師のみ)attack()(人狼のみ)guard()(狩人のみ)

update(GameInfo)

whisper()(人狼のみ)

talk()

update(GameInfo)

dayStart()

update(GameInfo)

finish()

会話終了

ゲーム終了

1日

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

Playerインターフェース

Playerインターフェース内のAbstract Method

上記6つのメソッドは適切な値を返さないとエラー発生

– 今は全部nullを返しているからエラー

• getName()• update(GameInfo gameinfo)• initialize(GameInfo gameinfo)• dayStart()• talk()• whisper()

• vote()• attack()• divine()• guard()• finish()全体,もしくは囁き

で発話するメソッド戻り値:String

対象プレイヤーを選択するメソッド戻り値:Agent

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

MySeerPlayerの実装

• MySeerPlayerが継承したAbstractSeerPlayer

–占い師に必要ないメソッド(attack, guard等)を事前に消してある

–毎朝,サーバから送られた占い結果をListに格納する等の簡単な実装がしてある

• talk, divine, voteを実装すればちゃんと動く

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

実際に実装してみましょう

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

戻り値を適切な値に変更

とりあえずエラーが出ないように占い師はtalk()でString型を,vote()とdivine()でAgent型を返せば良い

talk()で空白文字を返す

vote(),divine()で自分自身を返す

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

@Override

public Agent divine() {

return getMe();

}

@Override

public void finish() {

}

@Override

public String talk() {

return "";

}

@Override

public Agent vote() {

return getMe();

}

これで実行は可能に.次はvote()をちゃんと実装してみる

←getMe()はAbstractPlayer内のメソッドで,自分自身を返す

戻り値を適切な値に変更

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

vote()の実装

実装例

–生きているプレイヤーから自分を除いてランダムに投票してみる

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

@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はサーバから送られてくるゲーム内情報.ログや占い結果等の全ての情報はここから取得する

続く

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

vote()の実装

/**

* 引数のAgentのリストからランダムにAgentを選択する

* @param agentList

* @return

*/

private Agent randomSelect(List<Agent> agentList){

int num = new Random().nextInt(agentList.size());

return agentList.get(num);

}

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

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()を実装してみよう

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

divine()の実装

実装例

–自分を除いて,まだ占っていないプレイヤーからランダムに選択

※既に死んでいるプレイヤーから選択しないように注意

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

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());

}

}

続く

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

divine()の実装

if(divineCandidates.size() > 0){

//候補者リストからランダムに選択

return randomSelect(divineCandidates);

}else{

//候補者がいない場合は自分を占い

return getMe();

}

}

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

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();

}

}

次は占い結果を投票に反映させてみましょう

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

vote()の実装2

実装例– 占いで人狼を見つけていたらその中からランダム

– 人狼を見つけていなければ,自分と白判定が出たプレイヤー以外からランダム

– まだ占っていない場合は,自分以外からランダム

※既に死んでいるプレイヤーから選択しないように注意

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

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());

}

}

}続く

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

vote()の実装2if(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);

}

}

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

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);

}

}

次は占い結果を発話してみましょう

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

talk, whisperでの発話

主な発話は

org.aiwolf.client.lib.TemplateTalkFactory(全体用)

org.aiwolf.client.lib.TemplateWhisperFactory(囁き用)

で簡単に作成可能

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

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()

– もう今日は話すことない

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

TemplateTalkFactoryの使用例

//占いの情報の取得

Judge judge = getLatestDayGameInfo().getDivineResult();

//発話の作成

String talk = TemplateTalkFactory.divined(judge.getTarget(), judge.getResult());

今日の占い結果を報告する発話を生成

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

talk()の実装

実装例

–占いで人狼を見つけたらカミングアウト

– カミングアウトした後は占い結果を報告する

–話すことが無ければ”Over”(プレイヤーが全員Overを返せば会話のターンが終了)

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

talk()の実装

//既に役職のカミングアウトをしているか

boolean isComingOut = false;

@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;

}

}

} 続く

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

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;

}

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

talk()の実装(全体像)//既に役職のカミングアウトをしているかboolean isComingOut = false;

@Overridepublic 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;

}

次は他の人の発話を読み込んでみましょう

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

ログの読み込み

ログは GameInfo.getTalkList()でList<Talk>型として取得

Talkクラス内のメソッドは4つ– getAgent():発話したAgentを取得

– getContent():発話内容(String)を取得

– getDay():発話日(int)を取得

– getIdx():その日の何番目の発話か(int)を取得

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

ログの読み込み

Talk.getContent()で得られるStringの中身は

“DIVINED Agent[04] HUMAN”

のように人狼言語で記載

→Utteranceクラスでパース

//コンストラクタに発話内容のStringを代入すると自動的にパースされるUtterance utterance = new Utterance(talk.getContent());

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

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を返す

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

@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は読まないように変更してみる

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

ログの読み込み2

//その日のログの何番目まで読み込んだか

int readTalkNum = 0;

@Override

public void dayStart(){

super.dayStart();

readTalkNum = 0;

}

オレンジ部分:追加赤部分:修正

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

@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

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

ログの読み込み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しているプレイヤーを敵リストに追加してみましょう

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

//偽占い師COしているプレイヤーのリストList<Agent> fakeSeerCOAgent = new ArrayList<Agent>();

@Overridepublic 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(全体像)

Page 64: 人狼知能エージェント作成方法
Page 65: 人狼知能エージェント作成方法

補足

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

Playerの各メソッドの説明

• initialize(GameInfo)– ゲーム開始時に一度だけ呼ばれる

– サーバから送られてくるGameInfoを取得

• update(GameInfo)– 各行動の前に呼ばれる

– サーバから送られてくるGameInfoを取得

• dayStart()– 日の初めに呼ばれる

• finish()– ゲームが終了した時に呼ばれる

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

Playerの各メソッドの説明

• vote()– 投票する相手を選択する

• attack()– 襲撃する相手を選択する

– 人狼のみ呼ばれる

• divine()– 占いする相手を選択する

– 占い師のみ呼ばれる

• guard()– 護衛する相手を選択する

– 狩人のみ呼ばれる

1日の終わりに呼ばれるメソッド

Agentを返す必要あり

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

Playerの各メソッドの説明

• talk()– 全体に対して発話する

– 全員呼ばれるメソッド

• whisper()– 人狼だけに対して発話する

– 人狼のプレイヤーだけが使用するメソッド

発話のメソッド

Stringを返す必要あり

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

GameInfoの説明戻り値 メソッド名と説明

intgetDay()

日にちを返す

RolegetRole()

自分の役職を返す

AgentgetAgent()

自分(Agent型)を返す

List<Agent>getAgentList()

全プレイヤーのリストを返す

SpeciesgetMediumResult()

霊能結果を返す(霊能者のみ)

SpeciesgetDivineResult()

占い結果を返す(占い師のみ)

AgentgetExecutedAgent()

処刑されたプレイヤーを返す

AgentgetAttackedAgent()

襲撃されたプレイヤーを返す

List<Vote>getVoteList()

処刑の際の投票リストを返す

List<Vote>getAttackVoteList()

襲撃の際の人狼による投票のリストを返す(人狼のみ)

List<Talk>getTalkList()

会話のログを返す

List<Talk>getWhisperList()

囁きのログを返す(人狼のみ)

List<Agent>getHumanList()

人間のプレイヤーのリストを返す(ゲーム終了時のみ)

List<Agent>getWolfList()

人狼のプレイヤーのリストを返す(ゲーム終了時のみ)

List<Agent>getAliveAgentList()

生きているプレイヤーのリストを返す

Map<Agent, Status>getStatusMap()

各プレイヤーの生死の状態を返す

Map<Agent, Role>getRoleMap()

各プレイヤーの役職を返す(ゲーム終了時のみ)