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 == " ") { 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); }