SlideShare a Scribd company logo
1 of 149
Download to read offline
人狼知能
プログラミング演習
第一講目
電気通信大学 篠田孝祐
講義スケジュール
内容 詳細
第01講目 人狼知能とは.人狼知能エージェントプログラムの準備
第02講目 エージェントゲームサーバ・ソースコードリーディング
第03講目 アルゴリズムを考える!開発する!
第04講目 人狼知能エージェントの基本的な実装を学ぶ
第05講目 高度な知能をもつエージェントを実装するには!!
今回の内容
• 演習課題である,人狼知能とはなんなのかを簡
単に紹介
• 人狼知能エージェントプログラム作成の準備
• 環境の設定
• とにかく,人狼知能サーバを動かしてみる
恐ろしい夜がやってきました…
この村には、人間の姿に化けられる人食いオオカミが潜んでいる
…
人狼とは、人間と同じ姿をしており、昼間には区別が継がず、夜に
なる村人たちを一人ずつ襲っていく…
村人たちは、疑心暗鬼になりながら、話し合いによって人狼と思わ
れる人物を一人ずつ処刑してくことにした…
人狼ゲーム (Are You a Werewolf?)
目的:村人の中に紛れ込んだ人狼を見つけだす
昼: 参加者は議論によって、人狼と疑わしい村人を処刑する
夜:人狼は村人を一人襲う
村人には役職がある
 占い: 夜に任意のプレイヤがどの陣営か知れる
 狩人: 夜に人狼が襲いそうなプレイヤを守る
 狂人: 陣営は人間側だが、勝利条件は人狼側と同じ、人狼側からは役割は
わからない。
コンピュータvs人間の歴史
• 1997年チェス
• DeepBlueがチェスチャンピオンに勝利
• 2013年将棋
• コンピュータがプロ棋士に勝利
• 2050年サッカー
• ロボットによるチームが
ワールドカップ優勝チームに勝利(予
定)
完全ゲーム vs. 不完全ゲーム
• 完全情報ゲーム
• お互いの情報が完全に与えられているゲーム
• 将棋,囲碁,チェスなど
• すでにコンピュータが人間を上回るものが多い
• 不完全情報ゲーム
• ゲーム情報が完全には与えられていないゲーム
• 推論の対象が多岐にわたる
• 定型的な研究の場は少ない
人狼ゲームとは
• 村人のなかに隠れた人狼を会話を中心にさがす、
コミュニケーションゲーム
• 昼:会話をヒントにして人狼を追放
• 夜:役職の能力
• ゲームとしての情報学的特徴
• 不完全情報環境
• 情報の確かさ(エントロピー)の操作
• 情報の非対称性
• 他者の情報の確かさの推測
• 信頼の獲得
• 他者のもつ情報に基づく、自分のもつ情報の信頼性の構
築
実際に人狼をプレイしてみよう
• 人狼のゲームの進めかた
• ゲームマスタ: ゲームを進行する係
• プレイヤ:
• 村人サイド: 村人、占い師、狩人 など
• 人狼サイド: 人狼、狂人 など
※ http://jinrodou.com/whats-jinro/ より引用
占
狼
村 村
村
GM
一緒にプレイできる友達がいない人は
Youtube か ニコ動で動画をみてください
Java 言語での人狼知能エージェン
トのプログラムをする前に
プログラミング環境を整えよう
• プログラムを始める前に以下の作業を行います
1. Eclipse をインストールして使える状態にする
2. 人狼知能エージェントライブラリのダウンロード
3. Eclipse でエージェントを実装する準備
• プロジェクト作成
• ビルドパスの構成
• 新規フォルダの作成
• ビルドパスに追加
• 簡易プレイヤの作成
• ゲーム実行の確認
プログラム環境の準備(1)
• Eclipse 4 をインストール
• https://www.eclipse.org/downloads/
• 人狼知能ライブラリ
• DLサイト: http://aiwolf.org/server/
• aiwolf-client-0.X.X.jar
• プレイヤークライアント用ライブラリ
• aiwolf-common-0.X.X.jar
• Serverとclient両方で用いる共有ライブラリ
• aiwolf-server-0.X.X.jar
• ゲームサーバ用ライブラリ
• 本資料は 0.2.0 の時点で作成したものを 0.3.4 に合うよう
に修正したものである.未修正の部分があるかもしれな
いので,それには注意されたい
プログラム環境の準備(2)
Eclipseにプロジェクトを作成
① ファイル>新規>Javaプロジェクト
をクリック
② プロジェクト名入力
(例: “名前” + “エージェント”)
※ここでは MyAgent で説明する
②
①
プログラム環境の準備(3)
• 新規フォルダを作成する
• プロジェクトを右クリック>新規>フォルダー
• フォルダ名(エージェント名)を入力
• フォルダに準備(1)のjarファイルを追加
プログラム環境の準備(4)
ビルドパスにライブラリを追加
① 作成したプロジェクト>ビルドパス>ビルドパスの構成
をクリック
② “jar 追加”をクリック
③ 準備(1)の人狼知能ライブラリの jar を選択してOKする
① ② ③
とりあえず,人狼知能サーバを動
かしてみよう
サーバを動かすまでの4ステップ
1. AbstractRoleAssignPlayerを継承したクラスを作成
2. ゲーム実行のための構成を変更
3. 各役職のPlayerを作成
4. RoleAssignPlayerで各役職のPlayerをセット
新規パッケージを作成しよう
• MyAgent>srcを右クリック
• 新規>パッケージ
• パッケージ名を入力して完了
• 例えば: org.arwolf.myAgent
注意: 例の通りでは,一人で開発するだけなら
問題ありませんが,大会に出場するならユニー
クなものにしましょう
アドレス com.google.hoge など
新規クラスの作成を作成しよう
• 作成したパッケージを右クリック
• 新規>クラス
• スーパークラス>参照から
• ”AbstractRoleAssignPlayer”を選択
• クラス名を入力して完了
• 例: MyRoleAssignPlayer
※ こちらもパッケージ名と同じくユニークになるように
しましょう
ゲームを実行するには(1/2)
• プロジェクトを右クリック
• 実行>実行の構成
• メイン・クラス>検索から
• “RoleRequestStarter”を選択
ゲームを実行するには(2/2)
• 引数>プログラムの引数に下記を入力
「-n 11 -c org.aiwolf.myAgent.MyRoleAssignPlayer SEER」
プレイヤー数 パッケージ名 クラス名
希望役職
ゲームの実行してみる
• 適用→実行 をクリック
• 下部のペインに実行結果が表示される….はず
今日の課題
• 人狼知能サーバのソースコードを読んで、ソー
スコードを解説する
• ソースコード
https://github.com/aiwolf/AIWolfServer
• レポートの内容
• ソースコードに何が書かれているのか、理解して説
明できればOK
• 次回の講義で、いくつかのソースコードをその場で
説明してもらいます。
人狼知能
プログラミング演習
第二講目
電気通信大学 篠田孝祐
前回の内容
• 「人狼知能」とは何かを説明した
• 人狼知能エージェントプログラミングのための
準備として
• Javaプログラム環境をそろえる
• まずは,人狼知能サーバを動かしてみる
今回の内容
• エージェントとは,なんだろう?
• 人狼知能サーバのソースコードを読んでみよう
• 役職エージェントを作成してみる!
人狼知能をプログラムする前に
エージェントとは何だろう?
オブジェクトとは入れ物である
(C)Ghost in The Shell President Jomeson
身体・道具
情報・知識
+
からっぽの箱
=オブジェクト
(メソッド)
(変数)
なにかできる箱
犬 class
 データ: 名前
 データ: 年齢
 データ:所有物
 手続き:つかむ
 手続き:移動する(徒歩)
人間 class
 データ: 名前
 データ: 年齢
 データ:所有物
 手続き:つかむ
 手続き:移動する(徒歩)
