示例#1
0
        public static void Format(BgoGame game, String html)
        {
            //如果当前是EventResolve,那么没有CardRow
            if (game.CurrentPhase == TtaPhase.EventResolution)
            {
                game.PossibleActions.RemoveAll(a => a.ActionType == PlayerActionType.TakeCardFromCardRow);

                var mc   = BgoRegexpCollections.ExtractResolveingEvent.Match(html);
                var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), mc.Groups[2].Value), mc.Groups[1].Value);

                foreach (
                    var action in
                    game.PossibleActions.Where(action => action.ActionType == PlayerActionType.Unknown).ToList())
                {
                    String bgoStr   = action.Data[0].ToString();
                    String optValue = action.Data[1].ToString();

                    if (bgoStr == "----- Select an action -----")
                    {
                        continue;
                    }

                    action.ActionType = PlayerActionType.ResolveEventOption;

                    //获得CurrentActionCard
                    action.Data[0] = card;
                    action.Data[1] = bgoStr;
                    action.Data[2] = optValue;
                }
            }

            //Unknown的话
            //Data[0]是opt的显示内容,就是文本
            //Data[1]是optValue(要传给后端的)

            foreach (
                var action in
                game.PossibleActions.Where(action => action.ActionType == PlayerActionType.Unknown).ToList())
            {
                String bgoStr   = action.Data[0].ToString();
                String optValue = action.Data[1].ToString();

                if (bgoStr.StartsWith("Increase"))
                {
                    int foodCost = Convert.ToInt32(bgoStr.CutBetween("(", "F)"));
                    action.ActionType = PlayerActionType.IncreasePopulation;
                    action.Data[0]    = bgoStr;
                    action.Data[1]    = foodCost;
                    action.Data[2]    = optValue;
                }
                else if (bgoStr.StartsWith("Build"))
                {
                    //Build关键字的出现可能有多种情况。包括
                    //Build Iron (5R)
                    //Build free temple/Build free warrior.
                    //Build 1 stage of Library of Alexandria (1R)
                    //Build 4 stages of Library of Alexandria (1R)
                    if (bgoStr.IndexOf("stage", StringComparison.Ordinal) == 8 ||
                        bgoStr.IndexOf("stages", StringComparison.Ordinal) == 8)
                    {
                        //var keyword = bgoStr.Contains("stages") ? "stages" : "stage";
                        //Build X stage of Y (XR)
                        var resCost    = Convert.ToInt32(bgoStr.CutBetween("(", "R)"));
                        var stageCount = Convert.ToInt32(bgoStr.CutBetween("Build ", " stage"));

                        var wonderName = bgoStr.CutBetween("of ", " (");
                        action.ActionType = PlayerActionType.BuildWonder;
                        action.Data[0]    = Civilopedia.GetCardInfoByName(wonderName);
                        action.Data[1]    = stageCount;
                        action.Data[2]    = resCost;
                        action.Data[3]    = optValue;
                    }
                    else if (bgoStr.Contains("("))
                    {
                        //Building
                        String cardName = bgoStr.CutBetween("Build ", " (");
                        int    resCost  = Convert.ToInt32(bgoStr.CutBetween("(", "R)"));
                        action.ActionType = PlayerActionType.BuildBuilding;
                        action.Data[0]    = Civilopedia.GetCardInfoByName(cardName);
                        action.Data[1]    = resCost;
                        action.Data[2]    = optValue;
                    }
                    else
                    {
                        //以Build开头的其他无意义选项
                    }
                }
                else if (bgoStr.StartsWith("Upgrade"))
                {
                    //Upgrade Agriculture -> Irrigation (2R)
                    var card1   = bgoStr.CutBetween("Upgrade ", " ->");
                    var card2   = bgoStr.CutBetween("> ", " (");
                    var resCost = bgoStr.CutBetween("(", "R)");

                    action.ActionType = PlayerActionType.UpgradeBuilding;
                    action.Data[0]    = Civilopedia.GetCardInfoByName(card1);
                    action.Data[1]    = Civilopedia.GetCardInfoByName(card2);
                    action.Data[2]    = resCost;
                    action.Data[3]    = optValue;
                }
                else if (bgoStr.StartsWith("Play"))
                {
                    //Play关键字的出现可能有多种情况。包括
                    //Play A / Rich Land
                    //Play event Pestilence
                    //Play event Developed Territory II
                    if (bgoStr.Contains("/"))
                    {
                        //Play A / Rich Land
                        var age      = bgoStr.CutBetween("Play ", " /");
                        var cardName = bgoStr.CutAfter("/ ");
                        var card     = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), age), cardName);
                        action.ActionType = PlayerActionType.PlayActionCard;

                        action.Internal = IfCardIsInternal(card);

                        action.Data[0] = card;
                        action.Data[1] = optValue;
                    }
                    else if (bgoStr.StartsWith("Play event"))
                    {
                        //Play event Pestilence
                        //Play event Developed Territory II

                        if (bgoStr.EndsWith(" A") || bgoStr.EndsWith(" I") || bgoStr.EndsWith(" II") ||
                            bgoStr.EndsWith(" III"))
                        {
                            var conlonySplit = bgoStr.Split(" ".ToCharArray());
                            var conlonyName  = "";
                            for (var j = 2; j < conlonySplit.Length - 1; j++)
                            {
                                conlonyName += conlonySplit[j] + " ";
                            }
                            var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), conlonySplit[conlonySplit.Length]), conlonyName);
                            action.ActionType = PlayerActionType.PlayColony;
                            action.Data[0]    = card;
                            action.Data[1]    = optValue;
                        }
                        else
                        {
                            //Play event Pestilence
                            var card = Civilopedia.GetCardInfoByName(bgoStr.CutAfter("Play event "));
                            action.ActionType = PlayerActionType.PlayEvent;
                            action.Data[0]    = card;
                            action.Data[1]    = optValue;
                        }
                    }
                }
                else if (bgoStr.StartsWith("Revolution"))
                {
                    //Revolution! Change to Constitutional Monarchy (6S)
                    var resCost = Convert.ToInt32(bgoStr.CutBetween("(", "S)"));
                    var card    = Civilopedia.GetCardInfoByName(bgoStr.CutBetween("Change to ", " ("));
                    action.ActionType = PlayerActionType.Revolution;
                    action.Data[0]    = card;
                    action.Data[1]    = resCost;
                    action.Data[2]    = optValue;
                }
                else if (bgoStr.StartsWith("Elect"))
                {
                    //Elect leader: Moses
                    //Elect leader: Joan of Arc (for 1 MA)
                    if (!bgoStr.Contains("("))
                    {
                        var leader = bgoStr.CutAfter(": ");
                        action.ActionType = PlayerActionType.ElectLeader;
                        action.Data[0]    = Civilopedia.GetCardInfoByName(leader);
                        action.Data[1]    = optValue;
                    }
                    else
                    {
                        //MA elect
                    }
                }
                else if (bgoStr.StartsWith("Discover"))
                {
                    var resCost = Convert.ToInt32(bgoStr.CutBetween("(", "S)"));
                    var card    = Civilopedia.GetCardInfoByName(bgoStr.CutBetween("Discover ", " ("));
                    action.ActionType = PlayerActionType.DevelopTechCard;
                    action.Data[0]    = card;
                    action.Data[1]    = resCost;
                    action.Data[2]    = optValue;
                }
                else if (bgoStr.StartsWith("Reset Action Phase"))
                {
                    action.ActionType = PlayerActionType.ResetActionPhase;
                }
                else if (bgoStr.StartsWith("Pass political phase"))
                {
                    action.ActionType = PlayerActionType.PassPoliticalPhase;
                }
                else if (bgoStr.StartsWith("End Action Phase"))
                {
                    action.ActionType = PlayerActionType.EndActionPhase;
                }
                else if (bgoStr.StartsWith("Set up new tactics"))
                {
                    //Set up new tactics:  Classic Army
                    action.ActionType = PlayerActionType.SetupTactic;
                    var card = Civilopedia.GetCardInfoByName(bgoStr.CutAfter(":  "));
                    action.Data[0] = card;
                    action.Data[1] = optValue;
                }
                else if (bgoStr.StartsWith("Adopt tactics"))
                {
                    //Adopt tactics:  Heavy Cavalry
                    action.ActionType = PlayerActionType.AdoptTactic;
                    var card = Civilopedia.GetCardInfoByName(bgoStr.CutAfter(":  "));
                    action.Data[0] = card;
                    action.Data[1] = optValue;
                }
            }

            //---删除多余 / 一拆多
            #region disband/destory

            var disband =
                game.PossibleActions.FirstOrDefault(
                    action =>
                    action.ActionType == PlayerActionType.Unknown &&
                    action.Data[0].ToString() == "Disband / Destroy");
            if (disband != null)
            {
                //为每个建筑物建立自己的disband/destory
                game.PossibleActions.Remove(disband);
                var subDropdown = BgoRegexpCollections.ExtractSubDropDown("unite").Match(html);
                if (subDropdown.Success)
                {
                    foreach (Match match in BgoRegexpCollections.ExtractActions.Matches(subDropdown.Groups[1].Value))
                    {
                        //8;9 A/ Agriculture
                        var optValue = match.Groups[1].Value;
                        var cardName = match.Groups[2].Value;
                        var cardAge  = cardName.CutBefore("/");
                        cardName = cardName.CutAfter("/ ");

                        var card = Civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), cardAge), cardName);

                        if (card.CardType == CardType.MilitaryTechAirForce ||
                            card.CardType == CardType.MilitaryTechArtillery ||
                            card.CardType == CardType.MilitaryTechCavalry ||
                            card.CardType == CardType.MilitaryTechInfantry)
                        {
                            game.PossibleActions.Add(new BgoPlayerAction()
                            {
                                ActionType = PlayerActionType.Disband,
                                Data       = new Dictionary <int, object>
                                {
                                    { 0, card },
                                    { 1, disband.Data[1] },
                                    { 2, optValue }
                                }
                            });
                        }
                        else
                        {
                            game.PossibleActions.Add(new BgoPlayerAction()
                            {
                                ActionType = PlayerActionType.Destory,
                                Data       = new Dictionary <int, object>
                                {
                                    { 0, card },
                                    { 1, disband.Data[1] },
                                    { 2, optValue }
                                }
                            });
                        }
                    }
                }
            }

            #endregion

            #region 侵略一拆多

            var aggression =
                game.PossibleActions.Where(
                    action =>
                    action.ActionType == PlayerActionType.Unknown && (
                        action.Data[0].ToString().EndsWith(" A") || action.Data[0].ToString().EndsWith(" I") ||
                        action.Data[0].ToString().EndsWith(" II") || action.Data[0].ToString().EndsWith(" III")))
                .ToList();

            foreach (var action in aggression)
            {
                game.PossibleActions.Remove(action);

                String bgoStr   = action.Data[0].ToString();
                String optValue = action.Data[1].ToString();

                var cardName = bgoStr.Substring(0, bgoStr.LastIndexOf(" ", StringComparison.Ordinal));
                var cardAge  = bgoStr.Substring(bgoStr.LastIndexOf(" ", StringComparison.Ordinal) + 1);
                var card     = Civilopedia.GetCardInfoByName(
                    (Age)Enum.Parse(typeof(Age), cardAge)
                    , cardName);

                var advNum      = optValue.CutAfter(";");
                var subDropdown = BgoRegexpCollections.ExtractWarAggressionPactTargetList("listeAdversaires" + advNum).Match(html);
                if (subDropdown.Success)
                {
                    foreach (Match match in BgoRegexpCollections.ExtractWarAggressionPactTarget.Matches(subDropdown.Groups[1].Value))
                    {
                        //var childId = match.Groups[1].Value;
                        var childOpt   = match.Groups[2].Value;
                        var playername = match.Groups[3].Value.CutBefore(" -");
                        var maRequired = BgoRegexpCollections.ExtractImage.Matches(match.Groups[4].Value).Count;
                        game.PossibleActions.Add(new BgoPlayerAction
                        {
                            ActionType = PlayerActionType.Aggression,
                            Data       = new Dictionary <int, object>
                            {
                                { 0, card },
                                { 1, playername },
                                { 2, maRequired },
                                { 3, optValue },
                                { 4, "adversaire" + advNum },
                                { 5, childOpt }
                            }
                        });
                    }
                }
            }

            #endregion

            var selectaction =
                game.PossibleActions.FirstOrDefault(
                    action =>
                    action.ActionType == PlayerActionType.Unknown &&
                    action.Data[0].ToString() == "----- Select an action -----");
            if (selectaction != null)
            {
                game.PossibleActions.Remove(selectaction);
            }
        }
        /// <summary>
        /// 填充面板的帮助方法
        /// </summary>
        /// <param name="html"></param>
        /// <param name="game"></param>
        // ReSharper disable once FunctionComplexityOverflow
        internal static void FillGameBoard(String html, BgoGame game)
        {
            //分析用户面板

            game.PossibleActions = new List <PlayerAction>();

            //解出卡牌列
            var matches = BgoRegexpCollections.ExtractCardRow.Matches(html);

            game.CardRow = new List <CardRowCardInfo>();

            foreach (Match mc in matches)
            {
                var card = civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), mc.Groups[5].Value),
                                                         mc.Groups[6].Value);

                BgoCardRowCardInfo cardRowCardInfo = new BgoCardRowCardInfo
                {
                    Card            = card,
                    CanPutBack      = mc.Groups[4].Value.Contains("carteEnMain"),
                    CanTake         = mc.Groups[2].Value != "" && (!mc.Groups[4].Value.Contains("carteEnMain")),
                    CivilActionCost =
                        BgoRegexpCollections.ExtractGovenrmentAndActionPointsMissing.Matches(mc.Groups[8].Value).Count
                };

                //LogRecorder.Log(card.CardName + mc.Groups[2].Value);

                BgoPlayerAction pa = new BgoPlayerAction
                {
                    ActionType = PlayerActionType.TakeCardFromCardRow
                };
                pa.Data[0] = cardRowCardInfo;
                pa.Data[1] = game.CardRow.Count; //Card Row Pos
                pa.Data[2] = mc.Groups[3].Value; //idNote
                pa.Data[3] = mc.Groups[2].Value; //PostUrl

                //能拿能放回去,才能有Action
                if (cardRowCardInfo.CanPutBack || cardRowCardInfo.CanTake)
                {
                    game.PossibleActions.Add(pa);
                }

                game.CardRow.Add(cardRowCardInfo);
            }

            //当前事件
            var matchCurrentEvent = BgoRegexpCollections.ExtractCurrentEvent.Match(html);

            if (matchCurrentEvent.Groups[3].Value == "")
            {
                game.CurrentEventAge  = (Age)Enum.Parse(typeof(Age), matchCurrentEvent.Groups[5].Value);
                game.CurrentEventCard =
                    civilopedia.GetCardInfoByName(game.CurrentEventAge, matchCurrentEvent.Groups[6].Value);
                game.CurrentEventCount = matchCurrentEvent.Groups[7].Value;
            }
            else
            {
                game.CurrentEventAge   = (Age)Enum.Parse(typeof(Age), matchCurrentEvent.Groups[3].Value);
                game.CurrentEventCard  = null;
                game.CurrentEventCount = matchCurrentEvent.Groups[7].Value;
            }

            //未来事件
            var matchFutureEvent = BgoRegexpCollections.ExtractFutureEvent.Match(html);

            if (matchFutureEvent.Groups[1].Value.Length > 4)
            {
                game.FutureEventAge   = Age.A;
                game.FutureEventCount = "0";
            }
            else
            {
                game.FutureEventAge   = (Age)Enum.Parse(typeof(Age), matchFutureEvent.Groups[1].Value);
                game.FutureEventCount = matchFutureEvent.Groups[2].Value;
            }

            //卡牌剩余
            var matchCivilRemain = BgoRegexpCollections.ExtractCivilCardRemains.Match(html);

            game.CivilCardsRemain = Convert.ToInt32(matchCivilRemain.Groups[2].Value);
            var matchMilitaryRemain = BgoRegexpCollections.ExtractMilitryCardRemains.Match(html);

            game.MilitaryCardsRemain = Convert.ToInt32(matchMilitaryRemain.Groups[2].Value);

            //当前阶段
            var matchPhase = BgoRegexpCollections.ExtractGamePhase.Match(html);
            var phase      = matchPhase.Groups[1].Value;

            switch (phase.Trim())
            {
            case "Political Phase":
                game.CurrentPhase = TtaPhase.PoliticalPhase;
                break;

            case "Action Phase":
                game.CurrentPhase = TtaPhase.ActionPhase;
                break;

            case "Event Resolution":
                game.CurrentPhase = TtaPhase.EventResolution;
                break;

            case "Discard Phase":
                game.CurrentPhase = TtaPhase.DiscardPhase;
                break;

            default:
                game.CurrentPhase = TtaPhase.OtherPhase;
                break;
            }

            //时代和回合
            var matchAgeAndRound = BgoRegexpCollections.ExtractAgeAndRound.Match(html);

            game.CurrentAge   = (Age)Enum.Parse(typeof(Age), matchAgeAndRound.Groups[1].Value);
            game.CurrentRound = Convert.ToInt32(matchAgeAndRound.Groups[2].Value);

            //可抄袭阵型
            var sharedTacticsMatch = BgoRegexpCollections.ExtractSharedTactics.Match(html);

            game.SharedTactics = new List <CardInfo>();
            foreach (Match m in BgoRegexpCollections.ExtractSharedTacticsItem.Matches(sharedTacticsMatch.Groups[1].Value))
            {
                if (m.Groups[1].Value == "&nbsp;")
                {
                    continue;
                }
                game.SharedTactics.Add(civilopedia.GetCardInfoByName((Age)Enum.Parse(typeof(Age), m.Groups[1].Value),
                                                                     m.Groups[2].Value));
            }

            //拆开玩家面板

            matches     = BgoRegexpCollections.ExtractPlayerPlate.Matches(html);
            game.Boards = new List <TtaBoard>();

            int plateStart = -1;

            foreach (Match mc in matches)
            {
                if (plateStart != -1)
                {
                    String plate = html.Substring(plateStart, mc.Index - plateStart);

                    TtaBoard board = new TtaBoard();
                    game.Boards.Add(board);

                    FillPlayerBoard(board, plate);
                }

                plateStart = mc.Index;


                if (mc.Groups[2].Value != "")
                {
                    break;
                }
            }

            #region 校准名字和资源

            ExtractPlayerNameAndResource(html, game);

            #endregion


            //可用行动
            var subDropdown = BgoRegexpCollections.ExtractSubDropDown("action").Match(html);
            if (subDropdown.Success)
            {
                matches = BgoRegexpCollections.ExtractActions.Matches(subDropdown.Groups[1].Value);
                foreach (Match mc in matches)
                {
                    BgoPlayerAction pa = new BgoPlayerAction {
                        ActionType = PlayerActionType.Unknown
                    };
                    pa.Data[0] = mc.Groups[2].Value;
                    pa.Data[1] = mc.Groups[1].Value;

                    game.PossibleActions.Add(pa);
                }

                Match mSubmitForm = BgoRegexpCollections.ExtractSubmitForm.Match(html);
                game.ActionForm = new Dictionary <string, string>();

                if (mSubmitForm.Success)
                {
                    game.ActionFormSubmitUrl = mSubmitForm.Groups[1].Value;
                    matches = BgoRegexpCollections.ExtractSubmitFormDetail.Matches(mSubmitForm.Groups[2].Value);
                    foreach (Match mc in matches)
                    {
                        if (mc.Groups[2].Value != "")
                        {
                            game.ActionForm[mc.Groups[2].Value] = "";
                        }
                        else
                        {
                            game.ActionForm[mc.Groups[4].Value] = mc.Groups[5].Value;
                        }
                    }
                }
            }

            BgoActionFormater.Format((BgoGame)game, html);
        }