発話の取得
@Override public String talk() { GameInfo gameInfo = getLatestDayGameInfo(); List<Talk> talkList = gameInfo.getTalkList(); System.out.println("Today's talk"); for(Talk talk:talkList){ System.out.println(talk); } return null; }
Today's talk Day00[000] Agent[02] 5 werewolf 中略 Today's talk Day01[000] Agent[02] 6 werewolf Day01[001] Agent[04] ( 11 werewolf ) and ( 4 comingout seer ) and ( 3 inspected HUMAN ) Day01[002] Agent[09] 4 werewolf Day01[003] Agent[10] 2 werewolf Day01[004] Agent[01] 12 werewolf Day01[005] Agent[03] 12 werewolf Day01[006] Agent[12] 2 werewolf 中略 Today's talk Day01[000] Agent[02] 6 werewolf Day01[001] Agent[04] ( 11 werewolf ) and ( 4 comingout seer ) and ( 3 inspected HUMAN ) Day01[002] Agent[09] 4 werewolf Day01[003] Agent[10] 2 werewolf Day01[004] Agent[01] 12 werewolf Day01[005] Agent[03] 12 werewolf Day01[006] Agent[12] 2 werewolf Day01[007] Agent[06] 1 werewolf Day01[008] Agent[11] 10 werewolf Day01[009] Agent[11] Over Day01[010] Agent[10] Over Day01[011] Agent[03] Over Day01[012] Agent[04] Over 中略 Today's talk Day01[000] Agent[02] 6 werewolf Day01[001] Agent[04] ( 11 werewolf ) and ( 4 comingout seer ) and ( 3 inspected HUMAN ) Day01[002] Agent[09] 4 werewolf Day01[003] Agent[10] 2 werewolf Day01[004] Agent[01] 12 werewolf Day01[005] Agent[03] 12 werewolf Day01[006] Agent[12] 2 werewolf Day01[007] Agent[06] 1 werewolf Day01[008] Agent[11] 10 werewolf Day01[009] Agent[11] Over Day01[010] Agent[10] Over Day01[011] Agent[03] Over Day01[012] Agent[04] Over Day01[013] Agent[06] Over Day01[014] Agent[02] 9 werewolf Day01[015] Agent[09] Over Day01[016] Agent[12] Over Day01[017] Agent[01] Over Day01[018] Agent[09] Over Day01[019] Agent[11] Over Day01[020] Agent[01] Over Day01[021] Agent[06] Over Day01[022] Agent[12] Over Day01[023] Agent[04] Over
@Override public String talk() { List<Talk> talkList = getUpdatedTalk(); System.out.println("Updated talk"); for(Talk talk:talkList){ System.out.println(talk); } return null; } /** * 前回最後に獲得したTalkのインデックス */ int lastTalkIdx = -1; /** * 前回最後に獲得したTalkの日付 */ int lastTalkDay = -1; /** * 前回Talkを取得した後投稿されたTalkのみを獲得する * @return 前回獲得したTalkとの差分が入ったList */ protected List<Talk> getUpdatedTalk(){ GameInfo gameInfo = getLatestDayGameInfo(); List<Talk> talkList = gameInfo.getTalkList(); if(lastTalkDay != gameInfo.getDay()){ lastTalkDay = gameInfo.getDay(); if(!talkList.isEmpty()){ lastTalkIdx = talkList.get(talkList.size()-1).getIdx(); } return talkList; } for(int i = 0; i < talkList.size(); i++){ if(talkList.get(i).getIdx() > lastTalkIdx){ lastTalkIdx = talkList.get(talkList.size()-1).getIdx(); return talkList.subList(i, talkList.size()); } } return new ArrayList<>(); }
Updated talk Day00[000] Agent[04] 7 werewolf Day00[001] Agent[08] 4 werewolf Day00[002] Agent[05] 11 werewolf Day00[003] Agent[10] 4 werewolf Day00[004] Agent[11] 4 werewolf Day00[005] Agent[01] 5 werewolf Day00[006] Agent[12] 8 werewolf Day00[007] Agent[07] 10 werewolf Day00[008] Agent[02] 10 werewolf Day00[009] Agent[06] 10 werewolf 中略 Updated talk Day00[010] Agent[09] 6 werewolf Day00[011] Agent[08] Over 中略 Updated talk Day02[000] Agent[01] 10 werewolf Day02[001] Agent[10] ( 2 werewolf ) and ( 10 comingout seer ) and ( 9 inspected HUMAN ) and ( 6 inspected werewolf ) Day02[002] Agent[06] ( 1 werewolf ) and ( 6 comingout medium ) and ( 3 medium_telled HUMAN ) and ( 4 medium_telled HUMAN ) Day02[003] Agent[02] 6 werewolf Day02[004] Agent[09] 6 werewolf Day02[005] Agent[11] 6 werewolf
発話の内容
Day00[000] Agent[04] 7 werewolf
Day00[011] Agent[08] Over
Day02[001] Agent[10] ( 2 werewolf ) and ( 10 comingout seer ) and ( 9 inspected HUMAN ) and ( 6 inspected werewolf ) Day02[002] Agent[06] ( 1 werewolf ) and ( 6 comingout medium ) and ( 3 medium_telled HUMAN ) and ( 4 medium_telled HUMAN )
Day00[000] Agent[04] 7 werewolf
Day02[001] Agent[10] ( 2 werewolf ) and ( 10 comingout seer ) and ( 9 inspected HUMAN ) and ( 6 inspected werewolf )
Agent2が人狼だと思うAgent10は占い師だとカミングアウトするAgent9は占いの結果人間だったAgent6は占いの結果人狼だった
Day02[001] Agent[10] ( 2 werewolf ) and ( 10 comingout seer ) and ( 9 inspected HUMAN ) and ( 6 inspected werewolf ) Day02[002] Agent[06] ( 1 werewolf ) and ( 6 comingout medium ) and ( 3 medium_telled HUMAN ) and ( 4 medium_telled HUMAN )
Agent1が人狼だと思うAgent6は霊媒師だとカミングアウトするAgent3は霊媒の結果人間だったAgent4は霊媒の結果人間だった
発話の理解
Talkのパースには,Protocolクラスを利用する.
Protocolクラスは,人狼プロトコルを理解するためのクラスで,複数のUtteranceから構成され, UtteranceはSentenceTypeとPassageからなり・・・という多層構造を持っている.
大まかなProtocolクラスの概略は以下の通り.
実際に以下のコードで実行してみる.
なお,ここではその日の会話を総合して投票先を決める,ということを考え,talkメソッドではなく,voteメソッドでtalkのパースを行う.
@Override public Agent vote() { GameInfo gameInfo = getLatestDayGameInfo(); Agent myself = gameInfo.getAgent(); List<Talk> talkList = gameInfo.getTalkList(); for(Talk talk:talkList){ System.out.println(talk); Protocol protocol = new Protocol(talk.getContent()); List<Utterance> utteranceList = protocol.getUtterances(); System.out.println("Num of Utterance="+utteranceList.size()); for(Utterance utterance:utteranceList){ SentenceType sentenceType = utterance.getSentenceType(); Passage passage = utterance.getPassage(); if(sentenceType != null){ System.out.println("sentenceType"); System.out.println(sentenceType.getUv()); System.out.println(sentenceType.getRate()); } if(passage != null){ System.out.println("passage"); System.out.println("Action="+passage.getAction()); System.out.println("Attribution="+passage.getAttribution()); System.out.println("Category="+passage.getCategory()); System.out.println("Object="+passage.getObject()); System.out.println("State="+passage.getState()); System.out.println("Subject="+passage.getSubject()); System.out.println("Verb="+passage.getVerb()); } } } List<Agent> agentList = gameInfo.getAliveAgentList(); for(Agent agent:agentList){ if(agent != myself){ System.out.println(myself+" vote to "+agent); return agent; } } throw new AIWolfRuntimeException("Something wrong"); }
Day00[003] Agent[07] 7 werewolf Num of Utterance=1 passage Action=null Attribution=null Category=ESTIMATE Object=null State=werewolf Subject=Agent[07] Verb=is
さて,この中身について具体的にみる. まず「7 werewolf」という発話は,「Agent7は人狼だと思う」という意味を持つ.
文としては単文のため,Utteranceは1つ.
そのUtteranceを分解すると,
カテゴリは推定(ESTIMATE)対象(Subject)はAgent07動詞はis状態は人狼(werewolf)
Day03[005] Agent[04] ( 2 werewolf ) and ( 4 comingout seer ) and ( 12 inspected HUMAN ) and ( 10 inspected werewolf ) Num of Utterance=4 passage2 werewolf部分のUtterance Action=null Attribution=null Category=ESTIMATE Object=null State=werewolf Subject=Agent[02] Verb=is passage//4 comingout seer部分のUtterance Action=null Attribution=null Category=COMINGOUT Object=seer State=null Subject=Agent[04] Verb=comingout passage//12 inspected HUMAN部分のUtterance Action=inspected Attribution=Human Category=RESULT Object=null State=null Subject=Agent[12] Verb=inspected passage//10 inspected部分のUtterance Action=inspected Attribution=Werewolf Category=RESULT Object=null State=null Subject=Agent[10] Verb=inspected
他エージェントの発話を考慮した投票先決定
ここでは,簡単のために
「seerだとカミングアウトしたエージェントの投票に合わせる」.
という戦略を実装する.
/** * 人狼候補 */ SetwerewolfCandidateSet = new HashSet<>(); @Override public Agent vote() { GameInfo gameInfo = getLatestDayGameInfo(); Agent myself = gameInfo.getAgent(); List<Talk> talkList = gameInfo.getTalkList(); for(Talk talk:talkList){ Protocol protocol = new Protocol(talk.getContent()); List<Utterance> utteranceList = protocol.getUtterances(); for(Utterance utterance:utteranceList){ SentenceType sentenceType = utterance.getSentenceType(); Passage passage = utterance.getPassage(); if(passage != null){ if(passage.getCategory() == Category.COMINGOUT){ if(passage.getObject() == Role.seer){ Agent candidate = talk.getAgent(); seerCandidateSet.add(candidate); } } } } } System.out.println("Find Candidate"); //占い師の意見だけ採用 for(Talk talk:talkList){ if(!seerCandidateSet.contains(talk.getAgent())){ continue; } Protocol protocol = new Protocol(talk.getContent()); List<Utterance> utteranceList = protocol.getUtterances(); for(Utterance utterance:utteranceList){ Passage passage = utterance.getPassage(); if(passage.getCategory() == Category.RESULT && passage.getVerb() == Verb.inspected){ if(passage.getAttribution() == Species.Werewolf){ System.out.println(talk); Agent candidate = passage.getSubject(); if(candidate != myself){ werewolfCandidateSet.add(candidate); } else{ //自分を人狼だと言ってきたら,その占い師こそが人狼だ! seerCandidateSet.remove(talk.getAgent()); werewolfCandidateSet.add(talk.getAgent()); } } } } } for(Agent candidate:seerCandidateSet){ System.out.println("Seer candidate:"+candidate+" "+gameInfo.getStatusMap().get(candidate)); } for(Agent candidate:werewolfCandidateSet){ System.out.println("Werewolf candidate:"+candidate+" "+gameInfo.getStatusMap().get(candidate)); } //見つかった人狼候補に生きているものがいれば,そこに投票 for(Agent candidate:werewolfCandidateSet){ if(gameInfo.getStatusMap().get(candidate) == Status.alive){ System.out.println(myself+" vote to "+candidate+" by seer's result"); return candidate; } } //生きている人狼候補がいなければ,適当に投票 List<Agent> agentList = gameInfo.getAliveAgentList(); for(Agent agent:agentList){ if(agent != myself || seerCandidateSet.contains(agent)){ System.out.println(myself+" vote to "+agent); return agent; } } throw new AIWolfRuntimeException("Something wrong"); }
Find Candidate Day02[008] Agent[04] ( 12 werewolf ) and ( 3 inspected werewolf ) Seer candidate:Agent[04] alive Seer candidate:Agent[12] alive Werewolf candidate:Agent[03] alive Agent[10] vote to Agent[03] by seer's result 中略 =========== Day 03 Agent[03] executed Agent[12] divine Agent[04]. Result is Human Agent[07] guarded Agent[09]@2 guarded null attacked ====== Agent[01] SamplePlayer dead medium Agent[02] SamplePlayer alive villager Agent[03] SamplePlayer dead werewolf executed Agent[04] SamplePlayer alive possessed divined Agent[05] SamplePlayer alive villager Agent[06] SamplePlayer dead werewolf Agent[07] SamplePlayer alive bodyguard Agent[08] SamplePlayer alive villager Agent[09] SamplePlayer alive villager guarded Agent[10] BasePlayer alive villager Agent[11] SamplePlayer alive villager Agent[12] SamplePlayer alive seer
次は,自分の意見をTalkで表明することを目指してみよう.
0 件のコメント:
コメントを投稿