Javaにおけるオブジェクトとは
• データと手続きをclassとしてまとめられる
オブジェクトは引き継げる(継承)
「人間」というクラスを引き継い
で職ごとにクラスを作成すること
で,「人間」に関する基本的な行
動は「人間」クラスで管理できる
人狼知能エージェントでも
• 役職XXXのクラスを作成するにはAbstractXXXを
継承して役職エージェントを作成
• 役職
• 村人 Villager
• 占い Seer
• 狩人 Bodygaurd
• 霊媒師 Medium
• 人狼 Werewolf
• 狂人 Possessed
• それを,サーバからエージェントに割り当てら
れたロールに合わせてメソッドを呼び出すため
の
クライアントライブラリの構成
• Playerインタフェース(AbstractRole)を継承
Player インタフェース
Villager Seer Bodygaurd Medium Werewolf Possessed
• getName()
• update(GameInfo
gameinfo)
• initialize(GameInfo
gameinfo)
• dayStart()
• talk()
• vote()
• finish()
各役職ごとのメソッドが定義されている
talk(), whisper()
全体,もしくは囁きで発話
するメソッド
戻り値:String
• guard()• divine() • attack()
• whisper()
vote(), divine(), guard(), attack()
対象プレイヤーを選択する
メソッド
戻り値:Agent
エージェントとは
• もともとは,オブジェクト指向と呼ばれていた概
念を発展させたもの
• オブジェクト指向とは
• 「オブジェクト」というモノが存在することを前提として,
その単位でオブジェクトの行為を管理する仕組み
• 例えば
• オブジェクト「人」
• 行為「歩く」
• 行為「つかむ」
• オブジェクト「犬」
• 行為「歩く」
• それ以前は
• 「人間が歩く」という関数
• 「人間がつかむ」という関数
を定義してきた
人間
犬
歩く歩く
つかむ
オブジェクト指向からエージェント
指向へ
• エージェント指向のキーワードは「能動性」
• オブジェクト指向はプリセットされた情報と手段を
もってふるまう
• それに対して,エージェント志向では能動的に
• 情報を集める
• 目的を設定する
• 行動を生成・最適化する
ことが期待されている
• でも,現状で可能なのは
• 最適化ぐらい
• 行動パラメータ
• マルチエージェントのタスク分割
• 行動生成とか結構難しい
なので,現状はオブジェクトと同義
疲れたから帰
りたい
どこまで散歩
するか?
手を離さない
プログラム実装の基本的な考え方
アイディア
アルゴリズム
コード
知識
表現型
統計的・
確率的
表現型
これを反復しながら実装していくことになります.
人狼知能サーバのソースコードを
読んでみよう
人狼知能サーバ: クラス構成
• エージェント情報
• 状態
• ロール
• 行動情報
• 結果
• ゲームターン管理
• データ管理
• gemeData
• 集計
• ゲームログ出力
ServerStarter
Port: int
PlayerNum: int
+main()
GameSetting
+getDefault(int): void
AIWolfGame
gameDataMap: Map<Integer, GameData>
+init():void
+start(): void
+setRandom(Random): void
GameServer
- agentList List<Agent>
+ getServerLogger(): void
+ waitForConnection(): void
Handler
AiWolfLogFormat
ゲーム開始クラス
ゲーム制御クラス
GaneData
-
+ getGaneinfoToSend(Agent)
ゲームデータ/1日単位通信用コネクタ
Talk Vote Judge Guard
Agent Status
ゲームの進行(ネットワーク経由の場合)
サーバ起動
インスタンス作成
GameSetting
GameServer
通信ソケット作成
エージェント接続完了
ゲーム開始
ゲーム終了
サーバ終了
ゲーム終了通知
エージェント接続待機
ソケット追加
ゲームデータ作成
データ送信待機
データロ
グ
エージェント起動
インスタンス作成
通信ソケット作成
接続要求
ゲーム開始待機
ターン終了
ゲーム終了
エージェント終了
ゲームデー受取
対話思考
Yes
No
No
Yes
Yes
Yes
No
No
AIWolfGameServer(1/4)
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import org.aiwolf.common.AIWolfRuntimeException;
import org.aiwolf.common.data.Agent;
import org.aiwolf.common.data.Guard;
import org.aiwolf.common.data.Judge;
import org.aiwolf.common.data.Role;
import org.aiwolf.common.data.Species;
import org.aiwolf.common.data.Status;
import org.aiwolf.common.data.Talk;
import org.aiwolf.common.data.Team;
import org.aiwolf.common.data.Vote;
import org.aiwolf.common.net.GameInfo;
import org.aiwolf.common.net.GameSetting;
import org.aiwolf.common.util.AiWolfLoggerFactory;
import org.aiwolf.common.util.Counter;
import org.aiwolf.server.net.GameServer;
import org.aiwolf.server.util.FileGameLogger;
import org.aiwolf.server.util.GameLogger;
※ 0.2.0 時点でのソースコード
AIWolfGameServer(2/4)
Random rand;
GameSetting gameSetting;
GameServer gameServer;
Map<Integer, GameData> gameDataMap;
GameData gameData;
boolean isShowConsoleLog = true;
File logFile;
GameLogger gameLogger;
Map<Agent, String> agentNameMap;
public AIWolfGame(GameSetting gameSeting, GameServer gameServer) {
rand = new Random();
this.gameSetting = gameSeting;
this.gameServer = gameServer;
gameLogger = AiWolfLoggerFactory.getSimpleLogger(this.getClass().getSimpleName());
}
public void setLogFile(File logFile) throws IOException {
gameLogger = new FileGameLogger(logFile);
}
public void setGameLogger(GameLogger gameLogger){
this.gameLogger = gameLogger;
}
<中略>
メソッド変数の宣言
• Random: 乱数生成器クラス: ただしJava の乱数は脆弱
• 乱数のインスタンスは可能な限り1つにする
• Map<K, V>: あるkeyでvalueを保持するクラス
• File: ファイルを扱うためのクラス
public クラス名(引数): コンストラクタ
オブジェクトが new されたときに呼び出される
部分
返値 メソッド名(引数) throw hoge
例外処理を行う: IOEcveption は入出力に関する例
外処理
AIWolfGameServer(3/4)
protected void init(){
gameDataMap = new TreeMap<Integer, GameData>();
gameData = new GameData(gameSetting);
agentNameMap = new HashMap<Agent, String>();
gameServer.setGameData(gameData);
List<Agent> agentList = gameServer.getConnectedAgentList();
if(agentList.size() != gameSetting.getPlayerNum()){
throw new IllegalPlayerNumException("Player num is “+gameSetting.getPlayerNum() +" but connected agent is "+agentList.size());
}
Collections.shuffle(agentList, rand);
Map<Role, List<Agent>> requestRoleMap = new HashMap<Role, List<Agent>>();
for(Role role:Role.values()){
requestRoleMap.put(role, new ArrayList<Agent>());
}
List<Agent> noRequestAgentList = new ArrayList<Agent>();
for(Agent agent:agentList){
Role requestedRole = gameServer.requestRequestRole(agent);
if(requestedRole != null){
if(requestRoleMap.get(requestedRole).size() < gameSetting.getRoleNum(requestedRole)){
requestRoleMap.get(requestedRole).add(agent);
} else {
noRequestAgentList.add(agent)
}
メンバ変数の初期化
エージェントリストのシャッフル
プライベート変数の宣言
for(型 変数名: イテレータ)
拡張for文(for-each文)
AIWolfGameServer(4/4)
} else {
noRequestAgentList.add(agent)
}
}
for(Role role:Role.values()){
List<Agent> requestedAgentList = requestRoleMap.get(role);
for(int i = 0; i < gameSetting.getRoleNum(role); i++){
if(requestedAgentList.isEmpty()){
gameData.addAgent(noRequestAgentList.remove(0), Status.ALIVE, role);
} else {
gameData.addAgent(requestedAgentList.remove(0), Status.ALIVE, role);
}
}
}
gameDataMap.put(gameData.getDay(), gameData);
gameServer.setGameData(gameData);
gameServer.setGameSetting(gameSetting);
for(Agent agent:agentList){
gameServer.init(agent);
agentNameMap.put(agent, gameServer.requestName(agent));
}
}
※ 補足資料: Java言語に関する資料も参照
ソースコードリーディングの勧め
• コードリーディングとは
1. プログラムのソースコードを読む
2. 何をしているプログラムか理解する
3. プログラムの全体構造を把握する
4. そこにあるアルゴリズムを知る
• プログラマのすべてが書かれている
• そこにはアイディアがある
• アルゴリズムが書かれている
• 研究のコア、実現方法も隠れている
• ソースコードは公開されている
• オープンソースソフトウェア
• (ライセンスにもよるけど)自由に改変できる
• (ライセンスにもよるけど)自由に再配布できる
• 絵を模写するように、文章を写本するように、プログラムも真似
て読めるようすることが重要!!
• 人狼知能サーバのプログラムは,サーバークライアント型のプロ
グラムを実装する上でのノウハウが詰め込まれていて最適!
役職ごとのエージェントの実装
作成した役職の登録
• MyRoleAssignPlayerクラスのコンストラクタに役職
をセットするメソッドの追加
• 役職として占い師を振り分けられた時にMySeerPlayerを
呼び出す
• 他の役職の場合はデフォルトでサンプルプレイヤーが呼
び出される
• その他のロールを加えるときには、以下を加える
• setXXXPlayer(new YYXXX())
public MyRoleAssignPlayer(){
setSeerPlayer(new MySeer());
}
エージェントの行動サイクル
initialize(GameInfo)
vote()
divine()(占い師のみ)
attack()(人狼のみ)
guard()(狩人のみ)
update(GameInfo)
whisper()(人狼のみ)
talk()
update(GameInfo)
dayStart()
update(GameInfo)
finish()
会話終了
ゲーム終了
1日
1回のゲーム開始時の処理
1回のゲーム終了時の処理
前の日の処理など
会話
行動
サンプル: 占師(Seer)の実装
• 例として MySeer クラスとして実装
• MySeerが継承したAbstractSeer
• 占い師に必要ないメソッド(attack, guard等)を事
前に消してある
• 毎朝,サーバから送られた占い結果をListに格納す
る 等の簡単な実装がしてある
• 実装する必要のあるメソッド
• talk(), divine(), vote()の3つ
メソッドの実装例
1. voteの実装(1)
• ランダムに投票
2. divineの実装
• ランダムに占う
3. talkの実装
• カミングアウト,占い結果の報告
投票先をとりあえずランダムに
実装例
• 生きているプレイヤーから自分を除いてランダムに
投票してみる
必要な情報とアルゴリズム
• 生きているエージェントのリスト
• 自分自身を取り除く
• ランダムに選択する
@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);
}
}
↑getLatestDayGameInfo()はAbstractPlayer内のメソッドで,
最新のGameInfoを返す
GameInfoはサーバから送られてくるゲーム内情報.ロ
グや占い結果等の全ての情報はここから取得する
占い先もとにかくランダムに
実装例
• 自分以外の生きているエージェントを占う
• そのとき、すでに占ったエージェントも除外す
る
必要な情報・アルゴリズム
• 生きているエージェントのリスト
• 自分自身を取り除く
• すでに占ったエージェントの情報
• ランダムに選択する
@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();
}
}
人狼知能での会話の実装
実装例
• 占いで人狼を見つけたらカミングアウト
• カミングアウトした後は占い結果を報告する
• 話すことが無ければ”Over”
(プレイヤーが全員Overを返せば会話のターンが終了)
必要な情報・アルゴリズム
• 占い結果の保存
• 人狼の有無の確認
• 会話スキームの実装
boolean isComingOut = false; //既に役職のカミングアウトをしているどうかのフラグ
List<Agent> myToldJudgeList = new List<Agent>();
@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; //話すことが無ければ会話終了
}
他のプレイヤの会話の確認する
ログは GameInfo.getTalkList()でList<Talk>型として取得
Talkクラス内のメソッドは4つ
• getAgent():発話したAgentを取得
• getContent():発話内容(String)を取得
• getDay():発話日(int)を取得
• getIdx():その日の何番目の発話か(int)を取得
Talk.getContent()で得られるStringの中身は
“DIVINED Agent[04] HUMAN”
のように人狼言語で記載
→Utteranceクラスでパース
//コンストラクタに発話内容のStringを代入すると自動的にパースされる
Utterance utterance = new Utterance(talk.getContent());
UtteranceクラスのAPIDoc
戻り値 メソッド名と説明
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を返す
GameInfo から Talk を読む!
@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は読まないように変更してみる
//その日のログの何番目まで読み込んだか
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しているプレイヤーのリスト
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++;
}
}
オレンジ部分:追
加
赤部分:修正
今回の課題
• 人狼知能クライアントライブラリのソースコー
ドを読み、解説する
• https://github.com/aiwolf/AIWolfClient
以下のjavaファイルすべて対象
• 以下の役職の基本ルーチンを考えてみる
• 村人
• 人狼
• 占い
• 狩人
人狼知能
プログラミング演習
第三講目
電気通信大学 篠田孝祐
前回の内容
• エージェントってどんなのかを説明した
• 人狼知能サーバのソースコードを読んでみた
• ソースコードには実装のノウハウが詰まっている
• 人狼知能サーバは,クライアントサーバ型の実装ノ
ウハウがコンパクトに詰まっている
• とりあえず,役職を一つつくってみたはず!
今回の内容
• 人狼知能エージェントの役職の行動を検討する
• 実装にむけて,デバック方法を習得する
役職エージェントのアルゴリズム
を考えて実装する
人狼ゲームのながれは?
人狼知能では、サーバが配役などGM役を行う
① 初日の昼
議論を行う
② 初日の夜のターン
活動できるのは占い師のみ
③ 昼のターン(議論)
④ 夜のターン(活動)
それぞれのターンでどのような活動を行うのかを考える.
まずは,最低限の行動ができるようにしたうえで,他のプレイヤとの
議論(協調・競争)について考えましょう
村人エージェントの基本行動
• 村人の「一番の」役割とは
• 会話を通じて情報を引き出す
• 会話を行うための「情報」をどうするか
• 他のプレイヤの「投票」から考える
• 誰に投票したのか、その理由はなぜなのかを推論
• 他のプレイヤの「会話」から考える
• 誰がCOしたのか、誰を疑っているのか(疑っていないのか)
• 発言に矛盾がないか
• 自ら発言することで、場の情報を増やす
• 誰が怪しいかをしっかり発言する
• 自分が村人であることをCOする
• 投票する相手をきめる
http://www.beginners-jinro.jp/
人狼エージェントの基本行動
• 能力をもつプレイヤを襲撃する
• 「村人」を装って会話をおこなう
• 投票は目立たなようにする
• 投票が監視されている場合、同じプレイヤ同士の投
票は目立つ
http://www.beginners-jinro.jp/
占いエージェントの基本行動
• 占う相手の順序をつける
• 人狼にありがちな行動をしたプレイヤ順
• 会話が矛盾しているプレイヤ
• やたらと誰かを怪しんでいるプレイヤ
• 特定のプレイヤをかばうような発言・投票をするプレイ
ヤ
• 自分が占い師であることを告白(CO)する
• 狼を発見したとき
• 自分が追放されそうになったとき
• 自分が「占い師」であることへの信頼を得る
• 「人狼」を見つけたのに、理由なくほかのプレイヤ
に投票するなどは、信頼を得られない
http://www.beginners-jinro.jp/
狩人エージェントの基本行動
• 預言者を守る
• 占いCOが一人の時には素直に守るのがよいでしょ
う
• 複数COしている場合には、狼の襲撃先の予想が必
要
• 狼の襲撃先を予想する
• 狼が誰を襲おうと思うのかを狼の立場から考える
• 投票候補にも襲撃候補にもなりにくい立ち位置
を確保する
• COはゲームの終盤以外には、基本的には行わ
ない
http://www.beginners-jinro.jp/
前回の課題を参考に検討する
• 役職の行動を考えたものを,どのようにしてお
アルゴリズムとして実装するにはどうしたらよ
いか(データとメソッド)を考えてみよう
• K村人の場合
• N人狼の場合
• Y占いの場合
• O狩人の場合
K村人の場合
• 会話に参加
• 他人に投票させるよう誘導
• 人狼を推理し誘導
• 役職を聞き,推理
• 投票
• 発話が極端なプレイヤーに投票
• 1,2を繰り返す
必要なデータ:
プレイヤリスト, 投票候補リスト,評価
用データ,協調プレイヤリスト?
アルゴリズム:
対象プレイヤを決定する評価式
他のプレイヤの協調度合評価式
必要なデータ:
役職回答リスト
アルゴリズム:
役職を問うメソッド
必要なデータ:
プレイヤの発言データリスト
アルゴリズム:
「発話が極端な」プレイヤを決定メソッド
必要なデータ:
カミングアウトデータ
アルゴリズム:
役職条件付き襲撃決定アルゴリズム
狩人占い両方COしている状態では占い師以
外?
人狼同士でのネゴシエーションアルゴリズム
N人狼の場合
• 最初の投票では、一人が人狼の誰かに投票をし
て、残りが人狼以外のプレイヤーに集中して投
票をする。役職がカミングアウトされたらその
役職を優先して襲う。狩人、占い師両方生存し
ているならば、占い師以外を襲うようにする。
3人以上ならば最初のターンに、一人が占い師
を名のり、人狼の一人を黒として告発する。
必要なデータ:
人狼発話データ、投票候補リスト
アルゴリズム:
発話分析メソッド
投票候補先決定アルゴリズム
投票先確定アルゴリズム
必要なデータ:
人狼プレイヤリスト
アルゴリズム:
CO決定アルゴリズム
黒出し候補決定アルゴリズム
Y占いの場合
• 一番怪しいと思われる人を投票し、占う
必要なデータ:
プレイヤリスト
アルゴリズム:
「怪しいプレイヤ」発見アルゴリズム
O狩人の場合
必要なデータ:
カミングアウトリスト
アルゴリズム:
ランダム選択アルゴリズム
自作エージェントを動かす
他のエージェントと戦う
他のエージェントと対戦させる
• デフォルトではSamplePlayerとの対戦のみ
• RoleRequestStarter を使用する場合
• -c 'プレイヤークラス' '設定したい役職‘
• -c ‘プレイヤークラス’ で,役職を指定しないで利
用
• -d デフォルトのプレイヤークラスを指定
他のプレイヤを追加する!
• kajiPlayer
• org.aiwolf.kajiClient.KajiRoleAssignPlayer
• inabaPlayer
• https://github.com/aiwolf/HumanPlayer/tree/master/lib
からjarファイルをダウンロード
• 過去の大会参加者のプログラム
• 2015年 第一回人狼知能大会
http://aiwolf.org/2016/02/29/cedec2015source/
• 2016年 GAT2016ミニ大会
http://aiwolf.org/2016/04/21/sourcecode_gat2016/
自分で作成したプレイヤの追加方法
• jar ファイルの作成
• プロジェクトを右クリック
• エクスポートを選択
• JAVA > JAR ファイルを選択
• 自分のプロジェクト全てを選択
• エクスポートするフォルダを設定
• JAR ファイルを追加
• 実行するプロジェクトに追加
ライブラリの追加と同じ
プログラムのデバッグ方法
デバッグとは
• プログラムがきちんと動作しているのかを確かめ
るための機能
• 安直な実装は プリントデバック
• System.out.println(hoge); をプログラム埋め込んで変数や
ルート分岐が意図どおり動いているのかを確認する方法
• Eclipseで利用可能なデバック機能
• ブレークポイントの設定
• 変数の値の参照
• ステップイン
• ステップリターン
• ステップオーバー など
• プログラムの文法的な間違いは Eclipse は指摘でき
るが,アルゴリズム実装のミスは確認するしかな
い.
なぜ、デバッカーを使うのか
(1/2)
1. public class SummationDbg {
2. public static void main(String[] args){
3. int[] a = {1,2,3};
4. int total = new Summation().addArray(a);
5. System.out.println("1+2+3="+total);
6. }
7. }
SummationDbg.java の作成
1. public class Summation {
2. int addArray(int[] boxes){
3. for(int i = 1; i < boxes.length; i++)
4. boxes[0] += boxes[i];
5. return boxes[0];
6. }
7. }
Summation.javaの作成
なぜ、デバッカーを使うのか
(2/2)
この回答は
(1) 7 (2) 12 (3) 13
1. public class SummationDbg {
2. public static void main(String[] args){
3. int[] a = {1,2,3};
4. int total = new Summation().addArray(a);
5. System.out.println("1+2+3="+total);
6. a[2] = 4;
7. total = new Summation().addArray(a);
8. System.out.println("1+2+4="+total);
9. }
10. } SummationDbg.java の追加
Breakpoint とは
• プログラムの実行を途中で止めてみる個所
• Java の break; とほぼ同じ意味
• デバックモードで実行すると、その時点での変
数や配列などのデータの状態を確認できる
• printf デバックで System.out.println(変数) と打って途
中経過を見ようとするのに似ている...
• でも、大きなプログラムだと、どこで出力したもの
か確認するのが大変
Breakpoint の設定(1)
• 設定する行にフォーカスを合わせて、[Run]-
[Toggle Breakout]を選択
Breakpoint の設定(2)
• 右クリックで [Toggle Breakpoint]を選択
デバッグモードの実行
• [Run]-[Debug As]から実行するか、下記のデバッ
グアイコンをクリック
1つ目のbreakpointの状況
配列 a の状況
プログラム実行の操作
2つ目のbreakpointの状況
配列 a の状況
デバックツールの活用
• 動き始めてしまったプログラムの修正は難しい
• なぜなら,アルゴリズムがプログラムという形で分
解されてしまっているため,実装の間違いなのかア
ルゴリズムの間違いなのかがわかりにくい.
• そこで,人狼知能の開発では
• 対戦用アプリケーションで動作を確認する
• http://aiwolf.org/server/
• 人狼知能解析ビューワ
• https://github.com/NONONOexe/AIWolfAnalysis
などを活用してください
今回の課題
1. 以下の役職の行動ルーチンを検討する
• 狂人
• 霊媒師
2. # 2の課題で検討したルーチンをアルゴリズ
ムに直して実装する。最低2役職
擬似コードもしくはプログラム(.javaファイル)を提出
プログラムは、可能な限り動くもの
強いエージェントを作成するためのルーチンの変更
は可
人狼知能
プログラミング演習
第四講目
電気通信大学 篠田孝祐
今回の内容
• 課題で実装したプログラムor疑似コードをみて,
アルゴリズムをより具体的(実装可能なレベ
ル)にする
• 他のエージェントプログラムも参考にしてみる
N狩人の場合(1/3)
package org1551018aiwolf;
import java.util.List;
public class MyBodyguard {
AdvanceGameInfo agi = new AdvanceGameInfo();
Agent planningVoteAgent; //今日投票しようと思っているプレイヤー
Agent declaredPlanningVoteAgent; //自分が最後に宣言した「投票しようと思っているプレイヤー」
int readTalkListNum; //会話をどこまで読んだか
@Override
public void dayStart() {
declaredPlanningVoteAgent = null;
planningVoteAgent = null;
setPlanningVoteAgent();
readTalkListNum =0;
}
@Override
public String talk() {
if(declaredPlanningVoteAgent != planningVoteAgent){
String string = TemplateTalkFactory.vote(planningVoteAgent);
declaredPlanningVoteAgent = planningVoteAgent;
return string;
}else{
return TemplateTalkFactory.over();
}
}
@Override
public Agent vote() {
return planningVoteAgent;
}
狩人の行動
占い師を優先的に守るようにする。霊媒師が名乗り出ても
優先的に守ることはないように変更した。3%の確率で村人
からランダムで守るようにした。
N狩人の場合(2/3)
@Override
public Agent guard() {
//占い師,もしくは霊能者COしているプレイヤーからランダムに選択(3%の確率で生存プレイヤーの中からランダムに
変更)
List<Agent> guardAgentCandidate = new ArrayList<Agent>();
List<Agent> aliveAgentList = getLatestDayGameInfo().getAliveAgentList();
aliveAgentList.remove(getMe());
for(Agent agent: aliveAgentList){
if(agi.getComingoutMap().containsKey(agent)){
List<Role> guardRoleList = Arrays.asList(Role.MEDIUM);
if(guardRoleList.contains(agi.getComingoutMap().get(agent))){
guardAgentCandidate.add(agent);
}
}
}
Agent guardAgent;
if(guardAgentCandidate.size() > 0 && Math.random() < 0.97){
Random rand = new Random();
guardAgent = guardAgentCandidate.get(rand.nextInt(guardAgentCandidate.size()));
}else{
Random rand = new Random();
guardAgent = aliveAgentList.get(rand.nextInt(aliveAgentList.size()));
}
return guardAgent;
}
public void setPlanningVoteAgent(){
<中略>
}
}
N狩人の場合(3/3)
@Override
public void update(GameInfo gameInfo) {
super.update(gameInfo);
List<Talk> talkList = gameInfo.getTalkList();
boolean existInspectResult = false;
/* talkListからCO,占い結果の抽出 */
for(int i = readTalkListNum; i < talkList.size(); i++){
Talk talk = talkList.get(i);
Utterance utterance = new Utterance(talk.getContent());
switch (utterance.getTopic()) {
case COMINGOUT: //カミングアウトの発話の場合
agi.getComingoutMap().put(talk.getAgent(), utterance.getRole());
break;
case DIVINED: //占い結果の発話の場合
//AGIのJudgeListに結果を加える
Agent seerAgent = talk.getAgent();
Agent inspectedAgent = utterance.getTarget();
Species inspectResult = utterance.getResult();
Judge judge = new Judge(getDay(), seerAgent, inspectedAgent, inspectResult);
agi.addInspectJudgeList(judge);
existInspectResult =true;
break;
}
}
readTalkListNum =talkList.size();
/* 新しい占い結果があれば投票先を変える.(新たに黒判定が出た,
または投票先のプレイヤーに白判定が出た場合)*/
if(existInspectResult){
setPlanningVoteAgent();
}
}
O村人の場合(1/3)
package org.aiwolf.roAgent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import org.aiwolf.client.base.player.AbstractVillager;
import org.aiwolf.client.base.smpl.AdvanceGameInfo;
import org.aiwolf.client.lib.*;
import org.aiwolf.common.*;
import org.aiwolf.common.data.*;
import org.aiwolf.common.net.*;
public class MyVillager extends AbstractVillager{
AdvanceGameInfo agi = new AdvanceGameInfo();
Agent planningVoteAgent; //今日投票しようと思っているプレイヤー
Agent declaredPlanningVoteAgent; //自分が最後に宣言した「投票しようと思っているプレイヤー」
int readTalkListNum; //会話をどこまで読んだか
@Override
public void dayStart() {
declaredPlanningVoteAgent = null;
planningVoteAgent = null;
setPlanningVoteAgent();
readTalkListNum =0;
}
投票アルゴリズム:
人狼だと占われたエージェント,いなければ,ランダム
発話:
その日に投票しようとしているエージェントを報告.
変化すれば報告.
O村人の場合(2/3)
@Override
public String talk() {
int comingoutDay = 0;
boolean isCameout = false;
//役職をカミングアウトする
if(!isCameout && getDay() >= comingoutDay){
String string = TemplateTalkFactory.comingout(getMe(), getMyRole());
isCameout = true;
return string;
}
if(declaredPlanningVoteAgent != planningVoteAgent){
String string = TemplateTalkFactory.vote(planningVoteAgent);
declaredPlanningVoteAgent = planningVoteAgent;
return string;
}else{
return TemplateTalkFactory.over();
}
}
@Override
public Agent vote() {
return planningVoteAgent;
}
@Override
public void finish() {
// TODO 自動生成されたメソッド・スタブ
}
O村人の場合(2/3)
public void setPlanningVoteAgent(){
/* 人狼だと占われたプレイヤーを指定している場合はそのまま */
if(planningVoteAgent != null){
for(Judge judge: agi.getInspectJudgeList()){
if(judge.getTarget().equals(planningVoteAgent)){
return;
}
}
}
/*
* 投票先を未設定,または人狼だと占われたプレイヤー以外を投票先にしている場合
* 人狼だと占われたプレイヤーがいれば,投票先をそのプレイヤーに設定
* いなければ生存プレイヤーからランダムに選択
*/
List<Agent> voteAgentCandidate = new ArrayList<Agent>();
List<Agent> aliveAgentList = getLatestDayGameInfo().getAliveAgentList();
aliveAgentList.remove(getMe());
for(Judge judge: agi.getInspectJudgeList()){
if(aliveAgentList.contains(judge.getTarget()) && judge.getResult() == Species.WEREWOLF){
voteAgentCandidate.add(judge.getTarget());
}
}
if(voteAgentCandidate.size() > 0){
Random rand = new Random();
planningVoteAgent = voteAgentCandidate.get(rand.nextInt(voteAgentCandidate.size()));
}else{
Random rand = new Random();
planningVoteAgent = aliveAgentList.get(rand.nextInt(aliveAgentList.size()));
}
return;
}
}
package com.gmail.tnamura;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.aiwolf.client.base.player.AbstractSeer;
import org.aiwolf.client.lib.TemplateTalkFactory;
import org.aiwolf.client.lib.Utterance;
import org.aiwolf.common.data.Agent;
import org.aiwolf.common.data.Judge;
import org.aiwolf.common.data.Role;
import org.aiwolf.common.data.Species;
import org.aiwolf.common.data.Talk;
import org.aiwolf.common.net.GameInfo;
public class NamuraSeer extends AbstractSeer {
boolean isComingOut = false;
int readTalkNum=0;
Agent Target;
Agent declaredTarget;
List<Agent> voteTarget = new ArrayList<Agent>(); //投票候補者リスト
List<Agent> nonvoteTarget = new ArrayList<Agent>(); //非投票候補者リスト
List<Judge> myToldJudgeList = new ArrayList<Judge>(); //自分が公表したうらない結果を入れる
List<Agent> fakeSeerCOAgent = new ArrayList<Agent>(); //自分以外で占い師COしているプレイヤー
@Override
public void dayStart(){
super.dayStart();
Target = setTarget();
declaredTarget = null;
readTalkNum=0;
}
N占いの場合(1/3)
N占いの場合(2/4)
@Override
public String talk() { //人狼を見つけるまでカミングアウトしない
if(isComingOut==false){ //COしてなければ
for(Judge judge:getMyJudgeList()){ //占い結果をすべて調べる
if(judge.getResult()==Species.WEREWOLF){
//自分の役職をCO
String comingoutTalk = TemplateTalkFactory.comingout(getMe(), getMyRole());
isComingOut = true;
return comingoutTalk;
}
}
} else { //COしたら
for(Judge judge:getMyJudgeList()){
if(!myToldJudgeList.contains(judge)){
String resulttalk = TemplateTalkFactory.divined(judge.getTarget(),judge.getResult());
myToldJudgeList.add(judge);
return resulttalk;
}
}
}
if(declaredTarget!=Target){
String string = TemplateTalkFactory.vote(Target);
declaredTarget = Target;
return string;
}
return Talk.OVER;
}
@Override
public Agent vote() {
return Target;
}
N占いの場合(3/3)
public Agent setTarget(){
if(fakeSeerCOAgent.size()>0){ //自分以外で占い師COしているプレイヤーがいれば,優先して投票
return randomSelect(fakeSeerCOAgent);
}
//占いで人狼を見つけていれば,その中からランダムで投票
//占いで人狼を見つけていなければ,自分と白以外のプレイヤーからランダムで投票
List<Agent> white = new ArrayList<Agent>(); //ブラックリスト
List<Agent> black = new ArrayList<Agent>(); //ホワイトリスト
for(Judge judge:getMyJudgeList()){ //占った結果黒だったプレイヤーをblackリストに入れる
if(judge.getResult()==Species.WEREWOLF){
black.add(judge.getTarget());
}else{ //占った結果白だったプレイヤーをwhiteリストに入れる
white.add(judge.getTarget());
}
}
if(black.size()>0){ //リストからランダムに投票
return randomSelect(black);
}else{
List<Agent> voteCandidates = new ArrayList<Agent>(); //投票対象候補者リスト
//生き残っているプレイヤーをリストに加える
voteCandidates.addAll(getLatestDayGameInfo().getAliveAgentList());
//自分と白確定プレイヤーを候補から外す
voteCandidates.remove(getMe());
voteCandidates.removeAll(white);
return randomSelect(voteCandidates); //リストからランダムに投票
}
}
S人狼の場合
• 行動方針: 追放される前に村人を全員食べる
• 会話を行う.(能力者を会話から素直に決定)
• 会話の内容に矛盾が生じないよう村人を装う.能力
持ちが重複した場合,注目を集めやすい
• 能力者を優先的に襲う.騎士はさらに優先的におそ
う必要がある
S人狼の場合の擬似コード?
初日
• 会話
• カミングアウト 村人
• 狼だと思う人を言う ランダム
投票
• 発言回数が多い人に投票
狼同士の会話
• ID が若い方が襲撃対象を宣言
• 襲撃対象をランダムに決定
• 二人が投票した以外の人物から
襲撃
• 投票対象を襲撃
初日以降
• 会話
エージェントの全体構造の再確認
• エージェントを実装するうえで,クライアント
であるエージェント全体の構造がどうなってい
るのかを見てみる
• 対象とするソースコードは
• Sample Agent
• KajiAgent
• それ以外にも,大会上位チームのソースコードが公
開されているので,エージェント設計の参考にして
ください.
• http://aiwolf.org/
• 2015年 第一回人狼知能大会
http://aiwolf.org/2016/02/29/cedec2015source/
• 2016年 GAT2016ミニ大会
http://aiwolf.org/2016/04/21/sourcecode_gat2016/
Sampleエージェントの
コードを読む
Smpl エージェントの実装….
• AdvancedGameInfo
• SampleRoleAssignPlayer
• SampleBodyguard
• SampleMedium
• SamplePossessed
• SampleSeer
• SampleVillager
• SampleWerewolf
SampleRole
AssignPlayer
Sample
Bodygau
rad
Sample
Medium
Sample
Possess
ed
Sample
Seer
Sample
Villager
Sample
Werewo
lf
Advanced
GameInfo
Advanced
GameInfo
Advanced
GameInfo
Advanced
GameInfo
Advanced
GameInfo
Advanced
GameInfo
Smplエージェントの基本戦略
• 投票アルゴリズム:
人狼だと占われたエージェントや偽CO相手,いなければ,ラン
ダム
• 発話:
役職あり: CO以降、その役職の内容を報告
Default: その日に投票しようとしているエージェントを報告.
変化すれば報告.
• 役職CO:
3日以内にランダムな日
• 騙り(偽CO):
Talkの実装
public String talk() {
if(投票するプレイヤを宣言していない場合)
投票相手を宣言する発話内容を生成
宣言フラグを立てる
else
発話を終了
end
}
public String talk() {
if(declaredPlanningVoteAgent != planningVoteAgent){
String string = TemplateTalkFactory.vote(planningVoteAgent);
declaredPlanningVoteAgent = planningVoteAgent;
return string;
}else{
return TemplateTalkFactory.over();
}
}
AdvancedGameInfo.java (1/2)
public class AdvanceGameInfo {
/* 発話で伝えられた占い結果のリスト.今回のプロトコルでは何日目に占ったのか分からないので,発話日に設定.*/
private List<Judge> inspectJudgeList = new ArrayList<Judge>();
/* 発話で伝えられた霊能結果のリスト.今回のプロトコルでは何日目に霊能したのか分からないので,発話日に設定.*/
private List<Judge> mediumJudgeList = new ArrayList<Judge>();
private Map<Agent, Role> comingoutMap = new HashMap<Agent, Role>();
public Map<Agent, Role> getComingoutMap() {
return comingoutMap;
}
/* COしたプレイヤーをcomingoutMapに加える.
* @param agent
* @param role */
public void putComingoutMap(Agent agent, Role role){
comingoutMap.put(agent, role);
}
public void setComingoutMap(Map<Agent, Role> comingoutMap) {
this.comingoutMap = comingoutMap;
}
ComingOut した
プレイヤと役職を保
存
エージェントをkeyと
したMapに格納
AdvancedGameInfo.java (2/2)
public List<Judge> getInspectJudgeList() {
return inspectJudgeList;
}
public void setInspectJudgeList(List<Judge> inspectJudgeList) {
this.inspectJudgeList = inspectJudgeList;
}
public void addInspectJudgeList(Judge judge) {
this.inspectJudgeList.add(judge);
}
public List<Judge> getMediumJudgeList() {
return mediumJudgeList;
}
public void setMediumJudgeList(List<Judge> mediumJudgeList) {
this.mediumJudgeList = mediumJudgeList;
}
public void addMediumJudgeList(Judge judge) {
this.mediumJudgeList.add(judge);
}
}
発話から占いCOしたユーザの Judge
情報を拾ってしまうだけ.
なので…
こちらも、占いと同じ
なので…
KajiPlayer のコードを読む
LearningPlayerの構成
• BasePlayer
• GiftedPlayer
• WolfSidePlayer
KajiRole
AssignPlayer
Kaji
Bodygau
rad
Kaji
Medium
Kaji
Possess
ed
Kaji
Seer
Kaji
Villager
Kaji
Werewo
lf
Abstract
KajiBase
Player
AbstractGi
ftedPlayer
Abstract
KajiWolfS
ideAgent
AbstractGi
ftedPlayer
Abstract
KajiWolfS
ideAgent
Abstract
KajiBase
Player
Abstract
KajiBase
Player
Abstract
KajiBase
Player
Abstract
KajiBase
Player
Abstract
KajiBase
Player
KajiPlayer のライブラリ
• AdvancedGameInfo
• Strategies
• CauseOfDeath
• EnemyCase
• Pattern
• PatternMaker
• AbstractFaceRoleChanger
• FakeRoleChanger
• PossessedFakeRoleChanger
• WolfRoleChanger
GameInfo をプレイヤの行動決定用に拡張
行動戦略アルゴリズム?
場合分け用 enum
ゲーム状況分類?
役職の推定方法例
他のプレイヤの役割の可能性を探る(1/3)
player 村人 占い 人狼 狂人
A
B
C
D 村人
E
• 5人人狼(村2, 占1, 狼1, 狂1)の場合
• Player A が占いをCO
• Player B が占いをCO
• Player C が村人だと宣言
Player D (村人) 目線での情報
村人目線からは情報が少ない
でも、ランダムに選んでは負ける
….
他のプレイヤの役割の可能性を探る(2/3)
player 村人 占い 人狼 狂人
A
B
C
D
E 狂人
• 5人人狼(村2, 占1, 狼1, 狂1)の場合
• Player A が占いをCO
• Player B が占いをCO
• Player C が村人だと宣言
Player E (狂人) 目線での情報
狼はAかBだが、
決めてなし
投票は、C or D
他のプレイヤの役割の可能性を探る(3/3)
player 村人 占い 人狼 狂人
A
B 人狼
C
D
E
• 5人人狼(村2, 占1, 狼1, 狂1)の場合
• Player A が占いをCO
• Player B が占いをCO
• Player C が村人だと宣言
Player B (人狼) 目線での情報
狂人が誰?
A が真占だとすると
…
今回の課題
• すべての役職を実装して,他のエージェントと
対戦できるようにする
人狼知能
プログラミング演習
第五講目
電気通信大学 篠田孝祐
人狼知能プログラムを実装す
るうえでの疑問に答えてみる
質問①-1
能力持ちにカミングアウトに重複があった場合のみ,交互に守
る.防御が成功したとき,防御の優先度を上げる優先度を上げる.
という風に考えた.サンプルを参考にして,public Agent guard(){}
の部分を書き換えて,
のように書いた.
その後,if分で条件分岐させ,占い師がいた場合,霊媒師が居た場
合,村人が居た場合と分けようと思ったが,if()の()の中に何を記
述していけばよいかわからなかった.
はじめ,リストの番号で管理しようと思ったが,役職の人数が不
確定で変動するのでうまく行かなかった.
役職名で分岐させようと思ったが型があわなくて失敗した.
アドバイス①-1
• gaurdAgentCandidate : エージェントリスト
• If文で分岐とは
for (Agent agent: gaurdAgentCandidate){
if(agent が占い師COなら)
;
else if (agent が霊媒師COなら)
;
end
}
• 役職に関する情報はどこにあるのか?
• Agent クラスに役職を取ってくるメソッドがある??
• AdvancedGameInfo クラスの ComingOutMap では….
• 「型があわなくて失敗した」
• 何と何を比較したのか? Agent と Role?
質問①-2
• 優先度を,上げていく場合,新たに優先度を記
述したメソッドをどう作っていけばいいのかわ
からなかった.
• 優先度を記述するメソッドってなに?
質問②
• 村人の投票の仕方にライン理論の考え方を実装し
たいと考えているが、他人の投票先をどうやって
プログラムに書いていけばいいかわかりません。
• ライン理論…狼同士は互いに投票しあうことはないという前
提で、誰と誰がペアのような行動をとっているかを推理する
方法
とりあえずのアドバイス②
• 投票結果を保存するだけなら、前回紹介した
kajiAgent の AdvancedGameInfo くらすに
voteLists があります。
アドバイス②
• 投票を構成する情報
• 何日目、誰が、誰に、投票した
• ラインを構成する情報
• 誰と誰
• 誰(Agent)の情報
• 名前: getName() 同じ名前の場合がある
• ID: getAgentIdx() おそらくユニーク
• AgentIndex をkeyとするMapを作成して保存
• String: “(ID,ID)” という文字列を使って1次元配列
• int: ID を使用して2次元配列とする
人狼知能エージェントに学習
させるには?
強化学習(Reinforcement Learning)
• 強化学習とは、ある条件下における対応に対す
る尤度(もっともらしさ)を獲得するための手
法
• 出力に対する結果の良し悪しで報酬を与えるこ
とで、よりよい結果を得られる行動系列を獲得
しようとする
http://spider.art.coocan.jp/biology2/behavior2012.htm より
エージェントのQ学習(1/2)
• エージェントが観測した環境 s において,行動
a を実行する確率を、報酬によって最適化する。
• エージェントが,行動を決定する方策πに基づいて、
行動 a を選択できるような確率分布を獲得するのが
Q学習
環境
行動 観測・報酬
エージェントのQ学習(2/2)
• ある時刻tでの環境と行動の組み合わせ (s, a)
に対して、次の時刻 t + 1 の環境 st+1 をもとに報
酬 r を決定して、 (s, a) に対して報酬rを与える。
• Q(s,a) ← Q(s,a) + α[r + γ max Q(st+1,p)- Q(s,a)] α 学習係数
• π(s,a): ランダム, ε-グリーディ, ルーレット、soft
max, 等
• そのため、環境をすべて観測できるか、できな
いかによって、学習した尤度への信頼性がこと
なる
• MDP: マルコフ行動決定過程
• POMDP: 部分観測マルコフ行動決定過程
部分観測状態とは…
全体が把握できないで、一部
しか観測できない状態
人狼ゲームにおける観測情報は部分的かつ確率的なものである!
人狼知能を強化学習するには
• 環境 S を定義する
• 投票結果
• CO状況
• 会話内容
• (役職)
• 行動 A を定義する
• 投票
• 占い・護衛・襲撃 対象の決定
• 発話
• 報酬 R を定義する
• ゲームの勝利
• 人狼・占師の追放
• 騙せたとき
これらを定義したうえで,人狼BBSの
データなどを用いて学習させる!
補足資料
擬似コードとは(1/2)
• アルゴリズムなどを、架空の非常に高水準なプ
ログラミング言語で記述したものである。既存
のプログラミング言語の構文と、自然言語に近
い表現を組み合わせて記述することが多い。
※一部 wikipedia より引用
if クレジットカード番号が有効
番号と注文で取引をする
else
エラーを表示する
end if
クレジットカード処理の擬似コード
発言数を保存したリスト a から、
一番大きな数値のプレイヤを選択
する
for 発言数 tmp_a : a
最小の発言数と tmp_a を
比較して大きい場合には発言
数とエージェントを保存
end
return 発言数の多いエージェント
発言が多い人を探して投票
擬似コードとは(2/2)
• 処理内容をわかりやすい文章として書く
• 特定のプログラミング言語について知識がない
ひとでも理解できるようにする
• プログラムにおけるアルゴリズムの設計とコー
ディングを分離する
• 擬似コードの書き方には標準化された方法はな
い
• でも、プログラム書き直しやすい書き方のほうがよ
い
サーバとクライアントの接続
人狼知能サーバでは,将来的なこと(複数プログラミン
グ言語での接続)を想定して,2種類の接続方式で実装
されている.
サーバクライアント型システム
サーバ
クライアント
クライアント
クライアント
クライアント
クライアント
ポート
ポート
ポート
ポート
ポート
ポート
ポート
ポート
ポート
ポート
TCP/IP, UDP/IP
同期非通信型システム
サーバ クライアント
クライアント
クライアント
メソッド
メソッド
メソッド
メソッド
メソッド
メソッド
内部メソッド
呼び出し
Java 言語に関する資料
パッケージの宣言、インポート
• パッケージとは
• 複数あるクラスファイルをまとめるための仕組み
• ファイル名(名前)の衝突回避
• ライブラリとしての公開
• パッケージの定義
package org.aiwolf.common.util;
同じファイル構造(org/aiwolf/common/util/)に設置が必
要
• パッケージの読み込み
import org.aiwolf.common.util.*;
import org.aiwolf.common.util.Sorter.java;
* とすることで、そのフォルダにあるものをすべてイン
ポート可能であるが、実行ファイル・速度に影響があ
る
Javaの変数のスコープ
• スコープ修飾子
• public: インスタンスを通して直接アクセス可能
• protected: クラス内、継承したサブクラスからアク
セス可能
• 無し: パッケージ内から
• private: クラス内から
• メソッド内、 {} 内
• static
• 異なるインスタンスどうしで値を共有
ジェネリクス型
• AiWolfCommon/src/org/aiwolf/common/util/ 以下などで
使用
• Counter.java
• Sorter.java
• BidiMap.java
• Java の配列データは、基本的に任意の型を格納できる。
• でも、実際に一つの配列にいろんな方を入れることはない
• データを取り出すときに、キャストするのが煩わしい
• 特定のデータ型(クラス)を格納する宣言をしてしまいたい
• ジェネリクスを用いた実装
public class ArrayList<E> extends AbstractLink<E> … {
…
public <T> T[] toArray(T[] a) { … }
….
}
データの格納・アクセス
• List<Object>
• ArrayList<Object>
• LinkedList<Object>: FIFO
• Map<Key, Value>
• LinkedHashMap<Key, Value>
• TreeMap<Key, Value>
• BidiMap<Key, Value>: Key、Valueどちらの要素でも
アクセス可能なMap
• Counter<V> : 要素Vに対する投票や数え上げ
イテレータ・拡張for文
List<Objet> list;
• 通常: データに要素番号でアクセスできないと難しい
for(int i = 0; i < MAX; i++) {
Object obj = list[i]; // list.get(i);
System.out.println(obj);
}
• イテレータ: データ構造から直接取得するので高速
for(Iterator<Object> it = list.iterator(); it.hasNext(); ){
Object obj = it.next();
System.out.println();
}
• 拡張for文(for-each文): イテレータを活用して実装してある
For(Object obj: list) {
System.out.println(obj);
}
インスタンスの生成方法
• 一般的なインスタンス生成
• Object obj = new Object();
• クラス名:String からのインスタンス生成
• Object obj = (Object)Class.forName(クラス
名:String).newInstance();
アノテーション、JavaDoc
@Override
• メソッドのオーバライド時にアノテーションを加え
ることで、タイプミスなどをコンパイル時に警告さ
れる
@Deprecated
• メソッドやクラスが、バージョンアップで変更され
て、推奨されないものであるものに対して警告をす
る
@SuppressWarning
• コンパイル時の警告を抑制するためのアノテーショ
ン。
命名・コーディング規則の重要性
以下のソースコードを目にした時の感想は?
----------------------------------------------------------------------
public class FileCopy(){
private String f1;
private String f2;
public void main( String[] args ) throws Exception{
FileCopy a = new FileCopy();
a.f1 = new File( args[0] );
a.f2 = new File( args[1] );
a.run( 1024 );}
private void run( int i ) throws Exception{
FileInputStream s1 = new FileInputStream( f1 );
FileOutputStream s2 = new FileOutputStream( f2 );
byte[] b = new byte[i];
Int j;
while( (j=s1.read(b))>0) s2.write( b,0,j);
s1.close();
s2.close();
}}
ソースコードを読みやすくするには
• 意味が分かる(伝わる)ように書く
• クラスなのか、メソッドなのか、変数なのかわかる
ように
• メソッド名は動詞+名詞のように機能がわかるよう
に
• スコープがわかるように書く
• スコープ接頭語をつけたりする
• static なら s_*, メンバ変数であれば m_*, 引数なら a_* と
• 定数は大文字にする
Javaコーディング規則(1)
• パッケージ名は小文字
java.io.*;
• クラス名
• 先頭は大文字、複数の単語からなる場合には単語の先頭は大文字
class Sample {}
• 意味ある名前にして略さない
• メソッド名
• コンストラクタと同じ名前のメソッドは作らない
• メソッド名は文字の区切りのみ大文字
int getParameter() {}
void setParameter(int value) {}
• メソッドの役割を表す名前は統一する
• 返り値が Boolean の値の時にはTrue/Falseがわかるようにする
boolean isSampleClass() {} Boolean hasStock() {}
• 引数に入れる変数とメンバ変数を同じ名前にしない
Int num = 0;
void setParameter(int num){
this.num = num;
}
Java コーディング規則(2)
• 変数
• boolen 変数は、true/false がわかるような名前に
boolean hasTree;
boolean isMan;
• 定数は、なるべく static final で宣言して大文字に
static final int NUM_TRIAL;
• 変数名は役割がわかるように命名
• スコープの狭い変数はわかる範囲で略してもよい

More Related Content

What's hot

Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Jin wook
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tipsikeyat
 
NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅Seungjae Lee
 
はじめてのCF buildpack
はじめてのCF buildpackはじめてのCF buildpack
はじめてのCF buildpackKazuto Kusama
 
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack FirmwareSimen Li
 
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化Gosuke Miyashita
 
カジュアルにMongo dbのbackup機能説明
カジュアルにMongo dbのbackup機能説明カジュアルにMongo dbのbackup機能説明
カジュアルにMongo dbのbackup機能説明Masakazu Matsushita
 
Play with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit TechniquePlay with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit TechniqueAngel Boy
 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ applicationDaniele Pallastrelli
 
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)fisuda
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]MongoDB
 
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...Masahiko Sawada
 
ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)akira6592
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.kiki utagawa
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)fisuda
 
