/// <summary> /// この狩人が護衛したいエージェントを返す /// </summary> /// <returns>この狩人が護衛したいエージェント</returns> /// <remarks>nullは護衛なしを意味する</remarks> #else /// <summary> /// Returns the agent this bodyguard wants to guard. /// </summary> /// <returns>The agent this bodyguard wants to guard.</returns> /// <remarks>No guard in case of null.</remarks> #endif public override Agent Guard() { Agent candidate = null; // 前日の護衛が成功しているようなら同じエージェントを護衛 if (guardedAgent != null && Alive(guardedAgent) && CurrentGameInfo.LastDeadAgentList.Count == 0) { candidate = guardedAgent; } // 新しい護衛先の選定 else { // 占い師をカミングアウトしていて,かつ人狼候補になっていないエージェントを探す var candidates = AliveOthers.Where(a => GetCoRole(a) == Role.SEER && !werewolves.Contains(a)); // 見つからなければ霊媒師をカミングアウトしていて,かつ人狼候補になっていないエージェントを探す if (candidates.Count() == 0) { candidates = AliveOthers.Where(a => GetCoRole(a) == Role.MEDIUM && !werewolves.Contains(a)); } // それでも見つからなければ自分と人狼候補以外から護衛 if (candidates.Count() == 0) { candidates = AliveOthers.Where(a => a != Me && !werewolves.Contains(a)); } // それでもいなければ自分以外から護衛 if (candidates.Count() == 0) { candidates = AliveOthers; } // 護衛候補からランダムに護衛 candidate = candidates.Shuffle().First(); } guardedAgent = candidate; return(candidate); }
/// <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> /// <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 ChooseAttackVoteCandidate() { // カミングアウトした村人陣営は襲撃先候補 List <Agent> villagers = AliveOthers.Where(a => !werewolves.Contains(a) && a != possessed).ToList(); List <Agent> candidates = villagers.Where(a => IsCo(a)).ToList(); // 候補がいなければ村人陣営から if (candidates.Count() == 0) { candidates = villagers; } // 村人陣営がいない場合は裏切り者を襲う if (candidates.Count() == 0 && possessed != null) { candidates.Add(possessed); } if (candidates.Count() > 0) { if (!candidates.Contains(attackVoteCandidate)) { attackVoteCandidate = candidates.Shuffle().First(); } } else { attackVoteCandidate = null; } }
/// <summary> /// 偽判定を返す /// </summary> /// <param name="fakeRole">偽役職</param> /// <returns>偽判定結果</returns> Judge GetFakeJudge(Role fakeRole) { Agent target = null; // 占い師騙りの場合 if (fakeRole == Role.SEER) { target = AliveOthers.Where(a => !judgedAgents.Contains(a) && GetCoRole(a) != Role.SEER) .Shuffle().FirstOrDefault(); if (target == null) { target = AliveOthers.Shuffle().First(); } } // 霊媒師騙りの場合 else if (fakeRole == Role.MEDIUM) { target = CurrentGameInfo.ExecutedAgent; } if (target != null) { Species result = Species.HUMAN; // 人間が偽占い対象の場合 if (humans.Contains(target)) { // 偽人狼に余裕があれば if (fakeJudgeList.Where(j => j.Result == Species.WEREWOLF).Count() < numWolves) { // 裏切り者,あるいはまだカミングアウトしていないエージェントの場合,判定は五分五分 if ((target == possessed || !IsCo(target))) { if (new Random().NextDouble() < 0.5) { result = Species.WEREWOLF; } } // それ以外は人狼判定 else { result = Species.WEREWOLF; } } } return(new Judge(Day, Me, target, result)); } else { return(null); } }
/// <summary> /// 投票先候補を選ぶ /// </summary> /// <returns>投票先候補のエージェント</returns> protected override void ChooseVoteCandidate() { List <Agent> villagers = AliveOthers.Where(a => !werewolves.Contains(a) && a != possessed).ToList(); List <Agent> candidates = villagers; // 村人騙りの場合は村人陣営から if (fakeRole != Role.VILLAGER) // 占い師/霊媒師騙りの場合 { // 対抗カミングアウトしたエージェントは投票先候補 var rivals = villagers.Where(a => GetCoRole(a) == fakeRole); // 人狼と判定したエージェントは投票先候補 var fakeWolves = fakeJudgeList .Where(j => AliveOthers.Contains(j.Target) && j.Result == Species.WEREWOLF) .Select(j => j.Target).Distinct(); candidates = rivals.Concat(fakeWolves).ToList(); // 候補がいなければ人間と判定していない村人陣営から if (candidates.Count() == 0) { candidates = fakeJudgeList .Where(j => AliveOthers.Contains(j.Target) && j.Result != Species.HUMAN) .Select(j => j.Target).Distinct().ToList(); } } // 候補がいなければ村人陣営から if (candidates.Count() == 0) { candidates = villagers; } // 村人陣営がいない場合は裏切り者に投票 if (candidates.Count() == 0 && possessed != null) { candidates.Add(possessed); } if (candidates.Count() > 0) { if (!candidates.Contains(voteCandidate)) { voteCandidate = candidates.Shuffle().First(); // 以前の投票先から変わる場合,新たに推測発言 if (CanTalk) { TalkQueue.Enqueue(new Content(new EstimateContentBuilder(voteCandidate, Role.WEREWOLF))); } } } else { voteCandidate = null; } }
/// <summary> /// この占い師が占いたいエージェントを返す /// </summary> /// <returns>この占い師が占いたいエージェント</returns> /// <remarks>nullは占いなしを意味する</remarks> #else /// <summary> /// Returns the agent this seer wants to divine. /// </summary> /// <returns>The agent this seer wants to divine.</returns> /// <remarks>No divination in case of null.</remarks> #endif public override Agent Divine() { // 人狼候補がいればそれらからランダムに占う if (semiWolves.Count > 0) { return(semiWolves.Shuffle().First()); } // 人狼候補がいない場合,まだ占っていない生存者からランダムに占う List <Agent> candidates = AliveOthers.Where(a => !myDivinationMap.ContainsKey(a)).ToList(); if (candidates.Count == 0) { return(null); } return(candidates.Shuffle().First()); }
/// <summary> /// ゲーム開始時に呼ばれる /// </summary> /// <param name="gameInfo">最新のゲーム情報</param> /// <param name="gameSetting">ゲーム設定</param> #else /// <summary> /// Called when the game started. /// </summary> /// <param name="gameInfo">The current information of this game.</param> /// <param name="gameSetting">The setting of this game.</param> #endif public override void Initialize(GameInfo gameInfo, GameSetting gameSetting) { base.Initialize(gameInfo, gameSetting); numWolves = gameSetting.RoleNumMap[Role.WEREWOLF]; werewolves = gameInfo.RoleMap.Keys.ToList(); humans = AliveOthers.Where(a => !werewolves.Contains(a)).ToList(); // ランダムに騙る役職を決める fakeRole = new Role[] { Role.VILLAGER, Role.SEER, Role.MEDIUM }. Where(r => gameInfo.ExistingRoleList.Contains(r)).Shuffle().First(); WhisperQueue.Enqueue(new Content(new ComingoutContentBuilder(Me, fakeRole))); // 1~3日目からランダムにカミングアウトする comingoutDay = new int[] { 1, 2, 3 }.Shuffle().First(); // 第0~4ターンからランダムにカミングアウトする comingoutTurn = new int[] { 0, 1, 2, 3, 4 }.Shuffle().First(); isCameout = false; fakeJudgeList.Clear(); fakeJudgeQueue.Clear(); judgedAgents.Clear(); possessedList.Clear(); }
/// <summary> /// 偽占い結果を返す /// </summary> /// <returns>偽占い結果</returns> Judge GetFakeDivination() { Agent target = null; var candidates = AliveOthers.Where(a => !divinedAgents.Contains(a) && GetCoRole(a) != Role.SEER); if (candidates.Count() > 0) { target = candidates.Shuffle().First(); } else { target = AliveOthers.Shuffle().First(); } // 偽人狼に余裕があれば,人狼と人間の割合を勘案して,30%の確率で人狼と判定 Species result = Species.HUMAN; if (fakeDivinationList.Where(j => j.Result == Species.WEREWOLF).Count() < numWolves && new Random().NextDouble() < 0.3) { result = Species.WEREWOLF; } return(new Judge(Day, Me, target, result)); }
/// <summary> /// 投票先候補を選ぶ /// </summary> /// <returns>投票先候補のエージェント</returns> protected override void ChooseVoteCandidate() { // 生存人狼がいれば当然投票 var aliveWolves = blackList.Where(a => Alive(a)); if (aliveWolves.Count() > 0) { // 既定の投票先が生存人狼でない場合投票先を変える if (!aliveWolves.Contains(voteCandidate)) { voteCandidate = aliveWolves.Shuffle().First(); if (CanTalk) { TalkQueue.Enqueue(new Content(new RequestContentBuilder(null, new Content(new VoteContentBuilder(voteCandidate))))); } } return; } // 確定人狼がいない場合は推測する // 偽占い師 var fakeSeers = AliveOthers.Where(a => GetCoRole(a) == Role.SEER); // 偽霊媒師 var fakeMediums = IdentList.Where(j => myDivinationMap.ContainsKey(j.Target) && j.Result != myDivinationMap[j.Target]).Select(j => j.Agent); var candidates = fakeSeers.Concat(fakeMediums).Where(a => Alive(a)).Distinct(); // 人狼候補なのに人間⇒裏切り者 foreach (Agent possessed in candidates.Where(a => whiteList.Contains(a))) { if (!possessedList.Contains(possessed)) { TalkQueue.Enqueue(new Content(new EstimateContentBuilder(possessed, Role.POSSESSED))); possessedList.Add(possessed); } } semiWolves = candidates.Where(a => !whiteList.Contains(a)).ToList(); if (semiWolves.Count() > 0) { if (!semiWolves.Contains(voteCandidate)) { voteCandidate = semiWolves.Shuffle().First(); // 以前の投票先から変わる場合,新たに推測発言をする if (CanTalk) { TalkQueue.Enqueue(new Content(new EstimateContentBuilder(voteCandidate, Role.WEREWOLF))); } } } else { // 人狼候補がいない場合はグレイからランダム if (grayList.Count != 0) { if (!grayList.Contains(voteCandidate)) { voteCandidate = grayList.Shuffle().First(); } } // グレイがいない場合ランダム else { if (!AliveOthers.Contains(voteCandidate)) { voteCandidate = AliveOthers.Shuffle().First(); } } } }