public override CardUseStruct AskForUseCard(string pattern, string prompt, FunctionCard.HandlingMethod method)
        {
            const string rx_pattern = @"@?@?([_A-Za-z]+)(\d+)?!?";

            if (!string.IsNullOrEmpty(pattern) && pattern.StartsWith("@"))
            {
                Match result = Regex.Match(pattern, rx_pattern);
                if (result.Length > 0)
                {
                    string  skill_name = result.Groups[1].ToString();
                    UseCard card       = Engine.GetCardUsage(skill_name);
                    if (card != null)
                    {
                        CardUseStruct use = card.OnResponding(this, self, pattern, prompt, method);
                        return(use);
                    }

                    SkillEvent skill = Engine.GetSkillEvent(skill_name);
                    if (skill != null)
                    {
                        CardUseStruct use = skill.OnResponding(this, self, pattern, prompt, method);
                        return(use);
                    }
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(room.GetRoomState().GetCurrentResponseSkill()))
                {
                    string  skill_name = room.GetRoomState().GetCurrentResponseSkill();
                    UseCard card       = Engine.GetCardUsage(skill_name);
                    if (card != null)
                    {
                        CardUseStruct use = card.OnResponding(this, self, pattern, prompt, method);
                        return(use);
                    }

                    SkillEvent skill = Engine.GetSkillEvent(skill_name);
                    if (skill != null)
                    {
                        CardUseStruct use = skill.OnResponding(this, self, pattern, prompt, method);
                        return(use);
                    }
                }

                foreach (string key in prompt_keys.Keys)
                {
                    if (prompt.StartsWith(key))
                    {
                        string  skill_name = prompt_keys[key];
                        UseCard card       = Engine.GetCardUsage(skill_name);
                        if (card != null)
                        {
                            CardUseStruct use = card.OnResponding(this, self, pattern, prompt, method);
                            return(use);
                        }

                        SkillEvent skill = Engine.GetSkillEvent(skill_name);
                        if (skill != null)
                        {
                            CardUseStruct use = skill.OnResponding(this, self, pattern, prompt, method);
                            return(use);
                        }
                    }
                }
            }

            return(base.AskForUseCard(pattern, prompt, method));
        }
        public override string AskForChoice(string skill_name, string choice, object data)
        {
            bool trigger_skill = false;

            if (skill_name == "GameRule:TurnStart")
            {
                string[]      choices     = choice.Split('+');
                List <string> new_choices = new List <string>();
                foreach (string cho in choices)
                {
                    if (!cho.Contains("GameRule_AskForGeneralShow") && cho != "cancel")
                    {
                        trigger_skill = true;
                        new_choices.Add(cho);
                    }
                }
                if (trigger_skill)
                {
                    choice = string.Join("+", new_choices);
                }
            }

            if (skill_name == "GameRule:TriggerOrder" || trigger_skill)
            {
                if (choice.Contains("qianxi"))
                {
                    return("qianxi");
                }
                if (choice.Contains("duanbing"))
                {
                    return("duanbing");
                }
                if (choice.Contains("jieming"))
                {
                    return("jieming");
                }
                if (choice.Contains("fankui") && choice.Contains("ganglie"))
                {
                    return("fankui");
                }
                if (choice.Contains("fangzhu") && data is DamageStruct damage)
                {
                    Player from = damage.From;
                    if (choice.Contains("wangxi"))
                    {
                        if (from != null && from.IsNude())
                        {
                            return("wangxi");
                        }
                    }

                    if (choice.Contains("fankui"))
                    {
                        if (from != null && from == Self && HasArmorEffect(Self, SilverLion.ClassName))
                        {
                            bool friend = false;
                            foreach (Player p in FriendNoSelf)
                            {
                                if (!p.FaceUp)
                                {
                                    friend = true;
                                    break;
                                }
                            }
                            if (!friend)
                            {
                                return("fankui");
                            }
                        }
                    }

                    return("fangzhu");
                }

                if (choice.Contains("wangxi") && choice.Contains("ganglie"))
                {
                    return("ganglie");
                }
                if (choice.Contains("jiangxiong"))
                {
                    return("jianxiong");
                }

                if (choice.Contains("qianxi") && choice.Contains("guanxing"))
                {
                    if (self.JudgingArea.Count > 0 && room.AliveCount() <= 4)
                    {
                        return("qianxi");
                    }
                    return("guanxing");
                }

                if (choice.Contains("tiandu") && data is JudgeStruct judge)
                {
                    int id = judge.Card.Id;
                    if (IsCard(id, Peach.ClassName, self) || IsCard(id, Analeptic.ClassName, Self))
                    {
                        return("tiandu");
                    }
                }
                if (choice.Contains("yiji"))
                {
                    return("yiji");
                }
                if (choice.Contains("hunshang"))
                {
                    return("hunshang");
                }
                if (choice.Contains("yinghun_sunjian"))
                {
                    return("yinghun_sunjian");
                }
                if (choice.Contains("yinghun_sunce"))
                {
                    return("yinghun_sunce");
                }
                if (choice.Contains("yingzi_zhouyu"))
                {
                    return("yingzi_zhouyu");
                }
                if (choice.Contains("yingzi_sunce"))
                {
                    return("yingzi_sunce");
                }
                if (choice.Contains("yingziextra"))
                {
                    return("yingziextra");
                }
                if (choice.Contains("jieyue"))
                {
                    return("jieyue");
                }
                if (choice.Contains("tianxiang"))
                {
                    return("tianxiang");
                }
                string[] skillnames = choice.Split('+');
                return(skillnames[0]);
            }

            if (skill_name == HegNullification.ClassName)
            {
                if (!string.IsNullOrEmpty(Choice[HegNullification.ClassName]))
                {
                    return(Choice[HegNullification.ClassName]);
                }

                return("single");
            }

            UseCard card = Engine.GetCardUsage(skill_name);

            if (card != null)
            {
                return(card.OnChoice(this, self, choice, data));
            }

            SkillEvent skill = Engine.GetSkillEvent(skill_name);

            if (skill != null)
            {
                return(skill.OnChoice(this, self, choice, data));
            }

            return(base.AskForChoice(skill_name, choice, data));
        }
        public override List <Player> OnPlayerChosen(TrustedAI ai, Player player, List <Player> targets, int min, int max)
        {
            Room room = ai.Room;

            if (room.GetTag("extra_target_skill") is CardUseStruct use)
            {
                List <Player> result = new List <Player>();
                if (use.Card.Name == ExNihilo.ClassName)
                {
                    foreach (Player p in targets)
                    {
                        if (ai.IsFriend(p) && !ai.HasSkill("zishu", p))
                        {
                            return new List <Player> {
                                       p
                            }
                        }
                    }
                    ;
                }
                else if (use.Card.Name.Contains(Slash.ClassName))
                {
                    List <ScoreStruct> scores = ai.CaculateSlashIncome(player, new List <WrappedCard> {
                        use.Card
                    }, targets, false);
                    if (scores.Count > 0 && scores[0].Score > 0)
                    {
                        return(scores[0].Players);
                    }
                }
                else if (use.Card.Name == Snatch.ClassName)
                {
                    foreach (Player p in targets)
                    {
                        if (ai.FindCards2Discard(player, p, use.Card.Name, "hej", HandlingMethod.MethodGet).Score > 0)
                        {
                            return new List <Player> {
                                       p
                            }
                        }
                        ;
                    }
                }
                else if (use.Card.Name == Dismantlement.ClassName)
                {
                    foreach (Player p in targets)
                    {
                        if (ai.FindCards2Discard(player, p, use.Card.Name, "hej", HandlingMethod.MethodDiscard).Score > 0)
                        {
                            return new List <Player> {
                                       p
                            }
                        }
                        ;
                    }
                }
                else if (use.Card.Name == IronChain.ClassName)
                {
                    foreach (Player p in targets)
                    {
                        if (ai.IsFriend(p) && !ai.HasSkill("jieying", p) && p.Chained)
                        {
                            return new List <Player> {
                                       p
                            }
                        }
                        ;
                    }
                    foreach (Player p in targets)
                    {
                        if (ai.IsEnemy(p) && !p.Chained)
                        {
                            return new List <Player> {
                                       p
                            }
                        }
                        ;
                    }
                }
                else if (use.Card.Name == FireAttack.ClassName)
                {
                    foreach (Player p in targets)
                    {
                        if (ai.IsEnemy(p))
                        {
                            return new List <Player> {
                                       p
                            }
                        }
                        ;
                    }
                }
                else if (use.Card.Name == Duel.ClassName)
                {
                    WrappedCard   duel    = use.Card;
                    List <Player> enemies = ai.Exclude(ai.GetEnemies(player), duel);
                    List <Player> friends = ai.Exclude(ai.FriendNoSelf, duel);
                    int           n1      = ai.GetKnownCardsNums(Slash.ClassName, "he", player);

                    if (ai.HasSkill("wushuang"))
                    {
                        n1 *= 2;
                    }
                    List <ScoreStruct> scores = new List <ScoreStruct>();
                    foreach (Player p in friends)
                    {
                        if (!targets.Contains(p))
                        {
                            continue;
                        }
                        bool fuyin = false;
                        if (ai.HasSkill("fuyin", p) && p.GetMark("fuyin") == 0)
                        {
                            int count = player.HandcardNum;
                            if (count > p.HandcardNum)
                            {
                                fuyin = true;
                            }
                        }
                        if (!fuyin)
                        {
                            ScoreStruct score = ai.GetDamageScore(new DamageStruct(duel, player, p));
                            score.Players = new List <Player> {
                                p
                            };
                            foreach (string skill in ai.GetKnownSkills(p))
                            {
                                SkillEvent skill_e = Engine.GetSkillEvent(skill);
                                if (skill_e != null)
                                {
                                    score.Score += skill_e.TargetValueAdjust(ai, duel, player, new List <Player> {
                                        p
                                    }, p);
                                }
                            }
                            scores.Add(score);
                        }
                    }
                    foreach (Player p in enemies)
                    {
                        if (!targets.Contains(p))
                        {
                            continue;
                        }
                        bool fuyin = false;
                        if (ai.HasSkill("fuyin", p) && p.GetMark("fuyin") == 0)
                        {
                            int count = player.HandcardNum;
                            foreach (int id in duel.SubCards)
                            {
                                if (room.GetCardPlace(id) == Place.PlaceHand)
                                {
                                    count--;
                                }
                            }

                            if (count > p.HandcardNum)
                            {
                                ScoreStruct score = new ScoreStruct
                                {
                                    Score   = 1,
                                    Players = new List <Player> {
                                        p
                                    }
                                };
                                scores.Add(score);
                                fuyin = true;
                            }
                        }

                        if (!fuyin)
                        {
                            bool   no_red   = p.GetMark("@qianxi_red") > 0;
                            bool   no_black = p.GetMark("@qianxi_black") > 0;
                            double n2       = ai.GetKnownCardsNums(Slash.ClassName, "he", p, player);

                            bool fuqi = false;
                            if (player.ContainsTag("wenji") && player.GetTag("wenji") is List <string> names && names.Contains(Name))
                            {
                                fuqi = true;
                            }
                            if (ai.HasSkill("fuqi", player) && RoomLogic.DistanceTo(room, player, p) == 1)
                            {
                                fuqi = true;
                            }

                            if (!fuqi && !ai.IsLackCard(p, Slash.ClassName))
                            {
                                int rate = 4;
                                if (ai.GetKnownCards(p).Count != p.HandcardNum)
                                {
                                    rate = 5;
                                    if (ai.HasSkill("longdan", p))
                                    {
                                        rate -= 2;
                                        if (no_black || no_red)
                                        {
                                            rate += 1;
                                        }
                                    }
                                    if (ai.HasSkill("wusheng", p) && !no_red)
                                    {
                                        rate -= 2;
                                    }
                                    int count = p.HandcardNum - ai.GetKnownCards(p).Count;
                                    count += p.GetHandPile(true).Count - ai.GetKnownHandPileCards(p).Count;
                                    if (no_red)
                                    {
                                        rate += 1;
                                    }
                                    if (no_black)
                                    {
                                        rate += 2;
                                    }
                                    n2 += ((double)count / rate);
                                }
                                if (ai.HasSkill("wushuang", p))
                                {
                                    n2 *= 2;
                                }
                            }
                            ScoreStruct score = new ScoreStruct
                            {
                                Players = new List <Player> {
                                    p
                                }
                            };
                            if (fuqi)
                            {
                                score.Score = ai.GetDamageScore(new DamageStruct(duel, player, p)).Score;
                            }
                            else if (n2 > n1)
                            {
                                score.Score = ai.GetDamageScore(new DamageStruct(duel, p, player)).Score;
                            }
                            else
                            {
                                score.Score = ai.GetDamageScore(new DamageStruct(duel, p, player)).Score - (n2 - 1) * 0.4;
                            }

                            foreach (string skill in ai.GetKnownSkills(p))
                            {
                                SkillEvent skill_e = Engine.GetSkillEvent(skill);
                                if (skill_e != null)
                                {
                                    score.Score += skill_e.TargetValueAdjust(ai, duel, player, new List <Player> {
                                        p
                                    }, p);
                                }
                            }
                            scores.Add(score);
                        }
                    }
                    if (scores.Count > 0)
                    {
                        scores.Sort((x, y) => { return(x.Score > y.Score ? -1 : 1); });
                        if (scores[0].Score > 1)
                        {
                            return(scores[0].Players);
                        }
                    }
                }
            }
            return(new List <Player>());
        }