オンプレでPrivate Registry使ったDockerイメージの運用について
オンプレでPrivate Registry使ったDockerイメージの運用についてオンプレでPrivate Registry使ったDockerイメージの運用について
オンプレでPrivate Registry使ったDockerイメージの運用についてYASUKAZU NAGATOMI
 

What's hot (20)

Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략Mongo DB 성능최적화 전략
Mongo DB 성능최적화 전략
 
Cordovaの特徴と開発手法概要
Cordovaの特徴と開発手法概要Cordovaの特徴と開発手法概要
Cordovaの特徴と開発手法概要
 
知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips知っておきたいSpring Batch Tips
知っておきたいSpring Batch Tips
 
NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅NDC14 - 사례로 배우는 디스어셈블리 디버깅
NDC14 - 사례로 배우는 디스어셈블리 디버깅
 
はじめてのCF buildpack
はじめてのCF buildpackはじめてのCF buildpack
はじめてのCF buildpack
 
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee Architecture 與 TI Z-Stack Firmware
 
イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化イベント駆動プログラミングとI/O多重化
イベント駆動プログラミングとI/O多重化
 
カジュアルにMongo dbのbackup機能説明
カジュアルにMongo dbのbackup機能説明カジュアルにMongo dbのbackup機能説明
カジュアルにMongo dbのbackup機能説明
 
