Esempio n. 1
0
        private void SaveEventOperations(IGamePlayer player, IGamePlayer rightNeighbor, IGamePlayer leftNeighbor, IList <BorrowResourceData> data)
        {
            foreach (var entry in data)
            {
                var discountType = Enumerator.GetTradeDiscountType(entry.ResourceType);
                var coinsToPay   = player.HasDiscount(entry.ChosenNeighbor, discountType) ? ConstantValues.COIN_VALUE_FOR_SHARE_DISCOUNT : ConstantValues.COIN_VALUE_FOR_SHARE_DEFAULT;

                IGamePlayer neighborPlayer = null;
                switch (entry.ChosenNeighbor)
                {
                case PlayerDirection.ToTheLeft:
                    neighborPlayer = leftNeighbor;
                    break;

                case PlayerDirection.ToTheRight:
                    neighborPlayer = rightNeighbor;
                    break;

                default:
                    break;
                }
                if (neighborPlayer == null)
                {
                    continue;
                }

                LoggerHelper.DebugFormat("Player {0} will pay {1} coins to {2} for using the resource {3}", player.Name, coinsToPay, neighborPlayer.Name, entry.ResourceType);
                this.unitOfWork.AddEvent(new PayCoinEvent(player, coinsToPay));
                this.unitOfWork.AddEvent(new ReceiveCoinEvent(neighborPlayer, coinsToPay));
            }
        }
Esempio n. 2
0
        private void CollectTokens(IGamePlayer winner, IGamePlayer loser, Age age)
        {
            var token = ConflictToken.AgeOneVictory;

            switch (age)
            {
            case Age.I:
                token = ConflictToken.AgeOneVictory;
                break;

            case Age.II:
                token = ConflictToken.AgeTwoVictory;
                break;

            case Age.III:
                token = ConflictToken.AgeThreeVictory;
                break;

            default:
                break;
            }
            LoggerHelper.DebugFormat("{0} wins and receives a {1} token. {2} loses.", winner.Name, token, loser.Name);
            winner.ConflictTokens.Add(token);
            loser.ConflictTokens.Add(ConflictToken.Defeat);
        }
Esempio n. 3
0
        private bool TryBuyCard(IStructureCard card, ITurnPlayer player, Age age, SpecialCaseType specialCase)
        {
            if (CanGetForFree(card))
            {
                LoggerHelper.Debug("Card is free.");
                return(true);
            }
            if (HasDemandedCard(card, player.Cards))
            {
                LoggerHelper.Debug("Player can build for free because of previous card");
                return(true);
            }
            if (UseSpecialCase(player, specialCase, age))
            {
                LoggerHelper.DebugFormat("Player can play card for free, because of {0}", specialCase);
                return(true);
            }

            var coins     = card.ResourceCosts.Count(r => r == ResourceType.Coin);
            var resources = card.ResourceCosts.Where(r => r != ResourceType.Coin);

            LoggerHelper.DebugFormat("Structure card costs {0} coins and {1} resources", coins, resources.Count());
            if (player.CoinsLeft >= coins && !player.CheckResourceAvailability(resources.ToList(), false).Any())
            {
                if (coins > 0)
                {
                    unitOfWork.AddEvent(new PayCoinEvent(player, coins));
                }
                return(true);
            }

            return(false);
        }
        protected override void Compute(IList <IPlayer> players)
        {
            LoggerHelper.DebugFormat("Starting to compute scientific symbol victory points");
            foreach (var player in players)
            {
                var symbols    = new List <ScientificSymbol>();
                var cards      = player.Cards.Where(c => c.Type == StructureType.Scientific || c.Type == StructureType.Guilds).ToList();
                var choosables = 0;

                foreach (var c in cards)
                {
                    symbols.AddRange(c.StandaloneEffect
                                     .Where(e => Enumerator.ContainsEnumeratorValue <ScientificSymbol>((int)e.Type))
                                     .Select(e => (ScientificSymbol)((int)e.Type)));

                    choosables += c.ChoosableEffect
                                  .Any(e => Enumerator.ContainsEnumeratorValue <ScientificSymbol>((int)e.Type)) ?
                                  1 : 0;
                }

                foreach (var p in player.Wonder.ChoosableEffectsAvailable)
                {
                    choosables += p.Any(e => Enumerator.ContainsEnumeratorValue <ScientificSymbol>((int)e.Type)) ?
                                  1 : 0;
                }

                var symbolsToCompute = GetBestCombination(symbols, choosables);
                player.VictoryPoints += GetVictoryPoints(symbolsToCompute);

                LoggerHelper.DebugFormat("{0} has now {1} victory points.", player.Name, player.VictoryPoints);
            }
        }
