private void GetCardRewards(ITurnPlayer player, IGamePlayer rightNeighbor, IGamePlayer leftNeighbor, IList <IStructureCard> discardedCards) { foreach (var p in player.SelectedCard.Production) { GetOneTimeRewards(p, player, rightNeighbor, leftNeighbor, age, discardedCards); } }
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); }
static void ChoosePlay(ITurnPlayer player) { Console.WriteLine(string.Format("Player {0} ", player.Name.ToUpper())); //Console.WriteLine(string.Format("Player {0} ({1} {2} {3} stage(s))", player.Name.ToUpper(), player.Wonder.Name, player.Wonder.SelectedSide, player.Wonder.StagesBuilt)); CurrentData((IGamePlayer)player); CardOptions(player); SelectCard(player); SelectAction(player); BorrowResources(player); }
static void CardOptions(ITurnPlayer player) { Console.WriteLine("These are your card options:"); for (int i = 0; i < player.SelectableCards.Count; i++) { var card = player.SelectableCards[i]; ShowCardOption(card, i + 1); } Console.WriteLine(); }
private bool BuildWonderStage(ITurnPlayer player) { bool result = TryBuildStage(player); if (result) { LoggerHelper.Debug("Wonder stage can be built"); unitOfWork.AddEvent(new BuildStageEvent(player)); } return(result); }
/// <summary> /// Buys the selected card. /// </summary> /// <param name="card">The selected card.</param> /// <param name="player">Player buying the card.</param> /// <param name="age">The age that is being played.</param> /// <param name="specialCase">The user wants to use a special case card.</param> /// <returns></returns> private bool BuyCard(IStructureCard card, ITurnPlayer player, Age age, SpecialCaseType specialCase = SpecialCaseType.None) { bool result = TryBuyCard(card, player, age, specialCase); if (result) { LoggerHelper.Debug("Card can be bought"); unitOfWork.AddEvent(new AddCardEvent(player, card)); } return(result); }
private void GetWonderRewards(ITurnPlayer player, IGamePlayer rightNeighbor, IGamePlayer leftNeighbor, IList <IStructureCard> discardedCards) { if (player.Wonder.CurrentStage == null) { return; } foreach (var e in player.Wonder.CurrentStage.Effects) { GetOneTimeRewards(e, player, rightNeighbor, leftNeighbor, age, discardedCards); } }
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; } }
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 }); } }
static void SelectAdditionalCard(ITurnPlayer player) { Console.WriteLine("Please select your card number"); int index; while (true) { var selection = Console.ReadLine(); if (!int.TryParse(selection, out index) || index > manager.DiscardPile.Count || index < 1) { continue; } player.AdditionalInfo = manager.DiscardPile[index - 1]; Console.WriteLine(); break; } }
static void CopyGuildCard(ITurnPlayer player, IEnumerable <CardName> selectableCards) { Console.WriteLine("Please select your card number"); int index; while (true) { var selection = Console.ReadLine(); if (!int.TryParse(selection, out index) || index > selectableCards.Count() || index < 1) { continue; } player.Wonder.EffectsAvailable .First(e => e.Type == EffectType.CopyGuildFromNeighbor).Info = selectableCards.ElementAt(index - 1); Console.WriteLine(); break; } }
static void SelectCard(ITurnPlayer player) { Console.WriteLine("Please select your card number"); int index; while (true) { var selection = Console.ReadLine(); if (!int.TryParse(selection, out index) || index > player.SelectableCards.Count || index < 1) { continue; } player.SelectedCard = player.SelectableCards[index - 1]; Console.WriteLine(player.SelectedCard.Name + " chosen."); Console.WriteLine(); break; } }
static void SelectAction(ITurnPlayer player) { Console.WriteLine("Please select option 1 (BUY card), 2 (SELL card), 3 (BUILD wonder stage)"); int index; while (true) { var action = Console.ReadLine(); if (!int.TryParse(action, out index) || index > 3 || index < 1) { continue; } player.ChosenAction = (TurnAction)index - 1; Console.WriteLine(player.ChosenAction + " chosen."); Console.WriteLine(); break; } }
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; } }
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); }
private bool TryBuildStage(ITurnPlayer player) { if (player.Wonder.NextStage == null) { return(false); } var costs = player.Wonder.NextStage.Costs; var coins = costs.Count(r => r == ResourceType.Coin); var resources = costs.Where(r => r != ResourceType.Coin); if (player.CoinsLeft >= coins && !player.CheckResourceAvailability(resources.ToList(), false).Any()) { if (coins > 0) { unitOfWork.AddEvent(new PayCoinEvent(player, coins)); } return(true); } return(false); }
public ClearTemporaryResourceEvent(ITurnPlayer player) { this.player = player; }
private void RemoveCardFromSelectable(ITurnPlayer player) { player.SelectableCards.Remove(player.SelectedCard); }
static void BorrowResources(ITurnPlayer player) { var resources = new List <ResourceType>(); if (player.ChosenAction == TurnAction.BuyCard) { resources.AddRange(player.SelectedCard.ResourceCosts.Where(r => r != ResourceType.Coin)); } if (player.ChosenAction == TurnAction.BuildWonderStage) { resources.AddRange(player.Wonder.NextStage.Costs.Where(r => r != ResourceType.Coin)); } if (resources.Any() && player.CheckResourceAvailability(resources, false).Any()) { int index; while (true) { var oneForFreeCard = player.GetNonResourceEffects().FirstOrDefault(e => e.Type == EffectType.PlayCardForFreeOncePerAge); Console.WriteLine("You need to borrow resources, select which neighbor: 1 (from LEFT), 2 (from RIGHT), 3 (SKIP)" + (oneForFreeCard != null && player.ChosenAction == TurnAction.BuyCard && (oneForFreeCard.Info == null || (Age)oneForFreeCard.Info != manager.CurrentAge) ? ", 4 (PLAY FOR FREE)" : "")); var neighborSide = Console.ReadLine(); if (!int.TryParse(neighborSide, out index) || index == 3 || index > 4 || index < 1) { break; } if (index == 4) { player.SpecialCaseToUse = SpecialCaseType.PlayCardForFreeOncePerAge; break; } var neighbor = index == 1 ? PlayerDirection.ToTheLeft : PlayerDirection.ToTheRight; Console.WriteLine("Type the resource numbers you want to borrow from " + (index == 1 ? "LEFT" : "RIGHT") + " separated by comma (,)"); Console.WriteLine("1 (CLAY), 2 (ORE), 3 (STONE), 4 (WOOD), 5 (GLASS), 6 (LOOM), 7 (PAPYRUS)"); var borrow = Console.ReadLine(); foreach (var s in borrow.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)) { if (!int.TryParse(s, out index) || index > 7 || index < 1) { continue; } #region Translate Resource var res = ResourceType.Coin; switch (index) { case 1: res = ResourceType.Clay; break; case 2: res = ResourceType.Ore; break; case 3: res = ResourceType.Stone; break; case 4: res = ResourceType.Wood; break; case 5: res = ResourceType.Glass; break; case 6: res = ResourceType.Loom; break; case 7: res = ResourceType.Papyrus; break; default: break; } #endregion player.ResourcesToBorrow.Add(new BorrowResourceData { ChosenNeighbor = neighbor, ResourceType = res }); } Console.WriteLine(); } Console.WriteLine(); } }
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)); }
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); }