2014年11月5日水曜日

人狼知能作成tips 第2回 エージェントの作成

今回は,実際にエージェントを実装する.
(2015.03.31修正しました.aiwolf-ver0.1.16対応版)


役職に応じてエージェントを切り替えるプレイヤーの作成

 人狼サーバには役職別のエージェント作成に便利な抽象クラスが用意されている.
今回はそのAbstractRoleAssignPlayerを継承してエージェントを作っていく.

AbstractRoleAssignPlayerにはsetSeerPlayerやsetMediumPlayerなどのメソッドが用意されており,コンストラクタで各役職に対応したエージェントを指定してやれば,ゲーム開始時に決まった役職に応じて自動でエージェントを切り替えてくれる.

以下の例では,占い師のエージェントにMySeerPlayerを指定している.

public class RoleAssignPlayer extends AbstractRoleAssignPlayer {


public RoleAssignPlayer() {
this.setSeerPlayer(new MySeerPlayer());
}

@Override
public String getName() {
return null;
}

}
なお指定していない役職のエージェントに関しては,サンプルエージェントが自動的に指定される.


占い師エージェントの実装

では次に,実際にMySeerPlayerを実装して,占い師のエージェントを作ってみよう.
各役職に関しても便利な抽象クラスが用意されている.
ということで,占い師の抽象クラスであるAbstractSeerPlayerを継承して占い師を作ってみる. 

まず最初に,EclipseでJavaクラスの新規作成ウインドウの「スーパークラス」の欄に「org.aiwolf.client.base.player.AbstractSeerPlayer」を入力し, 適当な名前を付けて完了を押せば,以下の様なクラスが自動生成される.

public class SeerPlayer extends AbstractSeer {

@Override
public Agent divine() {
// TODO 自動生成されたメソッド・スタブ
return null;
}

@Override
public void finish() {
// TODO 自動生成されたメソッド・スタブ

}

@Override
public String talk() {
// TODO 自動生成されたメソッド・スタブ
return null;
}

@Override
public Agent vote() {
// TODO 自動生成されたメソッド・スタブ
return null;
}

}

あとは,各メソッドの中身を埋めればとりあえず動くものができる.
占い先を指定するdivineメソッドと投票先を指定するvoteメソッドは,
ランダムで自分以外を指定することにしてみる.
ソースコードは以下のとおり.

//現時点で生存しているエージェントのリストを取得
List<Agent> agentList = this.getLatestDayGameInfo().getAliveAgentList();

//リストから自分を除外する
agentList.remove(this.getMe());

//エージェントのリストをシャッフルする
Collections.shuffle(agentList);

//リストの先頭のエージェントを指定
Agent target = agentList.get(0);

発言内容を指定するtalkメソッドは第1回のものをそのまま使う.
finishメソッドはゲーム終了時に呼ばれるメソッドだが,今回は必要ないのでそのまま.
というわけで完成したものが以下.

package player;

import java.util.Collections;
import java.util.List;

import org.aiwolf.client.base.player.AbstractSeer;
import org.aiwolf.client.lib.TemplateTalkFactory;
import org.aiwolf.client.lib.Topic;
import org.aiwolf.client.lib.Utterance;
import org.aiwolf.common.data.Agent;
import org.aiwolf.common.data.Role;
import org.aiwolf.common.data.Talk;
import org.aiwolf.common.net.GameInfo;

public class MySeerPlayer extends AbstractSeer {

@Override
public Agent divine() {
//現時点で生存しているエージェントのリストを取得
List<Agent> agentList = this.getLatestDayGameInfo().getAliveAgentList();

//リストから自分を除外する
agentList.remove(this.getMe());

//エージェントのリストをシャッフルする
Collections.shuffle(agentList);

//リストの先頭のエージェントを指定
Agent target = agentList.get(0);

return target;
}

@Override
public void finish() {
// TODO 自動生成されたメソッド・スタブ

}

@Override
public String talk() {
GameInfo info = this.getLatestDayGameInfo();
List<Talk> talkList = info.getTalkList();

for(Talk t : talkList){
Utterance u = new Utterance(t.getContent());
if(u.getTopic() == Topic.COMINGOUT && u.getRole() == Role.SEER){
//対抗占い師CO
return TemplateTalkFactory.comingout(info.getAgent(), Role.SEER);
}
}

//占い師COがない場合はSKIP
return TemplateTalkFactory.skip();
}

@Override
public Agent vote() {
//現時点で生存しているエージェントのリストを取得
List<Agent> agentList = this.getLatestDayGameInfo().getAliveAgentList();

//リストから自分を除外する
agentList.remove(this.getMe());

//エージェントのリストをシャッフルする
Collections.shuffle(agentList);

//リストの先頭のエージェントを指定
Agent target = agentList.get(0);

return target;
}

}

次回は実際にエージェント同士で対戦させてみる.

0 件のコメント:

コメントを投稿