• 検索結果がありません。

SkipContentBuilder() : 様子を見る

ドキュメント内 人狼エージェント作成講座 (ページ 63-91)

YESNO

14. SkipContentBuilder() : 様子を見る

以下で定義される定数

Content.SKIP

が用意されている

SKIP = new Content(new SkipContentBuilder());

詳細は,

aiwolf-ver0.4.4.zip

1

つ前のリリース)内の

0.4.4

での発話生成の方法(修正版

2

.pdf

」を参照

発話生成の例

//占いの情報の取得

Judge judge = getLatestDayGameInfo().getDivineResult();

//発話の作成

ContentBuilder builder = new

DivinedResultContentBuilder(judge.getTarget(), judge.getResult();

String talk = new Content(builder).getText();

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

talk() の実装

1.

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

2.

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

talk() の実装

public String talk() {

// 占いで人狼を見つけたらカミングアウトする if (!isCO) {

if (!myDivinationQueue.isEmpty() &&

myDivinationQueue.peek().getResult() == Species.WEREWOLF) { isCO = true;

ContentBuilder builder = new ComingoutContentBuilder(me,

Role.SEER) return new Content(builder).getText();

} }

続く

待ち行列の先頭の要素を取り出さずに取得

talk() の実装

// カミングアウトした後は、まだ報告していない占い結果を順次報告 else {

if (!myDivinationQueue.isEmpty()) {

Judge divination = myDivinationQueue.poll();

ContentBuilder builder = new

DivinedResultContentBuilder(divination.getTarget(), divination.getResult());

return new Content(builder).getText();

} }

return Content.OVER.getText();

}

待ち行列の先頭の要素を取り出す

talk() の実装(全体像)

public String talk() {

// 占いで人狼を見つけたらカミングアウトする if (!isCO) {

if (!myDivinationQueue.isEmpty() && myDivinationQueue.peek().getResult() == Species.WEREWOLF) { isCO = true;

ContentBuilder builder = new ComingoutContentBuilder(me, Role.SEER) return new Content(builder).getText();

} }

// カミングアウトした後は、まだ報告していない占い結果を順次報告 else {

if (!myDivinationQueue.isEmpty()) {

Judge divination = myDivinationQueue.poll();

ContentBuilder builder = new DivinedResultContentBuilder(divination.getTarget(), divination.getResult());

return new Content(builder).getText();

} }

return Content.OVER.getText();

}

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

会話内容の取り込み

会話のリストは

GameInfo.getTalkList()

List<Talk>

として取得

• Talk

クラスのメソッド

– getAgent()

:発話した

Agent

を取得

– getText()

:発話内容(

String

)を取得

– getDay()

:発話日(

int

)を取得

– getIdx()

:その日の何番目の発話か(

int

)を取得

– getTurn()

:その日の何番目のターンの発話か

int

)を取得

会話内容の取り込み

Talk.getText()

で得られる文字列は人狼知能プロトコルに準拠

例:

“DIVINED Agent[04] HUMAN”

この文字列を

parse

するには,

Content

クラスのコンストラクタの 引数として与える

//Content

クラスのコンストラクタの引数に発話内容の

String

を入れると 自動的にパースされる

Content content = new Content(talk.getText());

Content クラスの使い方

戻り値 メソッド名 説明

String getText() 発話内容をそのまま返す

Operator getOperator() 発話内容の演算子を返す.発話が単文の場合はnull

Agent getSubject() 発話内容の主語を返す

Topic getTopic() 発話内容のトピックを返す(COMINGOUTDIVINED等)

Agent getTarget() 発話内容の目的語となるプレイヤーを返す(例えば”DIVINED Agent[01]

HUMAN” Agent[01]

Role getRole() 発話の目的語となる役職を返す(例えば”COMINGOUT Agent[02] SEER”

SEER

Species getResult() 占い(霊媒)の結果を返す(例えば”IDENTIFIED Agent[03] WEREWOLF”

WEREWOLF

TalkType getTalkType() TopicAGREE/DISAGREEの時,対象発話のタイプ(TALK/WHISPER)を返す

int getTalkDay() TopicAGREE/DISAGREEの時,対象発話の発話日を返す

int getTalkID() TopicAGREE/DISAGREEの時,対象発話の発話IDを返す List<Content> getContentList() 発話内容が複文・重文の場合,節のリストを返す

会話内容を取り込むように update() を修正(1)

/** GameInfo.talkList読み込みのヘッド */

int talkListHead; // dayStart()中で0に初期化しておくこと

public void update(GameInfo gameInfo) { currentGameInfo = gameInfo;

// GameInfo.talkListからカミングアウト・占い報告・霊媒報告を抽出

for (int i = talkListHead; i < currentGameInfo.getTalkList().size();

i++) { Talk talk = currentGameInfo.getTalkList().get(i);

Agent talker = talk.getAgent();

if (talker == me) { continue;

}

Content content = new Content(talk.getText()); // 発話をparse

続く

会話内容を取り込むように update() を修正(2)

switch (content.getTopic()) { case COMINGOUT:

// カミングアウト発話の処理 break;

case DIVINED:

// 占い結果報告発話の処理 break;

case IDENTIFIED:

// 霊媒結果報告発話の処理 break;

default:

break;

} }

talkListHead = currentGameInfo.getTalkList().size();

}

修正した update() の全体像

/** GameInfo.talkList読み込みのヘッド */

int talkListHead; // dayStart()中で0に初期化しておくこと public void update(GameInfo gameInfo) {

currentGameInfo = gameInfo;

// GameInfo.talkListからカミングアウト・占い報告・霊媒報告を抽出

for (int i = talkListHead; i < currentGameInfo.getTalkList().size(); i++) { Talk talk = currentGameInfo.getTalkList().get(i);

Agent talker = talk.getAgent();

if (talker == me) { continue;

}

Content content = new Content(talk.getText()); // 発話をparse switch (content.getTopic()) {

case COMINGOUT: // カミングアウト発話の処理 break;

case DIVINED: // 占い結果報告発話の処理 break;

case IDENTIFIED: // 霊媒結果報告発話の処理 break;

default:

break;

} }

talkListHead = currentGameInfo.getTalkList().size();

}

実際にカミングアウトの情報を 取り込んでみましょう

カミングアウト情報の取り込み例

/** カミングアウト状況 */

Map<Agent, Role> comingoutMap = new HashMap<>(); // initializeで初期化しておくこと public void update(GameInfo gameInfo) {

currentGameInfo = gameInfo;

// GameInfo.talkListからカミングアウト・占い報告・霊媒報告を抽出

for (int i = talkListHead; i < currentGameInfo.getTalkList().size(); i++) { Talk talk = currentGameInfo.getTalkList().get(i);

Agent talker = talk.getAgent();

if (talker == me) { continue;

}

Content content = new Content(talk.getText()); // 発話をparse switch (content.getTopic()) {

case COMINGOUT:

// カミングアウト情報の取り込み

comingoutMap.put(talker, content.getRole());

break;

case DIVINED: // 占い結果報告発話の処理 break;

case IDENTIFIED: // 霊媒結果報告発話の処理 break;

default:

break;

} }

