예제 #1
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();
                }
            }
        }
예제 #2
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();
                }
            }
        }
예제 #3
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)))));
                }
            }
        }
예제 #4
0
 /// <summary>
 /// プレイヤーの発言を返す
 /// </summary>
 /// <returns>発話文字列</returns>
 public virtual string Talk()
 {
     ChooseVoteCandidate();
     if (voteCandidate != null && voteCandidate != declaredVoteCandidate)
     {
         TalkQueue.Enqueue(new Content(new VoteContentBuilder(voteCandidate)));
         declaredVoteCandidate = voteCandidate;
     }
     return(TalkQueue.Count > 0 ? TalkQueue.Dequeue().Text : Utterance.SKIP);
 }
예제 #5
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;
            }
        }
예제 #6
0
        /// <summary>
        /// プレイヤーの発言を返す
        /// </summary>
        /// <returns>発言の文字列</returns>
        /// <remarks>
        /// nullはSkipを意味する
        /// </remarks>
#else
        /// <summary>
        /// Returns this player's talk.
        /// </summary>
        /// <returns>The string representing this player's talk.</returns>
        /// <remarks>
        /// Null means Skip.
        /// </remarks>
#endif
        public override string Talk()
        {
            talkTurn++;
            if (fakeRole != Role.VILLAGER)
            {
                if (!isCameout)
                {
                    // 他の人狼のカミングアウト状況を調べて騙る役職が重複しないようにする
                    int fakeSeerCO   = werewolves.Where(a => a != Me && GetCoRole(a) == Role.SEER).Count();
                    int fakeMediumCO = werewolves.Where(a => a != Me && GetCoRole(a) == Role.MEDIUM).Count();
                    if ((fakeRole == Role.SEER && fakeSeerCO > 0) || (fakeRole == Role.MEDIUM && fakeMediumCO > 0))
                    {
                        fakeRole = Role.VILLAGER; // 潜伏
                        WhisperQueue.Enqueue(new Content(new ComingoutContentBuilder(Me, Role.VILLAGER)));
                    }
                    else
                    {
                        // 対抗カミングアウトがある場合,今日カミングアウトする
                        if (humans.Where(a => GetCoRole(a) == fakeRole).Count() > 0)
                        {
                            comingoutDay = Day;
                        }
                        // カミングアウトするタイミングになったらカミングアウト
                        if (Day >= comingoutDay && talkTurn >= comingoutTurn)
                        {
                            isCameout = true;
                            TalkQueue.Enqueue(new Content(new ComingoutContentBuilder(Me, fakeRole)));
                        }
                    }
                }
                // カミングアウトしたらこれまでの偽判定結果をすべて公開
                else
                {
                    while (fakeJudgeQueue.Count > 0)
                    {
                        Judge judge = fakeJudgeQueue.Dequeue();
                        if (fakeRole == Role.SEER)
                        {
                            TalkQueue.Enqueue(new Content(new DivinedResultContentBuilder(judge.Target, judge.Result)));
                        }
                        else if (fakeRole == Role.MEDIUM)
                        {
                            TalkQueue.Enqueue(new Content(new IdentContentBuilder(judge.Target, judge.Result)));
                        }
                    }
                }
            }
            return(base.Talk());
        }
예제 #7
0
        /// <summary>
        /// プレイヤーの発言を返す
        /// </summary>
        /// <returns>発言の文字列</returns>
        /// <remarks>
        /// nullはSkipを意味する
        /// </remarks>
#else
        /// <summary>
        /// Returns this player's talk.
        /// </summary>
        /// <returns>The string representing this player's talk.</returns>
        /// <remarks>
        /// Null means Skip.
        /// </remarks>
#endif
        public override string Talk()
        {
            // 即占い師カミングアウト
            if (!isCameout)
            {
                TalkQueue.Enqueue(new Content(new ComingoutContentBuilder(Me, Role.SEER)));
                isCameout = true;
            }
            // カミングアウトしたらこれまでの偽判定結果をすべて公開
            if (isCameout)
            {
                while (fakeDivinationQueue.Count > 0)
                {
                    Judge judge = fakeDivinationQueue.Dequeue();
                    TalkQueue.Enqueue(new Content(new DivinedResultContentBuilder(judge.Target, judge.Result)));
                }
            }
            return(base.Talk());
        }