SQLite の暗号化
SQLite の暗号化SQLite の暗号化
SQLite の暗号化
 
x86
x86x86
x86
 
Play with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit TechniquePlay with FILE Structure - Yet Another Binary Exploit Technique
Play with FILE Structure - Yet Another Binary Exploit Technique
 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ application
 
Marp Tutorial
Marp TutorialMarp Tutorial
Marp Tutorial
 
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
 
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
 
ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)
ネットワーク自動化、なに使う? ~自動化ツール紹介~ (2017/07/21開催)
 
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
 
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
 
オンプレでPrivate Registry使ったDockerイメージの運用について
オンプレでPrivate Registry使ったDockerイメージの運用についてオンプレでPrivate Registry使ったDockerイメージの運用について
オンプレでPrivate Registry使ったDockerイメージの運用について
 

Viewers also liked

Pyramid + socket.io 人狼を作ってみた
Pyramid + socket.io 人狼を作ってみたPyramid + socket.io 人狼を作ってみた
Pyramid + socket.io 人狼を作ってみたJunya Hayashi
 
人狼知能エージェント作成方法
人狼知能エージェント作成方法人狼知能エージェント作成方法
人狼知能エージェント作成方法kengo009
 
人狼知能エージェント作成方法
人狼知能エージェント作成方法人狼知能エージェント作成方法
人狼知能エージェント作成方法kengo009
 