Esempio n. 5
0
 protected override void Compute(IList <IPlayer> players)
 {
     LoggerHelper.DebugFormat("Starting to compute military conflict victory points");
     foreach (var p in players)
     {
         p.VictoryPoints += p.ConflictTokenSum;
         LoggerHelper.DebugFormat("{0} has now {1} victory points.", p.Name, p.VictoryPoints);
     }
 }
 protected override void Compute(IList <IPlayer> players)
 {
     LoggerHelper.DebugFormat("Starting to compute treasury victory points");
     foreach (var p in players)
     {
         p.VictoryPoints += (int)(p.Coins / 3);
         LoggerHelper.DebugFormat("{0} has now {1} victory points. Coins({2})", p.Name, p.VictoryPoints, p.Coins);
     }
 }
Esempio n. 7
0
 private void DiscardLeftCards()
 {
     foreach (var p in players)
     {
         foreach (var c in p.SelectableCards)
         {
             discardPile.Add(c);
             LoggerHelper.DebugFormat("Discarded {0}", c.Name);
         }
     }
 }
Esempio n. 8
0
        public IList <IStructureCard> GetShuffledDeck(int numberOfPlayers)
        {
            var cardMapping = CardMappingHelper.ReadMainXmlFile();

            LoggerHelper.DebugFormat("The deck has {0} cards", cardMapping.CardMapping.Count);
            var deck = FilterAndMapDeck(cardMapping, numberOfPlayers);

            Randomizer.Shuffle <IStructureCard>(deck, deck.Count * 4);
            LoggerHelper.DebugFormat("Shuffled {0} cards for {1} players", deck.Count, numberOfPlayers);
            return(deck);
        }
Esempio n. 9
0
 void DrawWonderCards()
 {
     LoggerHelper.Info("Randomly drawing wonder cards to players.");
     foreach (var p in this.Players)
     {
         var wonderCard = wonderCards.First();
         wonderCards.Remove(wonderCard);
         var wonder = WonderFactory.CreateWonder(wonderCard.Name, wonderCard.Side);
         LoggerHelper.DebugFormat("Defining side {0} of wonder {1} to player: {2}", wonderCard.Side, wonderCard.Name, p.Name);
         p.SetWonder(wonder);
     }
 }
Esempio n. 10
0
 protected override void Compute(IList <IPlayer> players)
 {
     LoggerHelper.DebugFormat("Starting to compute wonder stage victory points");
     foreach (var p in players)
     {
         foreach (var e in p.Wonder.EffectsAvailable.Where(e => e.Type == EffectType.VictoryPoint))
         {
             p.VictoryPoints += e.Quantity;
         }
         LoggerHelper.DebugFormat("{0} has now {1} victory points.", p.Name, p.VictoryPoints);
     }
 }
Esempio n. 11
0
 public void SetupCoinsFromBank(IList <IGamePlayer> players)
 {
     if (players == null)
     {
         return;
     }
     LoggerHelper.DebugFormat("Giving {0} coins to each player", ConstantValues.INITIAL_COINS);
     foreach (var p in players)
     {
         p.ReceiveCoin(ConstantValues.INITIAL_COINS);
     }
 }