예제 #8
0
        /// <summary>
        /// プレイヤーの発言を返す
        /// </summary>
        /// <returns>発言の文字列</returns>
        /// <remarks>
        /// nullはSkipを意味する
        /// </remarks>
#else
        /// <summary>
        /// Returns this player's talk.
        /// </summary>
        /// <returns>The string representing this player's talk.</returns>
        /// <remarks>
        /// Null means Skip.
        /// </remarks>
#endif
        public override string Talk()
        {
            // カミングアウトする日になったら,あるいは占い結果が人狼だったら
            // あるいは占い師カミングアウトが出たらカミングアウト
            if (!isCameout && (Day >= comingoutDay ||
                               (divinationQueue.Count > 0 && divinationQueue.Peek().Result == Species.WEREWOLF) ||
                               IsCo(Role.SEER)))
            {
                TalkQueue.Enqueue(new Content(new ComingoutContentBuilder(Me, Role.SEER)));
                isCameout = true;
            }
            // カミングアウトしたらこれまでの占い結果をすべて公開
            if (isCameout)
            {
                while (divinationQueue.Count > 0)
                {
                    Judge divination = divinationQueue.Dequeue();
                    TalkQueue.Enqueue(new Content(new DivinedResultContentBuilder(divination.Target, divination.Result)));
                }
            }
            return(base.Talk());
        }
예제 #9
0
        /// <summary>
        /// プレイヤーの発言を返す
        /// </summary>
        /// <returns>発言の文字列</returns>
        /// <remarks>
        /// nullはSkipを意味する
        /// </remarks>
#else
        /// <summary>
        /// Returns this player's talk.
        /// </summary>
        /// <returns>The string representing this player's talk.</returns>
        /// <remarks>
        /// Null means Skip.
        /// </remarks>
#endif
        public override string Talk()
        {
            // カミングアウトする日になったら,あるいは霊媒結果が人狼だったら
            // あるいは霊媒師カミングアウトが出たらカミングアウト
            if (!isCameout && (Day >= comingoutDay ||
                               (identQueue.Count > 0 && identQueue.Peek().Result == Species.WEREWOLF) ||
                               IsCo(Role.MEDIUM)))
            {
                TalkQueue.Enqueue(new Content(new ComingoutContentBuilder(Me, Role.MEDIUM)));
                isCameout = true;
            }
            // カミングアウトしたらこれまでの霊媒結果をすべて公開
            if (isCameout)
            {
                while (identQueue.Count > 0)
                {
                    Judge ident = identQueue.Dequeue();
                    TalkQueue.Enqueue(new Content(new IdentContentBuilder(ident.Target, ident.Result)));
                }
            }
            return(base.Talk());
        }
예제 #10
0
 /// <summary>
 /// 新しい日が始まるときに呼ばれる
 /// </summary>
 public virtual void DayStart()
 {
     CanTalk    = true;
     CanWhisper = false;
     if (CurrentGameInfo.Role == Role.WEREWOLF)
     {
         CanWhisper = true;
     }
     TalkQueue.Clear();
     WhisperQueue.Clear();
     declaredVoteCandidate       = null;
     voteCandidate               = null;
     declaredAttackVoteCandidate = null;
     attackVoteCandidate         = null;
     talkListHead = 0;
     // 前日に追放されたエージェントを登録
     AddExecutedAgent(CurrentGameInfo.ExecutedAgent);
     // 昨夜に死亡した(襲撃された)エージェントを登録
     if (CurrentGameInfo.LastDeadAgentList.Count > 0)
     {
         AddKilledAgent(CurrentGameInfo.LastDeadAgentList[0]);
     }
 }
예제 #11
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();
                    }
                }
            }
        }