脱初心者! 経験は人狼力を向上させるのか? ~データから見るベテランの実力~
脱初心者!経験は人狼力を向上させるのか?~データから見るベテランの実力~脱初心者!経験は人狼力を向上させるのか?~データから見るベテランの実力~
脱初心者! 経験は人狼力を向上させるのか? ~データから見るベテランの実力~Fujio Toriumi
 
Classboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methodsClassboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methodsShugo Maeda
 
人狼ルール説明
人狼ルール説明人狼ルール説明
人狼ルール説明jinrawinc
 
人狼知能プロジェクト・プロトコル解説
人狼知能プロジェクト・プロトコル解説人狼知能プロジェクト・プロトコル解説
人狼知能プロジェクト・プロトコル解説Hirotaka Osawa
 
人狼知能セミナー資料20160507
人狼知能セミナー資料20160507人狼知能セミナー資料20160507
人狼知能セミナー資料20160507Fujio Toriumi
 
人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館
人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館
人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館Fujio Toriumi
 
8つの魔法の習得 -RとRubyによるデータ解析入門より-
8つの魔法の習得 -RとRubyによるデータ解析入門より-8つの魔法の習得 -RとRubyによるデータ解析入門より-
8つの魔法の習得 -RとRubyによるデータ解析入門より-Yuki Shimizu
 