talkListHead = currentGameInfo.getTalkList().size();

}

カミングアウト情報が取り込めたら

例えば,偽の占い師が現れたことがわかる

自分のカミングアウト前だったらどうする?

偽占い師は人狼か,それとも裏切り者か・・・

などについて,対応を考えてみましょう

補足

Player の各メソッドの説明

• initialize(GameInfo)

ゲーム開始時に一度だけ 呼ばれる

サーバから送られてくる

GameInfo

を取得

• update(GameInfo)

各行動の前に呼ばれる

サーバから送られてくる

GameInfo

を取得

• dayStart()

日の初めに呼ばれる

• finish()

ゲームが終了した時に呼 ばれる

Player の各メソッドの説明

• vote()

投票する相手を選択する

• attack()

襲撃する相手を選択する

人狼のみ呼ばれる

• divine()

占いする相手を選択する

占い師のみ呼ばれる

• guard()

護衛する相手を選択する

狩人のみ呼ばれる

1

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

Agent

を返す必要あり

Player の各メソッドの説明

• talk()

全体に対して発話する

全員呼ばれるメソッド

• whisper()

人狼だけに対して発話す

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

発話のメソッド

String

を返す必要あり

GameInfo

の説明

戻り値 メソッド名 説明

int getDay() 日にちを返す

Role getRole() 自分の役職を返す

List<Agent> getExistingRoles() このゲームに存在する役職のリストを返す

Agent getAgent() 自分(Agent型)を返す

List<Agent> getAgentList() 全プレイヤーのリストを返す

Species getMediumResult() 霊媒結果を返す(霊媒師のみ)

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

Agent getGuardedAgent() 前日護衛したプレイヤーを返す(狩人のみ)

List<Agent> getLastDeadAgentList() 前日死亡したプレイヤーのリストを返す(呪殺された妖狐を含む)

Agent getExecutedAgent() 前日追放されたプレイヤーを返す

Agent getLatestExecutedAgent() 当日追放が決まったプレイヤーを返す.決定前はnull

Agent getAttackedAgent() 襲撃の成否にかかわらず,襲撃したプレイヤーを返す(人狼のみ)

List<Vote> getVoteList() 前日の追放の際の投票リストを返す

List<Vote> getLatestVoteList() 追放再投票の場合,前投票のリストを返す

List<Vote> getAttackVoteList() 襲撃投票のリストを返す(人狼のみ)

List<Vote> getLatestAttackVoteList() 襲撃再投票の場合,前投票のリストを返す(人狼のみ)

List<Talk> getTalkList() 会話のリストを返す

List<Talk> getWhisperList() 囁きのリストを返す(人狼のみ)

List<Agent> getAliveAgentList() 生きているプレイヤーのリストを返す

Map<Agent, Status> getStatusMap() 各プレイヤーの生死の状態を返す

Map<Agent, Role> getRoleMap() 各プレイヤーの役職を返す.ゲーム中は自分の分かる役職のみ(村人な

ら自分だけ,人狼なら仲間の人狼も).ゲーム終了時は全員の役職.

付録: GUI によるゲームの実行

GUI によるゲームの実行

サーバの起動

– Windows

の場合

: StartServer.bat

をダブルクリック

– Mac/Linux

の場合

: StartSerber.sh

をダブルクリック

サーバの設定

• Num of players

5

に設定

• Connect

をクリックしてサーバを起動

クライアントの接続 (1/3)

クライアント接続用プログラム

– Windows

の場合

:StartGuiClient.bat

を起動

– Mac/Linux

の場合

: StartGuiClient.sh

を起動

クライアントの接続 (2/3)

先ほど作成した

jar

aiwolf-client.jar

JarFiles

欄にドラッグアンドドロップ

クライアントの接続 (3/3)

• Jar

ファイル,接続するプレイヤークラスを選択

• Connect Agent

を選択

• Role

欄で役職をリクエストすることもできる

ゲームの実行

自分のエージェント

1

体と

SampleRoleAssignPlayer

4

Connect

• Server Starter

Start Game

をクリック

5体のエージェントが接続されて いるのを確認(

ServerStarter

ドキュメント内 人狼エージェント作成講座 (ページ 63-91)

関連したドキュメント