Esempio n. 12
0
        private void GetOneTimeRewards(IEffect effect, ITurnPlayer player, IGamePlayer rightNeighbor, IGamePlayer leftNeighbor, Age age, IList <IStructureCard> discardedCards)
        {
            switch (effect.Type)
            {
            case EffectType.Coin:
                unitOfWork.AddEvent(new ReceiveCoinEvent(player, effect.Quantity));
                LoggerHelper.DebugFormat("Player {0} get {1} coins", player.Name, effect.Quantity);
                break;

            case EffectType.CoinPerRawMaterialCard:
                var rawMaterialCoins = GetCoinsForStructureType(player, rightNeighbor, leftNeighbor, StructureType.RawMaterial, effect.Direction) * effect.Quantity;
                unitOfWork.AddEvent(new ReceiveCoinEvent(player, rawMaterialCoins));
                LoggerHelper.DebugFormat("Player {0} get {1} coins because of {2}", player.Name, rawMaterialCoins, effect.Type);
                break;

            case EffectType.CoinPerManufacturedGoodCard:
                var manufacturedCoins = GetCoinsForStructureType(player, rightNeighbor, leftNeighbor, StructureType.ManufacturedGood, effect.Direction) * effect.Quantity;
                unitOfWork.AddEvent(new ReceiveCoinEvent(player, manufacturedCoins));
                LoggerHelper.DebugFormat("Player {0} get {1} coins because of {2}", player.Name, manufacturedCoins, effect.Type);
                break;

            case EffectType.CoinPerCommercialCard:
                var commercialCoins = GetCoinsForStructureType(player, rightNeighbor, leftNeighbor, StructureType.Commercial, effect.Direction) * effect.Quantity;
                unitOfWork.AddEvent(new ReceiveCoinEvent(player, commercialCoins));
                LoggerHelper.DebugFormat("Player {0} get {1} coins because of {2}", player.Name, commercialCoins, effect.Type);
                break;

            case EffectType.CoinPerWonderStageBuilt:
                var stageCoins = GetCoinsForWonderStage(player, rightNeighbor, leftNeighbor, effect.Direction) * effect.Quantity;
                unitOfWork.AddEvent(new ReceiveCoinEvent(player, stageCoins));
                LoggerHelper.DebugFormat("Player {0} get {1} coins because of {2}", player.Name, stageCoins, effect.Type);
                break;

            case EffectType.PlayOneDiscardedCard:
                var discarded = (IStructureCard)player.AdditionalInfo;
                if (!discardedCards.Contains(discarded))
                {
                    throw new Exception("The card is not in discard pile.");
                }
                LoggerHelper.DebugFormat("Player {0} plays discarded card {1}", player.Name, discarded.Name);
                unitOfWork.AddEvent(new DrawFromDiscardPileEvent(discarded, discardedCards));
                unitOfWork.AddEvent(new AddCardEvent(player, discarded));
                player.ExecutedAction = TurnAction.BuyCard;
                player.SelectedCard   = discarded;
                GetCardRewards(player, rightNeighbor, leftNeighbor, discardedCards);
                break;

            default:
                break;
            }
        }
Esempio n. 13
0
        private void CheckResourcesToBorrow(IStructureCard card, ITurnPlayer player)
        {
            IList <ResourceType> missingResources = new List <ResourceType>();

            if ((player.ChosenAction == TurnAction.BuyCard && (CanGetForFree(card) || HasDemandedCard(card, player.Cards))) || ValidSpecialCase(player, player.SpecialCaseToUse, age) != null)
            {
                return;
            }

            IList <ResourceType> resourcesToCheck = new List <ResourceType>();

            if (player.ChosenAction == TurnAction.BuildWonderStage && player.Wonder.NextStage != null)
            {
                foreach (var c in player.Wonder.NextStage.Costs)
                {
                    resourcesToCheck.Add(c);
                }
            }
            if (player.ChosenAction == TurnAction.BuyCard)
            {
                foreach (var c in card.ResourceCosts)
                {
                    resourcesToCheck.Add(c);
                }
            }
            //Remove predefined resources to borrow
            foreach (var r in player.ResourcesToBorrow)
            {
                var index = resourcesToCheck.IndexOf(r.ResourceType);
                if (index >= 0)
                {
                    resourcesToCheck.RemoveAt(index);
                }
            }
            missingResources = player.CheckResourceAvailability(resourcesToCheck.Where(r => r != ResourceType.Coin).ToList(), false);

            if (missingResources.Any())
            {
                LoggerHelper.DebugFormat("Will need to borrow {0} resources that were not set.", missingResources.Count);
            }
            //Add the rest of the needed resources to list
            foreach (var r in missingResources)
            {
                player.ResourcesToBorrow.Add(new BorrowResourceData
                {
                    ChosenNeighbor = PlayerDirection.None,
                    ResourceType   = r
                });
            }
        }