通信対戦ゲームを作った話
通信対戦ゲームを作った話通信対戦ゲームを作った話
通信対戦ゲームを作った話mipsparc
 
Rubyと機械学習の現状
Rubyと機械学習の現状Rubyと機械学習の現状
Rubyと機械学習の現状Aki Ariga
 
Rubyによるデータ解析
Rubyによるデータ解析Rubyによるデータ解析
Rubyによるデータ解析Shugo Maeda
 
Awsとrubyで作るビッグデータ解析の裏側
Awsとrubyで作るビッグデータ解析の裏側Awsとrubyで作るビッグデータ解析の裏側
Awsとrubyで作るビッグデータ解析の裏側Shohei Kobayashi
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみたYuusuke Takeuchi
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeMasahiro Tanaka
 
RubyエンジニアがPythonをdisるためにPythonを勉強してみた
RubyエンジニアがPythonをdisるためにPythonを勉強してみたRubyエンジニアがPythonをdisるためにPythonを勉強してみた
RubyエンジニアがPythonをdisるためにPythonを勉強してみたYusuke Kon
 

Viewers also liked (17)

Pyramid + socket.io 人狼を作ってみた
Pyramid + socket.io 人狼を作ってみたPyramid + socket.io 人狼を作ってみた
Pyramid + socket.io 人狼を作ってみた
 
