/// <summary> /// 投票先候補を選ぶ /// </summary> /// <returns>投票先候補のエージェント</returns> protected override void ChooseVoteCandidate() { // 霊媒師をカミングアウトしている他のエージェントは人狼候補 var fakeMediums = AliveOthers.Where(a => GetCoRole(a) == Role.MEDIUM); // 自分や殺されたエージェントを人狼と判定,あるいは自分と異なる判定の占い師は人狼候補 var fakeSeers = DivinationList .Where(j => (j.Result == Species.WEREWOLF && (j.Target == Me || Killed(j.Target))) || (myIdentMap.ContainsKey(j.Target) && j.Result != myIdentMap[j.Target])).Select(j => j.Agent); var candidates = fakeMediums.Concat(fakeSeers).Where(a => Alive(a)).Distinct(); if (candidates.Count() > 0) { if (!candidates.Contains(voteCandidate)) { voteCandidate = candidates.Shuffle().First(); // 以前の投票先から変わる場合,新たに推測発言と占い要請をする if (CanTalk) { TalkQueue.Enqueue(new Content(new EstimateContentBuilder(voteCandidate, Role.WEREWOLF))); TalkQueue.Enqueue(new Content(new RequestContentBuilder(null, new Content(new DivinationContentBuilder(voteCandidate))))); } } } // 人狼候補がいない場合はランダム else { if (!AliveOthers.Contains(voteCandidate)) { voteCandidate = AliveOthers.Shuffle().First(); } } }
/// <summary> /// 投票先候補を選ぶ /// </summary> /// <returns>投票先候補のエージェント</returns> protected override void ChooseVoteCandidate() { // 自分や殺されたエージェントを人狼と判定していて,生存している占い師を投票先候補とする var candidates = DivinationList .Where(j => j.Result == Species.WEREWOLF && (j.Target == Me || Killed(j.Target)) && Alive(j.Agent)) .Select(j => j.Agent).Distinct(); if (candidates.Count() > 0) { if (!candidates.Contains(voteCandidate)) { voteCandidate = candidates.Shuffle().First(); // 以前の投票先から変わる場合,新たに推測発言と占い要請をする if (CanTalk) { TalkQueue.Enqueue(new Content(new EstimateContentBuilder(voteCandidate, Role.WEREWOLF))); TalkQueue.Enqueue(new Content(new RequestContentBuilder(null, new Content(new DivinationContentBuilder(voteCandidate))))); } } } // 人狼候補がいない場合はランダム else { if (!AliveOthers.Contains(voteCandidate)) { voteCandidate = AliveOthers.Shuffle().First(); } } }
/// <summary> /// 投票先候補を選ぶ /// </summary> /// <returns>投票先候補のエージェント</returns> protected override void ChooseVoteCandidate() { // 自分や殺されたエージェントを人狼と判定していて,生存している占い師は人狼候補 var werewolves = DivinationList .Where(j => j.Result == Species.WEREWOLF && (j.Target == Me || Killed(j.Target))).Select(j => j.Agent); // 対抗カミングアウトのエージェントは投票先候補 var rivals = AliveOthers.Where(a => !werewolves.Contains(a) && GetCoRole(a) == Role.SEER); // 人狼と判定したエージェントは投票先候補 var fakeHumans = fakeDivinationQueue.Where(j => j.Result == Species.HUMAN).Select(j => j.Target).Distinct(); var fakeWerewolves = fakeDivinationQueue.Where(j => j.Result == Species.WEREWOLF).Select(j => j.Target).Distinct(); var candidates = rivals.Concat(fakeWerewolves).Distinct(); // 候補がいなければ人間と判定していない村人陣営から if (candidates.Count() == 0) { candidates = AliveOthers.Where(a => !werewolves.Contains(a) && !fakeHumans.Contains(a)); // それでも候補がいなければ村人陣営から if (candidates.Count() == 0) { candidates = AliveOthers.Where(a => !werewolves.Contains(a)); } } if (!candidates.Contains(voteCandidate)) { voteCandidate = candidates.Shuffle().First(); // 以前の投票先から変わる場合,新たに推測発言と占い要請をする if (CanTalk) { TalkQueue.Enqueue(new Content(new EstimateContentBuilder(voteCandidate, Role.WEREWOLF))); TalkQueue.Enqueue(new Content(new RequestContentBuilder(null, new Content(new DivinationContentBuilder(voteCandidate))))); } } }
/// <summary> /// ゲーム開始時に呼ばれる /// </summary> /// <param name="gameInfo">最新のゲーム情報</param> /// <param name="gameSetting">ゲーム設定</param> public virtual void Initialize(GameInfo gameInfo, GameSetting gameSetting) { Day = -1; Me = gameInfo.Agent; AliveOthers = gameInfo.AliveAgentList.Where(a => a != Me).ToList(); ExecutedAgents.Clear(); KilledAgents.Clear(); DivinationList.Clear(); IdentList.Clear(); comingoutMap.Clear(); }
/// <summary> /// ゲーム情報更新の際に呼ばれる /// </summary> /// <param name="gameInfo">最新のゲーム情報</param> #else /// <summary> /// Called when the game information is updated. /// </summary> /// <param name="gameInfo">The current information of this game.</param> #endif public override void Update(GameInfo gameInfo) { base.Update(gameInfo); // 占い/霊媒結果が嘘の場合,裏切り者候補 possessed = DivinationList.Concat(IdentList) .Where(j => !werewolves.Contains(j.Agent) && ((humans.Contains(j.Target) && j.Result == Species.WEREWOLF) || (werewolves.Contains(j.Target) && j.Result == Species.HUMAN))) .Select(j => j.Agent).Distinct().Shuffle().FirstOrDefault(); if (possessed != null && !possessedList.Contains(possessed)) { possessedList.Add(possessed); WhisperQueue.Enqueue(new Content(new EstimateContentBuilder(possessed, Role.POSSESSED))); } }
/// <summary> /// ゲーム情報更新の際に呼ばれる /// </summary> /// <param name="gameInfo">最新のゲーム情報</param> public virtual void Update(GameInfo gameInfo) { CurrentGameInfo = gameInfo; // 1日の最初の呼び出しはDayStart()の前なので何もしない if (CurrentGameInfo.Day == Day + 1) { Day = gameInfo.Day; return; } // 2回目の呼び出し以降 // (夜フェーズ限定)追放されたエージェントを登録 AddExecutedAgent(CurrentGameInfo.LatestExecutedAgent); // GameInfo.TalkListからカミングアウト,占い報告,霊媒報告,推定を抽出 for (int i = talkListHead; i < CurrentGameInfo.TalkList.Count; i++) { Talk talk = CurrentGameInfo.TalkList[i]; Agent talker = talk.Agent; if (talker == Me) { continue; } Content content = new Content(talk.Text); switch (content.Topic) { case Topic.COMINGOUT: SetCoRole(talker, content.Role); break; case Topic.DIVINED: DivinationList.Add(new Judge(Day, talker, content.Target, content.Result)); break; case Topic.IDENTIFIED: IdentList.Add(new Judge(Day, talker, content.Target, content.Result)); break; default: break; } } talkListHead = CurrentGameInfo.TalkList.Count; }
/// <summary> /// Update AdditionalGameinfo. /// </summary> /// <param name="gameInfo">Game information.</param> public void Update(GameInfo gameInfo) { // 1日の最初の呼び出しではその日の初期化などを行う if (gameInfo.Day != day) { day = gameInfo.Day; talkListHead = 0; AddExecutedAgent(gameInfo.ExecutedAgent); // 前日に追放されたエージェントを登録 if (gameInfo.LastDeadAgentList.Count != 0) { LastKilledAgent = gameInfo.LastDeadAgentList[0]; // 妖狐がいないので長さ最大1 } if (LastKilledAgent != null) { if (!KilledAgents.Contains(LastKilledAgent)) { KilledAgents.Add(LastKilledAgent); } AliveOthers.Remove(LastKilledAgent); } } // (夜フェーズ限定)追放されたエージェントを登録 AddExecutedAgent(gameInfo.LatestExecutedAgent); // talkListからカミングアウト,占い結果,霊媒結果を抽出 for (int i = talkListHead; i < gameInfo.TalkList.Count; i++) { Talk talk = gameInfo.TalkList[i]; Agent talker = talk.Agent; Content content = new Content(talk.Text); Agent target = content.Target; switch (content.Topic) { case Topic.COMINGOUT: ComingoutMap[talker] = content.Role; break; case Topic.DIVINED: DivinationList.Add(new Judge(day, talker, content.Target, content.Result)); break; case Topic.IDENTIFIED: IdentList.Add(new Judge(day, talker, target, content.Result)); break; case Topic.ESTIMATE: if (target != null) { if (EstimateMap[target] == null) { EstimateMap[target] = new List <Talk>(); } EstimateMap[target].Add(talk); } break; default: break; } } talkListHead = gameInfo.TalkList.Count; }