Esempio n. 14
0
        protected override void Compute(IList <IPlayer> players)
        {
            LoggerHelper.DebugFormat("Starting to compute commercial structure victory points");
            foreach (var p in players)
            {
                var cards = p.Cards.Where(c => c.Type == BaseEntities.StructureType.Commercial).ToList();
                var sb    = new StringBuilder();

                foreach (var c in cards)
                {
                    foreach (var e in c.StandaloneEffect)
                    {
                        var pts = 0;
                        switch (e.Type)
                        {
                        case BaseEntities.EffectType.VictoryPointPerWonderStageBuilt:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByWonderStage(p, e.Quantity);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerCommercialCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.Commercial);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerRawMaterialCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.RawMaterial);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerManufacturedGoodCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.ManufacturedGood);
                            break;

                        default:
                            break;
                        }
                        if (pts > 0)
                        {
                            sb.AppendFormat("{0}({1}) ", c.Name, pts);
                        }
                    }
                }

                LoggerHelper.DebugFormat("{0} has now {1} victory points. {2}", p.Name, p.VictoryPoints, sb.ToString());
            }
        }
Esempio n. 15
0
        private void GetMultipleTimesRewards(IEffect effect, ITurnPlayer player, IGamePlayer rightNeighbor, IGamePlayer leftNeighbor, IList <IStructureCard> discardedCards)
        {
            switch (effect.Type)
            {
            case EffectType.PlaySeventhCard:
                if (turn != 6)
                {
                    break;
                }
                LoggerHelper.DebugFormat("Player {0} plays extra card", player.Name);
                player.SelectedCard = player.SelectableCards[0];
                Play(player, rightNeighbor, leftNeighbor, discardedCards);
                GetCardRewards(player, rightNeighbor, leftNeighbor, discardedCards);
                break;

            default:
                break;
            }
        }
Esempio n. 16
0
        private void Play(ITurnPlayer player, IGamePlayer rightPlayer, IGamePlayer leftPlayer, IList <IStructureCard> discardedCards)
        {
            LoggerHelper.DebugFormat("Player {0} will {1} {2}", player.Name, player.ChosenAction, player.SelectedCard.Name);
            var           success      = false;
            ITradeManager tradeManager = new TradeManager(unitOfWork);

            CheckResourcesToBorrow(player.SelectedCard, player);
            if ((player.ChosenAction != TurnAction.BuyCard || !player.HasCard(player.SelectedCard)) &&
                tradeManager.BorrowResources(player, rightPlayer, leftPlayer, player.ResourcesToBorrow, true))
            {
                switch (player.ChosenAction)
                {
                case TurnAction.BuyCard:
                    success = BuyCard(player.SelectedCard, player, age, player.SpecialCaseToUse);
                    break;

                case TurnAction.SellCard:
                    SellCard(player, discardedCards);
                    success = true;
                    break;

                case TurnAction.BuildWonderStage:
                    success = BuildWonderStage(player);
                    break;

                default:
                    break;
                }
            }

            if (!success)
            {
                LoggerHelper.DebugFormat("Player {0} could not {1}. Selling and discarding card", player.Name, player.ChosenAction);
                SellCard(player, discardedCards);
                player.ExecutedAction = TurnAction.SellCard;
            }
            else
            {
                player.ExecutedAction = player.ChosenAction;
            }
            RemoveCardFromSelectable(player);
        }
 protected override void Compute(IList <IPlayer> players)
 {
     LoggerHelper.DebugFormat("Starting to compute civilian structure victory points");
     foreach (var p in players)
     {
         var sb = new StringBuilder();
         foreach (var c in p.Cards.Where(c => c.Type == BaseEntities.StructureType.Civilian))
         {
             foreach (var e in c.Production)
             {
                 if (e.Type != BaseEntities.EffectType.VictoryPoint)
                 {
                     return;
                 }
                 sb.AppendFormat("{0}({1}) ", c.Name, e.Quantity);
                 p.VictoryPoints += e.Quantity;
             }
         }
         LoggerHelper.DebugFormat("{0} has now {1} victory points. {2}", p.Name, p.VictoryPoints, sb.ToString());
     }
 }