人狼知能エージェント作成方法
人狼知能エージェント作成方法人狼知能エージェント作成方法
人狼知能エージェント作成方法
 
人狼知能エージェント作成方法
人狼知能エージェント作成方法人狼知能エージェント作成方法
人狼知能エージェント作成方法
 
脱初心者! 経験は人狼力を向上させるのか? ~データから見るベテランの実力~
脱初心者!経験は人狼力を向上させるのか?~データから見るベテランの実力~脱初心者!経験は人狼力を向上させるのか?~データから見るベテランの実力~
脱初心者! 経験は人狼力を向上させるのか? ~データから見るベテランの実力~
 
Classboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methodsClassboxes, nested methods, and real private methods
Classboxes, nested methods, and real private methods
 
人狼ルール説明
人狼ルール説明人狼ルール説明
人狼ルール説明
 
人狼知能プロジェクト・プロトコル解説
人狼知能プロジェクト・プロトコル解説人狼知能プロジェクト・プロトコル解説
人狼知能プロジェクト・プロトコル解説
 
人狼知能セミナー資料20160507
人狼知能セミナー資料20160507人狼知能セミナー資料20160507
人狼知能セミナー資料20160507
 
人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館
人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館
人工知能は人狼の夢を見るか-日本デジタルゲーム学会年次大会2013@函館
 
