2014年6月27日金曜日

人狼知能エージェントの作成・その3 スタート編

2015/02/09変更
サーバのバージョンの変更に従って,一部ソースコードが変更されています.
古いバージョンをお使いの方はver0.1.15以上にアップデートしてください.

さて,今日は人狼知能Talkする編を書こうと思ったけど,
その前に「テスト用に,自分で繰り返し実行する方法が知りたい」という意見があったので,
先にそちらを書こうと思う.

ゲーム実行のためのメインクラス

AIWolfのゲームを実行するには,

  • AIWolfGame:ゲーム実行サーバ本体クラス
  • GameSetting:ゲームの設定クラス
  • GameServer:エージェントとゲームサーバとの通信用クラス
の三つのクラスと,エージェントクラスを利用する.
以下は実行サンプルのソースコードである.
ただし,このソースコードは,人狼知能エージェントの作成・その1-ver0.1.15対応にある BasePlayerをつかっている.ので,作成していない場合は先にこちらを参照して作成して欲しい.

package org.aiwolf.player.bin;

import java.io.File;
import java.io.IOException;

import java.util.HashMap;
import java.util.Map;

import org.aiwolf.client.base.smpl.SampleRoleAssignPlayer;
import org.aiwolf.common.data.Player;
import org.aiwolf.common.data.Role;
import org.aiwolf.common.data.Team;
import org.aiwolf.common.net.GameSetting;
import org.aiwolf.player.BasePlayer;
import org.aiwolf.server.AIWolfGame;
import org.aiwolf.server.GameData;
import org.aiwolf.server.net.DirectConnectServer;



/**
 * テスト用に人狼をスタートするためのMainクラス
 * @author tori
 *
 */
public class TestStarter {

 /**
  * 他のエージェントの数
  */
 static protected int PLAYER_NUM = 12;
 
 /**
  * @param args
  * @throws IOException 
  */
 public static void main(String[] args) throws IOException {
  

  Map playerMap = new HashMap();//・・・(1)
  //BasePlayerはVillagerに固定
  playerMap.put(new BasePlayer(), Role.VILLAGER);
  for(int i = 0; i < PLAYER_NUM-1; i++){
   //そのほかのエージェントは,SamplePlayerで役職の希望は無し.
   playerMap.put(new SampleRoleAssignPlayer(), null);
  }
  
  
  DirectConnectServer gameServer = new DirectConnectServer(playerMap);//・・・(2)
  GameSetting gameSetting = GameSetting.getDefaultGame(playerMap.size());//・・・(3)
  AIWolfGame game = new AIWolfGame(gameSetting, gameServer);//・・・(4)
  game.setLogFile(new File("./log/TestStarter.log"));//・・・(5)
  game.start();//・・・(6)
  Team winner = game.getWinner();//・・・(7)
  if(winner == Team.VILLAGER){
   System.out.println("Win!");
  }
  GameData gameData = game.getGameData();//・・・(8)

 }

}

ソースについて説明する.

メインクラスの説明

(1)役職の登録
まずエージェントクラスと当該エージェントを付けたい役職をMap型クラスに登録する.
新しいインスタンスを作成し,当該エージェントを付けたRoleをMapに登録していくだけである.
この時,各役職の人数制限を超えたエージェントが同じ役職に希望していた場合,その中のいずれかのエージェントが希望する役職になり, それ以外のエージェントは余った役職に割り当てられる.
また,役職を特に指定したくないエージェントはnullをsetすればよい.
この例では,自作のBasePlayerだけVillagerを指定し,それ以外はSampleRoleAssignPlayerとして,いずれも特に役職を指定していない.
(2)Connectorの作成
人狼サーバは,TCPIPを使ってサーバとエージェントを接続するが,テスト用環境ではTCPIPを使う必要性がない. そのような場合は,DirectConnectServerを使う.
ここでは,先ほどの希望役職を指定したMapを引数として,DirectConnectServerを作成している.
なお,すべてのエージェントにランダムに役職を与えて実行する場合は,
List<Agent> playerList = new ArrayList<Agent>();
//中略
DirectConnectServer gameServer = new DirectConnectServer(playerList);
のように,AgentのListを引数としてDirectConnectServerを作成すればよい.
(3)GameSettingの作成
GameSettingクラスは,さまざまなゲームの条件を決めるクラスである.
各役職に付けるエージェント数や,各自の投票結果を他のエージェントに知らせるか,などを決定するものである.
現状では,
GameSetting.getDefaultGameエージェント数);
で取得できるデフォルトのGameSettingを利用することが推奨されている.
これ以外のGameSettingを利用した場合の動作の保証はない.
(4)AIWolfGameの作成
ここでは,ゲーム実行サーバ本体の作成を行っている.
GameSettingとGameServerを指定して作成する.
(5)LogFileの設定
ゲームログを出力する場合,ここでログファイルを指定する.
ログを設定しない場合,ゲームログはコンソールにしか表示されない.
(6)ゲームの開始
game.start();
によって,ゲームが開始される.以降,ゲームが終了するまで自動で処理される.
(7)勝利チームの獲得
ゲーム終了後,どちらが勝ったのかを取得する.
勝利したかどうかに応じてエージェントを進化させたい場合などに利用することが可能.
単純に何回も実行して勝率を確認するためにも利用できる.
(8)全ゲームデータの取得
GameData gameData = game.getGameData();
で獲得できるGameDataは,このゲームで行われたすべての行動が記録されているデータクラスである.
このデータクラスを使って,ゲームの解析を行うことが可能.

以上で,起動メインクラスの説明は終了.
いくつかエージェントを作って,Roleを割り当て方を変えながらエージェントの実力をテストしてみればよいと思う.

0 件のコメント: