private static IEnumerator PerformAction(BgoSessionObject sessionObject, BgoGame game, String actionValue, Dictionary <String, String> overrideData, Action callback)
        {
            var postUrl = RemoveCharacterEntities(game.ActionFormSubmitUrl);

            WWWForm myPostData = new WWWForm();

            foreach (var pair in game.ActionForm)
            {
                if (pair.Key == "action")
                {
                    myPostData.AddField("action", actionValue);
                }
                else
                {
                    if (overrideData != null && overrideData.ContainsKey(pair.Key))
                    {
                        myPostData.AddField(pair.Key, overrideData[pair.Key]);
                        overrideData.Remove(pair.Key);
                    }
                    else
                    {
                        myPostData.AddField(pair.Key, pair.Value);
                    }
                }
            }
            if (overrideData != null)
            {
                foreach (var pair in overrideData)
                {
                    myPostData.AddField(pair.Key, pair.Value);
                }
            }


            var cookieHeaders = myPostData.headers;

            cookieHeaders.Add("Cookie", "PHPSESSID=" + sessionObject._phpSession + "; identifiant=" + sessionObject._identifiant + "; mot_de_passe=" + sessionObject._motDePasse);

            //var data = Encoding.UTF8.GetString(myPostData.data);

            var www = new WWW(BgoBaseUrl + postUrl, myPostData.data, cookieHeaders);

            yield return(www);

            if (www.error != null)
            {
                Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error);

                yield break;
            }

            var responseText = www.text;

            BgoPageProvider.FillGameBoard(responseText, game);

            if (callback != null)
            {
                callback();
            }
        }
        /// <summary>
        /// 根据网页内容填充玩家面板
        /// </summary>
        /// <param name="phpSession"></param>
        /// <param name="game"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public static IEnumerator RefreshBoard(String phpSession, BgoGame game, Action callback)
        {
            WWWForm myPostData    = new WWWForm();
            var     cookieHeaders = myPostData.headers;

            cookieHeaders.Add("Cookie", "PHPSESSID=" + phpSession);

            //var data = Encoding.UTF8.GetString(myPostData.data);

            var www = new WWW(BgoBaseUrl + "index.php?cnt=202&pl=" + game.GameId + "&nat=" + game.Nat, null, cookieHeaders);

            yield return(www);

            if (www.error != null)
            {
                Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error);

                yield break;
            }

            var html = www.text;

            Assets.CSharpCode.UI.Util.LogRecorder.Log("Board page received");

            FillGameBoard(html, game);

            if (callback != null)
            {
                callback();
            }
        }
        public static IEnumerator PostInternalAction(BgoSessionObject sessionObject, BgoGame game, BgoPlayerAction action,
                                                     Action <List <PlayerAction> > callback)
        {
            switch (action.ActionType)
            {
            case PlayerActionType.PlayActionCard:
                return(Perform2StepAction(sessionObject, game, action.Data[1].ToString(), callback));

            case PlayerActionType.BuildWonder:
                return(Perform2StepAction(sessionObject, game, action.Data[3].ToString(), callback));

            default:
                return(null);
            }
        }
        /// <summary>
        /// 获取正在进行的游戏列表,注意这里面也能取到最近完成的比赛
        /// </summary>
        /// <param name="phpSession"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public static IEnumerator GameLists(String phpSession, Action <List <BgoGame> > callback)
        {
            //http://boardgaming-online.com/index.php?cnt=2

            WWWForm myPostData = new WWWForm();
            var     headers    = myPostData.headers;

            headers.Add("Cookie", "PHPSESSID=" + phpSession);

            WWW www = new WWW(BgoBaseUrl, null, headers);

            //UnityWebRequest www = UnityWebRequest.Get(BgoBaseUrl+ "index.php?cnt=2");

            //www.SetRequestHeader("Cookie", "PHPSESSID=" + phpSession);

            yield return(www);

            if (www.error != null)
            {
                Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error);

                yield break;
            }

            var responseText = www.text;

            List <BgoGame> games = new List <BgoGame>();

            //Some logic to extract games
            var matches = BgoRegexpCollections.ListGamesInMyGamePage.Matches(responseText);

            foreach (Match match in matches)
            {
                BgoGame game = new BgoGame();
                game.GameId  = match.Groups[1].Value;
                game.Nat     = match.Groups[3].Value;
                game.Version = "2.0";
                game.Name    = UTF8Decoder(match.Groups[4].Value);
                games.Add(game);
            }

            if (callback != null)
            {
                callback(games);
            }
        }
示例#5
0
        public IEnumerator TakeInternalAction(TtaGame game, PlayerAction action, Action <List <PlayerAction> > callback)
        {
            BgoGame         bgoGame   = game as BgoGame;
            BgoPlayerAction bgoAction = action as BgoPlayerAction;
            Action <List <PlayerAction> > callbackDelegate = (actions) =>
            {
                if (callback != null)
                {
                    callback(actions);
                }
            };

            if (bgoAction == null)
            {
                LogRecorder.Log("Null Action!");
                return(null);
            }

            return(BgoPostProvider.PostInternalAction(sessionObject, bgoGame, bgoAction, callbackDelegate));
        }
示例#6
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);
            }
        }
        private static IEnumerator SendTakePutBackCardPostMessage(BgoSessionObject sessionObject, BgoGame game, String postUrl, String idNote, Action callback)
        {
            postUrl = RemoveCharacterEntities(postUrl);

            WWWForm myPostData = new WWWForm();

            myPostData.AddField("idNote", idNote);
            myPostData.AddField("idMsgChat", "");

            var cookieHeaders = myPostData.headers;

            cookieHeaders.Add("Cookie", "PHPSESSID=" + sessionObject._phpSession + "; identifiant=" + sessionObject._identifiant + "; mot_de_passe=" + sessionObject._motDePasse);

            //var data = Encoding.UTF8.GetString(myPostData.data);

            var www = new WWW(BgoBaseUrl + postUrl, myPostData.data, cookieHeaders);

            yield return(www);

            if (www.error != null)
            {
                Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error);

                yield break;
            }

            var responseText = www.text;

            BgoPageProvider.FillGameBoard(responseText, game);

            if (callback != null)
            {
                callback();
            }
        }
        private static IEnumerator Perform2StepAction(BgoSessionObject sessionObject, BgoGame game, String actionValue,
                                                      Action <List <PlayerAction> > callback)
        {
            var postUrl = RemoveCharacterEntities(game.ActionFormSubmitUrl);

            WWWForm myPostData = new WWWForm();

            var actionSp = actionValue.Split(";".ToCharArray());
            var idCarte  = "0";

            foreach (var pair in game.ActionForm)
            {
                if (pair.Key == "action")
                {
                    myPostData.AddField("action", actionValue);
                }
                else if (pair.Key == "idCarteAction")
                {
                    if (actionSp.Length > 1 && actionSp[0] == "12")
                    {
                        idCarte = actionSp[1];
                        myPostData.AddField("idCarteAction", actionSp[1]);
                    }
                    else
                    {
                        myPostData.AddField("idCarteAction", pair.Value);
                    }
                }
                else
                {
                    myPostData.AddField(pair.Key, pair.Value);
                }
            }

            var cookieHeaders = myPostData.headers;

            cookieHeaders.Add("Cookie", "PHPSESSID=" + sessionObject._phpSession + "; identifiant=" + sessionObject._identifiant + "; mot_de_passe=" + sessionObject._motDePasse);

            //var data = Encoding.UTF8.GetString(myPostData.data);

            var www = new WWW(BgoBaseUrl + postUrl, myPostData.data, cookieHeaders);

            yield return(www);

            if (www.error != null)
            {
                Assets.CSharpCode.UI.Util.LogRecorder.Log(www.error);

                yield break;
            }

            var responseText = www.text;

            //Step1 Complete

            var labelMatches = BgoRegexpCollections.ExtractActionChoice.Matches(responseText);

            if (labelMatches.Count <= 0)
            {
                callback(new List <PlayerAction>());
                yield break;
            }
            var actions = new List <PlayerAction>();

            foreach (Match m in labelMatches)
            {
                var msg      = m.Groups[2].Value;
                var optValue = m.Groups[1].Value;

                BgoPlayerAction pa = new BgoPlayerAction {
                    ActionType = PlayerActionType.Unknown
                };
                pa.Data[0] = msg;
                pa.Data[1] = optValue;
                pa.Data[2] = idCarte;
                actions.Add(pa);
            }
            BgoActionFormater.FormatInternalAction(actions, responseText);

            if (callback != null)
            {
                callback(actions);
            }
        }
        public static IEnumerator PostAction(BgoSessionObject sessionObject, BgoGame game, BgoPlayerAction action,
                                             Action callback)
        {
            switch (action.ActionType)
            {
            //Special function
            case PlayerActionType.TakeCardFromCardRow:
            case PlayerActionType.PutBackCard:
                return(SendTakePutBackCardPostMessage(sessionObject, game, action.Data[3].ToString(),
                                                      action.Data[2].ToString(), callback));

            //----optvalue is [1]
            case PlayerActionType.ResetActionPhase:
            case PlayerActionType.PassPoliticalPhase:
            case PlayerActionType.EndActionPhase:
            case PlayerActionType.PlayActionCard:
            case PlayerActionType.ElectLeader:
            case PlayerActionType.SetupTactic:
            case PlayerActionType.AdoptTactic:
            case PlayerActionType.PlayColony:
            case PlayerActionType.PlayEvent:
                return(PerformAction(sessionObject, game, action.Data[1].ToString(), callback));

            //----optvalue is [2]
            case PlayerActionType.IncreasePopulation:
            case PlayerActionType.BuildBuilding:
            case PlayerActionType.Revolution:
            case PlayerActionType.ResolveEventOption:
            case PlayerActionType.DevelopTechCard:
                return(PerformAction(sessionObject, game, action.Data[2].ToString(), AttachIdCarte(3, action),
                                     callback));

            //----optvalue is [3]
            case PlayerActionType.UpgradeBuilding:
            case PlayerActionType.BuildWonder:
                return(PerformAction(sessionObject, game, action.Data[3].ToString(), AttachIdCarte(4, action), callback));

            //----has additional form
            case PlayerActionType.Destory:
            case PlayerActionType.Disband:
                return(PerformAction(sessionObject, game, action.Data[1].ToString(),
                                     new Dictionary <String, String>
                {
                    { "unite", action.Data[2].ToString() }
                },
                                     callback));

            case PlayerActionType.Aggression:
                return(PerformAction(sessionObject, game, action.Data[3].ToString(),
                                     new Dictionary <String, String>
                {
                    { action.Data[4].ToString(), action.Data[5].ToString() }
                },
                                     callback));

            //----Unknown
            case PlayerActionType.Unknown:
                return(PerformAction(sessionObject, game, action.Data[1].ToString(), callback));

            default:
                return(null);
            }
        }
        // ReSharper disable once FunctionComplexityOverflow
        private static void ExtractPlayerNameAndResource(string html, BgoGame game)
        {
            var myNameMatch = BgoRegexpCollections.ExtractMyName.Match(html);
            var myName      = myNameMatch.Groups[1].Value.Replace("&nbsp;", " ");

            var matches = BgoRegexpCollections.ExtractPlayerNameAndResource.Matches(html);

            for (var i = 0; i < matches.Count; i++)
            {
                Match mc = matches[i];

                var board = game.Boards[i];

                board.PlayerName = mc.Groups[1].Value;

                if (myName.ToLower() == board.PlayerName.ToLower())
                {
                    game.MyPlayerIndex = i;
                }

                var strCut = mc.Groups[0].Value;

                var resourceMatches = BgoRegexpCollections.ExtractPlayerNameAndResourceCutResourceOut.Matches(strCut);

                foreach (Match rmc in resourceMatches)
                {
                    switch (rmc.Groups[1].Value)
                    {
                    case "Culture":
                    {
                        var cm   = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value);
                        int curr = Convert.ToInt32(cm.Groups[1].Value);
                        int incr = cm.Groups[3].Value == "-" ? 0 : Convert.ToInt32(cm.Groups[3].Value);
                        board.Resource[ResourceType.Culture]          = curr;
                        board.Resource[ResourceType.CultureIncrement] = incr;
                    }
                    break;

                    case "Science":
                    {
                        var cm    = BgoRegexpCollections.ExtractPlayerNameAndResourceSpecial.Match(rmc.Groups[2].Value);
                        int curr  = Convert.ToInt32(cm.Groups[1].Value);
                        int mcurr = cm.Groups[2].Value == "" ? 0 : Convert.ToInt32(cm.Groups[2].Value);
                        int incr  = cm.Groups[4].Value == "-" ? 0 : Convert.ToInt32(cm.Groups[4].Value);
                        board.Resource[ResourceType.Science]            = curr;
                        board.Resource[ResourceType.ScienceForMilitary] = mcurr;
                        board.Resource[ResourceType.ScienceIncrement]   = incr;
                    }
                    break;

                    case "Puissance":
                    {
                        var cm   = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value);
                        int curr = Convert.ToInt32(cm.Groups[1].Value);
                        board.Resource[ResourceType.MilitaryForce] = curr;
                    }
                    break;

                    case "Exploration":
                    {
                        var cm   = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value);
                        int curr = cm.Groups[1].Value == "" ? 0 : Convert.ToInt32(cm.Groups[1].Value);
                        board.Resource[ResourceType.Exploration] = curr;
                    }
                    break;

                    case "HF":
                    {
                        var cms = BgoRegexpCollections.ExtractPlayerNameAndResourceHappy.Matches(rmc.Groups[2].Value);
                        board.Resource[ResourceType.HappyFace] = cms.Count;
                        //cms = BgoRegexpCollections.ExtractPlayerNameAndResourceUnhappy.Matches(rmc.Groups[2].Value);
                        //board.ResourceQuantity[ResourceType.UnhappyFace] = cms.Count;
                    }
                    break;

                    case "Nourriture":
                    {
                        var cm   = BgoRegexpCollections.ExtractPlayerNameAndResourceNormal.Match(rmc.Groups[2].Value);
                        int curr = Convert.ToInt32(cm.Groups[1].Value);
                        int incr = cm.Groups[3].Value == "-" ? 0 : Convert.ToInt32(cm.Groups[3].Value);
                        board.Resource[ResourceType.Food]          = curr;
                        board.Resource[ResourceType.FoodIncrement] = incr;
                    }
                    break;

                    case "Ressources":
                    {
                        var cm    = BgoRegexpCollections.ExtractPlayerNameAndResourceSpecial.Match(rmc.Groups[2].Value);
                        int curr  = Convert.ToInt32(cm.Groups[1].Value);
                        int mcurr = cm.Groups[2].Value == "" ? 0 : Convert.ToInt32(cm.Groups[2].Value);
                        int incr  = cm.Groups[4].Value == "" ? 0 : Convert.ToInt32(cm.Groups[4].Value);
                        board.Resource[ResourceType.Resource]            = curr;
                        board.Resource[ResourceType.ResourceForMilitary] = mcurr;
                        board.Resource[ResourceType.ResourceIncrement]   = incr;
                    }
                    break;

                    default:
                        Assets.CSharpCode.UI.Util.LogRecorder.Log("UnknownRMC:" + rmc.Groups[1].Value);
                        break;
                    }
                }
            }
        }
        /// <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);
        }