8つの魔法の習得 -RとRubyによるデータ解析入門より-
8つの魔法の習得 -RとRubyによるデータ解析入門より-8つの魔法の習得 -RとRubyによるデータ解析入門より-
8つの魔法の習得 -RとRubyによるデータ解析入門より-
 
通信対戦ゲームを作った話
通信対戦ゲームを作った話通信対戦ゲームを作った話
通信対戦ゲームを作った話
 
Rubyと機械学習の現状
Rubyと機械学習の現状Rubyと機械学習の現状
Rubyと機械学習の現状
 
Rubyによるデータ解析
Rubyによるデータ解析Rubyによるデータ解析
Rubyによるデータ解析
 
Awsとrubyで作るビッグデータ解析の裏側
Awsとrubyで作るビッグデータ解析の裏側Awsとrubyで作るビッグデータ解析の裏側
Awsとrubyで作るビッグデータ解析の裏側
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
 
Ruby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrakeRuby科学データ処理ツールの開発 NArrayとPwrake
Ruby科学データ処理ツールの開発 NArrayとPwrake
 
RubyエンジニアがPythonをdisるためにPythonを勉強してみた
RubyエンジニアがPythonをdisるためにPythonを勉強してみたRubyエンジニアがPythonをdisるためにPythonを勉強してみた
RubyエンジニアがPythonをdisるためにPythonを勉強してみた
 

Similar to 人狼知能プログラミング演習資料2015

Unity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだことUnity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだことKatsutoshi Makino
 
0730 bp study#35発表資料
0730 bp study#35発表資料0730 bp study#35発表資料
0730 bp study#35発表資料Yasuhiro Horiuchi
 
採用LT「まだお祈りデプロイで消耗してるの?」
採用LT「まだお祈りデプロイで消耗してるの?」採用LT「まだお祈りデプロイで消耗してるの?」
採用LT「まだお祈りデプロイで消耗してるの?」Takayuki Fukumoto
 
AutoEncoderで特徴抽出
AutoEncoderで特徴抽出AutoEncoderで特徴抽出
AutoEncoderで特徴抽出Kai Sasaki
 
機械学習 / Deep Learning 大全 (1) 機械学習基礎編
機械学習 / Deep Learning 大全 (1) 機械学習基礎編機械学習 / Deep Learning 大全 (1) 機械学習基礎編
機械学習 / Deep Learning 大全 (1) 機械学習基礎編Daiyu Hatakeyama
 
CVPR2016 reading - 特徴量学習とクロスモーダル転移について
CVPR2016 reading - 特徴量学習とクロスモーダル転移についてCVPR2016 reading - 特徴量学習とクロスモーダル転移について
CVPR2016 reading - 特徴量学習とクロスモーダル転移についてAkisato Kimura
 
Google Cloud Platformでソーシャルゲームを1本出してみた!
Google Cloud Platformでソーシャルゲームを1本出してみた!Google Cloud Platformでソーシャルゲームを1本出してみた!
Google Cloud Platformでソーシャルゲームを1本出してみた!Hasegawa Yusuke
 
Infrastructure as Codeの取り組みと改善
Infrastructure as Codeの取り組みと改善Infrastructure as Codeの取り組みと改善
Infrastructure as Codeの取り組みと改善Takashi Honda
 
【20-E-5】実践!Infrastructure as a Codeの取り組みと改善
【20-E-5】実践!Infrastructure as a Codeの取り組みと改善【20-E-5】実践!Infrastructure as a Codeの取り組みと改善
【20-E-5】実践!Infrastructure as a Codeの取り組みと改善Developers Summit
 
iOS ジオフェンシングで簡単リアル連動
iOS ジオフェンシングで簡単リアル連動iOS ジオフェンシングで簡単リアル連動
iOS ジオフェンシングで簡単リアル連動OCHI Shuji
 
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現gree_tech
 
Amazon DynamoDB 初心者が理解した事
Amazon DynamoDB 初心者が理解した事Amazon DynamoDB 初心者が理解した事
Amazon DynamoDB 初心者が理解した事Hirokazu Tokuno
 
【Hpcstudy】みんな、ベンチマークどうやってるの?
【Hpcstudy】みんな、ベンチマークどうやってるの?【Hpcstudy】みんな、ベンチマークどうやってるの?
【Hpcstudy】みんな、ベンチマークどうやってるの?Seiichiro Ishida
 
Jaws festa-2014-cdp-03
Jaws festa-2014-cdp-03Jaws festa-2014-cdp-03
Jaws festa-2014-cdp-03宗 大栗
 
地方企業がソーシャルゲーム開発を成功させるための10のポイント
地方企業がソーシャルゲーム開発を成功させるための10のポイント地方企業がソーシャルゲーム開発を成功させるための10のポイント
地方企業がソーシャルゲーム開発を成功させるための10のポイントKentaro Matsui
 
人狼知能セミナー資料案20170624
人狼知能セミナー資料案20170624人狼知能セミナー資料案20170624
人狼知能セミナー資料案20170624Kosuke Shinoda
 
20180217 hackertackle geode
20180217 hackertackle geode20180217 hackertackle geode
20180217 hackertackle geodeMasaki Yamakawa
 

Similar to 人狼知能プログラミング演習資料2015 (20)

Unity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだことUnity * スマートフォン開発で学んだこと
Unity * スマートフォン開発で学んだこと
 
0730 bp study#35発表資料
0730 bp study#35発表資料0730 bp study#35発表資料
0730 bp study#35発表資料
 
採用LT「まだお祈りデプロイで消耗してるの?」
採用LT「まだお祈りデプロイで消耗してるの?」採用LT「まだお祈りデプロイで消耗してるの?」
採用LT「まだお祈りデプロイで消耗してるの?」
 
AutoEncoderで特徴抽出
AutoEncoderで特徴抽出AutoEncoderで特徴抽出
AutoEncoderで特徴抽出
 
機械学習 / Deep Learning 大全 (1) 機械学習基礎編
機械学習 / Deep Learning 大全 (1) 機械学習基礎編機械学習 / Deep Learning 大全 (1) 機械学習基礎編
機械学習 / Deep Learning 大全 (1) 機械学習基礎編
 
CVPR2016 reading - 特徴量学習とクロスモーダル転移について
CVPR2016 reading - 特徴量学習とクロスモーダル転移についてCVPR2016 reading - 特徴量学習とクロスモーダル転移について
CVPR2016 reading - 特徴量学習とクロスモーダル転移について
 
Google Cloud Platformでソーシャルゲームを1本出してみた!
Google Cloud Platformでソーシャルゲームを1本出してみた!Google Cloud Platformでソーシャルゲームを1本出してみた!
Google Cloud Platformでソーシャルゲームを1本出してみた!
 
Infrastructure as Codeの取り組みと改善
Infrastructure as Codeの取り組みと改善Infrastructure as Codeの取り組みと改善
Infrastructure as Codeの取り組みと改善
 
【20-E-5】実践!Infrastructure as a Codeの取り組みと改善
【20-E-5】実践!Infrastructure as a Codeの取り組みと改善【20-E-5】実践!Infrastructure as a Codeの取り組みと改善
【20-E-5】実践!Infrastructure as a Codeの取り組みと改善
 
iOS ジオフェンシングで簡単リアル連動
iOS ジオフェンシングで簡単リアル連動iOS ジオフェンシングで簡単リアル連動
iOS ジオフェンシングで簡単リアル連動
 
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
アナザーエデンにおける非同期オートセーブを用いた通信待ちストレスのないゲーム体験の実現
 
Amazon DynamoDB 初心者が理解した事
Amazon DynamoDB 初心者が理解した事Amazon DynamoDB 初心者が理解した事
Amazon DynamoDB 初心者が理解した事
 
Jsai2019 softbank_industrial-session
Jsai2019 softbank_industrial-sessionJsai2019 softbank_industrial-session
Jsai2019 softbank_industrial-session
 
Apache geode at-s1p
Apache geode at-s1pApache geode at-s1p
Apache geode at-s1p
 
【Hpcstudy】みんな、ベンチマークどうやってるの?
【Hpcstudy】みんな、ベンチマークどうやってるの?【Hpcstudy】みんな、ベンチマークどうやってるの?
【Hpcstudy】みんな、ベンチマークどうやってるの?
 
Jaws festa-2014-cdp-03
Jaws festa-2014-cdp-03Jaws festa-2014-cdp-03
Jaws festa-2014-cdp-03
 
地方企業がソーシャルゲーム開発を成功させるための10のポイント
地方企業がソーシャルゲーム開発を成功させるための10のポイント地方企業がソーシャルゲーム開発を成功させるための10のポイント
地方企業がソーシャルゲーム開発を成功させるための10のポイント
 
JAWS DAYS 2022
JAWS DAYS 2022JAWS DAYS 2022
JAWS DAYS 2022
 
人狼知能セミナー資料案20170624
人狼知能セミナー資料案20170624人狼知能セミナー資料案20170624
人狼知能セミナー資料案20170624
 
20180217 hackertackle geode
20180217 hackertackle geode20180217 hackertackle geode
20180217 hackertackle geode
 

Recently uploaded

The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024koheioishi1
 
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料Takayuki Itoh
 
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学ssusere0a682
 
TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationYukiTerazawa
 
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学ssusere0a682
 
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2Tokyo Institute of Technology
 
UniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScriptUniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScriptyuitoakatsukijp
 

Recently uploaded (7)

The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024
 
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
 
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
 
TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentation
 
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
 
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
 
UniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScriptUniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScript
 

人狼知能プログラミング演習資料2015