Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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();
                }
            }
        }
Exemplo n.º 3
0
        /// <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();
                }
            }
        }
Exemplo n.º 4
0
        /// <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;
            }
        }
Exemplo n.º 5
0
        /// <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)))));
                }
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// エージェントを殺されたエージェントのリストに追加する
 /// </summary>
 void AddKilledAgent(Agent killedAgent)
 {
     if (killedAgent != null)
     {
         AliveOthers.Remove(killedAgent);
         if (!KilledAgents.Contains(killedAgent))
         {
             KilledAgents.Add(killedAgent);
         }
     }
 }
Exemplo n.º 7
0
 /// <summary>
 /// エージェントを追放されたエージェントのリストに追加する
 /// </summary>
 void AddExecutedAgent(Agent executedAgent)
 {
     if (executedAgent != null)
     {
         AliveOthers.Remove(executedAgent);
         if (!ExecutedAgents.Contains(executedAgent))
         {
             ExecutedAgents.Add(executedAgent);
         }
     }
 }
Exemplo n.º 8
0
        /// <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);
            }
        }
Exemplo n.º 9
0
        /// <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;
            }
        }
Exemplo n.º 10
0
        /// <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());
        }
Exemplo n.º 11
0
        /// <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();
        }
Exemplo n.º 12
0
        /// <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));
        }
Exemplo n.º 13
0
        /// <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();
                    }
                }
            }
        }
Exemplo n.º 14
0
        /// <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;
        }