Esempio n. 18
0
        public void GetPostGameRewards(IList <IGamePlayer> players)
        {
            LoggerHelper.Info("Getting post game rewards for players.");
            foreach (var p in players)
            {
                foreach (var e in p.Wonder.EffectsAvailable)
                {
                    switch (e.Type)
                    {
                    case EffectType.CopyGuildFromNeighbor:
                        var neighbors = NeighborsHelper.GetNeighbors(players.Select(pl => (IPlayer)pl).ToList(), p);
                        if (e.Info == null)
                        {
                            break;
                        }
                        var selectedCard = (CardName)e.Info;
                        var card         = neighbors[NeighborsHelper.RIGHTDIRECTION].Cards.FirstOrDefault(c => c.Name == selectedCard);
                        if (card != null)
                        {
                            unitOfWork.AddEvent(new AddCardEvent(p, card));
                        }
                        else
                        {
                            card = neighbors[NeighborsHelper.LEFTDIRECTION].Cards.FirstOrDefault(c => c.Name == selectedCard);
                            if (card != null)
                            {
                                unitOfWork.AddEvent(new AddCardEvent(p, card));
                            }
                        }
                        LoggerHelper.DebugFormat("Player {0} copied {1} from neighbor as part of CopyGuildFromNeighbor effect.", p.Name, selectedCard);
                        break;

                    default:
                        break;
                    }
                }
            }
        }
Esempio n. 19
0
        public void MoveSelectableCards(IList <ITurnPlayer> players)
        {
            var direction = "to the left";

            switch (age)
            {
            case Age.I:
                MoveCards(players);
                break;

            case Age.II:
                MoveCards(players.Reverse());
                direction = "to the right";
                break;

            case Age.III:
                MoveCards(players);
                break;

            default:
                break;
            }
            LoggerHelper.DebugFormat("Moving all selectable cards {0}", direction);
        }
        /// <summary>
        /// 生成授权跳转Url
        /// </summary>
        /// <param name="context"></param>
        /// <param name="httpContext"></param>
        private void CreateRedirectUrl(AuthorizationFilterContext context, Microsoft.AspNetCore.Http.HttpContext httpContext)
        {
            LoggerHelper.DebugFormat("即将跳转到微信服务器来并授权获取粉丝信息");
            string redirectUrl = httpContext.Request.Query["redirectUrl"];
            string state       = httpContext.Request.Query["state"];

            if (string.IsNullOrWhiteSpace(redirectUrl))
            {
                redirectUrl = httpContext.Request.GetDisplayUrl();
            }
            //已获取授权
            if (!redirectUrl.ToLower().Contains("openid="))
            {
                httpContext.Response.Cookies.Append(RedirectUrlCookieName, redirectUrl);
                //获取授权Url
                var url = WeChatApisContext.Current.OAuthApi.GetAuthorizeUrl(redirectUrl, state ?? State);
                LoggerHelper.Debug(string.Format("跳转至微信服务器获取授权...\n{0}\n{1}", redirectUrl, url));
                context.Result = new RedirectResult(url);
            }
            else
            {
                context.Result = new RedirectResult(redirectUrl);
            }
        }
Esempio n. 21
0
        protected override void Compute(IList <IPlayer> players)
        {
            LoggerHelper.DebugFormat("Starting to compute guild victory points");
            foreach (var p in players)
            {
                var cards         = p.Cards.Where(c => c.Type == BaseEntities.StructureType.Guilds).ToList();
                var neighbors     = NeighborsHelper.GetNeighbors(players, p);
                var rightNeighbor = neighbors[NeighborsHelper.RIGHTDIRECTION];
                var leftNeighbor  = neighbors[NeighborsHelper.LEFTDIRECTION];
                var sb            = new StringBuilder();

                foreach (var c in cards)
                {
                    foreach (var e in c.StandaloneEffect)
                    {
                        var pts = 0;
                        switch (e.Type)
                        {
                        case BaseEntities.EffectType.VictoryPointPerRawMaterialCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.RawMaterial, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerManufacturedGoodCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.ManufacturedGood, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerCommercialCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.Commercial, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerScientificCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.Scientific, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerMilitaryCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.Military, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerConflictDefeat:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByConflictDefeat(p, e.Quantity, StructureType.Military, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerCivilianCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.Civilian, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerWonderStageBuilt:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByWonderStage(p, e.Quantity, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        case BaseEntities.EffectType.VictoryPointPerGuildCard:
                            p.VictoryPoints += pts = VictoryPointsHelper.GetVictoryPointsByStructureType(p, e.Quantity, StructureType.Guilds, e.Direction, rightNeighbor, leftNeighbor);
                            break;

                        default:
                            break;
                        }
                        if (pts > 0)
                        {
                            sb.AppendFormat("{0}({1}) ", c.Name, pts);
                        }
                    }
                }
                LoggerHelper.DebugFormat("{0} has now {1} victory points. {2}", p.Name, p.VictoryPoints, sb.ToString());
            }
        }
Esempio n. 22
0
 private void SellCard(ITurnPlayer player, IList <IStructureCard> discardedCards)
 {
     LoggerHelper.DebugFormat("Discard {0} and collect coins", player.SelectedCard.Name);
     unitOfWork.AddEvent(new DiscardCardEvent(player.SelectedCard, discardedCards));
     unitOfWork.AddEvent(new ReceiveCoinEvent(player, ConstantValues.SELL_CARD_COINS));
 }
Esempio n. 23
0
        public bool BorrowResources(ITurnPlayer player, IGamePlayer rightNeighbor, IGamePlayer leftNeighbor, IList <BorrowResourceData> data, bool allowAutomaticChoice)
        {
            if (!data.Any())
            {
                return(true);
            }

            //If some of the data doesn't have a direction preference and is not allowed to automatic choose, nothing happens
            if (!allowAutomaticChoice && data.Any(r => r.ChosenNeighbor != PlayerDirection.ToTheLeft && r.ChosenNeighbor != PlayerDirection.ToTheRight))
            {
                return(false);
            }

            //Select a random direction for the non preference entries.
            foreach (var r in data.Where(r => r.ChosenNeighbor != PlayerDirection.ToTheLeft && r.ChosenNeighbor != PlayerDirection.ToTheRight))
            {
                var availableDirections = new List <PlayerDirection>();
                availableDirections.Add(PlayerDirection.ToTheLeft);
                availableDirections.Add(PlayerDirection.ToTheRight);
                r.ChosenNeighbor = Randomizer.SelectOne(availableDirections);
            }

            var fromRight = data.Where(r => r.ChosenNeighbor == PlayerDirection.ToTheRight).Select(r => r.ResourceType).ToList();
            var fromLeft  = data.Where(r => r.ChosenNeighbor == PlayerDirection.ToTheLeft).Select(r => r.ResourceType).ToList();

            LoggerHelper.DebugFormat("Player {0} will borrow {1} resources from right neighbor and {2} resources from left neighbor.", player.Name, fromRight.Count, fromLeft.Count);

            var missingFromRight = BorrowResourceFromNeighbor(rightNeighbor, fromRight);
            var missingFromLeft  = BorrowResourceFromNeighbor(leftNeighbor, fromLeft);

            if (missingFromRight.Any() || missingFromLeft.Any())
            {
                //If not allowed to automatic choose and some resource is missing, it can't be completed.
                if (!allowAutomaticChoice)
                {
                    return(false);
                }

                LoggerHelper.DebugFormat("Player {0} could not borrow {1} resources from right neighbor and {2} resources from left neighbor.", player.Name, fromRight.Count, fromLeft.Count);
                //Move missing resources between neighbors and try to borrow again.
                RemoveResourcesAndAddRange(fromRight, missingFromRight, missingFromLeft);
                RemoveResourcesAndAddRange(fromLeft, missingFromLeft, missingFromRight);

                if (BorrowResourceFromNeighbor(rightNeighbor, fromRight).Any() || BorrowResourceFromNeighbor(leftNeighbor, fromLeft).Any())
                {
                    return(false);
                }

                //Clears former data and create new using the correct neighbors.
                data.Clear();
                foreach (var rt in fromRight)
                {
                    data.Add(new BorrowResourceData {
                        ChosenNeighbor = PlayerDirection.ToTheRight, ResourceType = rt
                    });
                }
                foreach (var rt in fromLeft)
                {
                    data.Add(new BorrowResourceData {
                        ChosenNeighbor = PlayerDirection.ToTheLeft, ResourceType = rt
                    });
                }
            }

            //Checks if got enough coins to pay.
            foreach (var d in data)
            {
                player.CoinsLeft -= player.HasDiscount(d.ChosenNeighbor, Enumerator.GetTradeDiscountType(d.ResourceType)) ? ConstantValues.COIN_VALUE_FOR_SHARE_DISCOUNT : ConstantValues.COIN_VALUE_FOR_SHARE_DEFAULT;
                if (player.CoinsLeft < 0)
                {
                    LoggerHelper.DebugFormat("Player {0} cannot afford costs in coins. Will not be able to borrow resources.", player.Name);
                    return(false);
                }
            }

            //If everything went ok
            player.AddTemporaryResources(data.Select(r => r.ResourceType).ToList());
            SaveEventOperations(player, rightNeighbor, leftNeighbor, data);
            return(true);
        }
        /// <summary>
        /// The OnAuthorization
        /// </summary>
        /// <param name="context">The context<see cref="AuthorizationFilterContext"/></param>
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            LoggerHelper.Debug(string.Format("Action:{0}正在获取授权并且获得粉丝信息。", context.ActionDescriptor.DisplayName));
            var httpContext = context.HttpContext;
            var request     = httpContext.Request;
            var code        = request.Query["code"];
            var state       = request.Query["state"];
            var userAgent   = request.Headers["User-Agent"].ToString().ToLower();

            //是否来自微信端请求
            if (!userAgent.Contains("micromessenger"))
            {
                context.Result = new ContentResult()
                {
                    Content = "不支持除微信浏览器以外的请求!",
                };
                return;
            }

            #region 如果是从微信验证页面跳转回来

            if (!string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(state))
            {
                LoggerHelper.DebugFormat("根据授权Code获取粉丝信息。Code:{0}   State:{1} ...", code, state);

                var redirectUrlCookie = request.Cookies[RedirectUrlCookieName];
                if (string.IsNullOrEmpty(redirectUrlCookie))
                {
                    return;
                }
                var redirectUrl = redirectUrlCookie;
                if (IsOnlyGetOpenId)
                {
                    //通过code换取access_token,Code只能用一次
                    //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
                    var result = WeChatApisContext.Current.OAuthApi.Get(code);
                    if (!result.IsSuccess())
                    {
                        if (result.ReturnCode == SDK.Apis.ReturnCodes.OAUTH授权码已被使用)
                        {
                            LoggerHelper.Warn(result.ReturnCode + "!正在重新跳转以进行授权!");
                            CreateRedirectUrl(context, httpContext);
                            return;
                        }
                        LoggerHelper.Error("授权出错,获取access_token失败!" + result.GetFriendlyMessage());
                        throw new Exception("授权出错,获取access_token失败!");
                    }
                    LoggerHelper.Debug("授权成功:" + result.DetailResult);
                    redirectUrl += (redirectUrl.Contains("?") ? "&" : "?") + "openId=" + result.OpenId;
                }
                else
                {
                    if (!redirectUrl.Contains("code="))
                    {
                        redirectUrl += (redirectUrl.Contains("?") ? "&" : "?") + "code=" + code;
                    }

                    if (!redirectUrl.Contains("state="))
                    {
                        redirectUrl += (redirectUrl.Contains("?") ? "&" : "?") + "state=" + state;
                    }
                }

                httpContext.Response.Cookies.Delete(RedirectUrlCookieName);
                context.Result = new RedirectResult(redirectUrl);
            }

            #endregion

            #region 如果没有验证,则进行验证

            else
            {
                CreateRedirectUrl(context, httpContext);
            }

            #endregion
        }