/// <summary> /// Determines if a given card is buildable. /// Returns "T" if it is, returns "F" if it is not /// </summary> /// <param name="card"></param> /// <returns></returns> public CommerceOptions isCardBuildable(Card card) { CommerceOptions ret = new CommerceOptions(); //retrieve the cost Cost cost = card.cost; //if the player already owns a copy of the card, Return F immediatley // Note cannot use playedStructure.Contains(card) because Age 1 Loom != Age 2 Loom, so it's possible to build more than one of them. if (playedStructure.Exists(x => x.Id == card.Id)) { ret.bAreResourceRequirementsMet = false; ret.buildable = CommerceOptions.Buildable.StructureAlreadyBuilt; return ret; } //if the cost is !, that means its free. Return T immediately if (cost.coin == 0 && cost.resources == string.Empty) { ret.bAreResourceRequirementsMet = true; ret.buildable = CommerceOptions.Buildable.True; return ret; } //if the player owns the prerequiste, Return T immediately if (playedStructure.Exists(x => (x.chain[0] == card.strName) || (x.chain[1] == card.strName))) { ret.bAreResourceRequirementsMet = true; ret.buildable = CommerceOptions.Buildable.True; return ret; } if (card.structureType == StructureType.Guild && playedStructure.Exists(x => x.Id == CardId.Ramses)) { // Ramses: The player can build any Guild card for free. ret.bAreResourceRequirementsMet = true; ret.buildable = CommerceOptions.Buildable.True; return ret; } int nWildResources = 0; if (playedStructure.Exists(x => x.effect is StructureDiscountEffect && ((StructureDiscountEffect)x.effect).discountedStructureType == card.structureType)) { // A leader card has been played that matches the structure type being built, so we can add a wild resource // e.g. We're building a science structure while Archimedes is in play for this player, or a military structure // when Leonidas is in play. ++nWildResources; } int coinCost = cost.coin; if (card.structureType == StructureType.Leader) { if (playerBoard.name == "Roma (A)" || playedStructure.Exists(x => x.Id == CardId.Maecenas)) { coinCost = 0; } else if (playerBoard.name == "Roma (B)") { coinCost = Math.Max(0, coinCost - 2); } else if (leftNeighbour.playerBoard.name == "Roma (B)" || rightNeighbour.playerBoard.name == "Roma (B)") { coinCost -= 1; } } if (coin < coinCost) { // if the card has a coin cost and we don't have enough money, the card is not buildable. ret.bAreResourceRequirementsMet = false; ret.buildable = CommerceOptions.Buildable.InsufficientCoins; return ret; } ret = resourceMgr.CanAfford(cost, leftNeighbour.resourceMgr.getResourceList(false), rightNeighbour.resourceMgr.getResourceList(false), ResourceManager.CommercePreferences.LowestCost | ResourceManager.CommercePreferences.BuyFromLeftNeighbor); if (ret.bAreResourceRequirementsMet) { if ((ret.leftCoins == 0 && ret.rightCoins == 0) && (ret.bankCoins == 0 || (ret.bankCoins == cost.coin))) { if (coin < ret.bankCoins) ret.buildable = CommerceOptions.Buildable.InsufficientCoins; else ret.buildable = CommerceOptions.Buildable.True; } else if (coin < ret.bankCoins) { ret.buildable = CommerceOptions.Buildable.InsufficientCoins; } else { ret.buildable = CommerceOptions.Buildable.CommerceRequired; } } else { ret.buildable = CommerceOptions.Buildable.InsufficientResources; } return ret; }
public void executeActionNow(Card card) { Effect effect = card.effect; // I think the only effects that really need to be dealt with NOW are those // that affect game state (e.g. Babylon B, Play a discarded card.) if (effect == null) { switch(card.Id) { case CardId.Babylon_B_s2: // This is a signal that the Babylon player gets to take a 7th turn in this and future ages. // It only does something after the 6th turn, unlike other Powers such as Halikarnassos, Solomon, // and Roma (B) babylonPowerEnabled = true; break; case CardId.Halikarnassos_A_s2: case CardId.Halikarnassos_B_s1: case CardId.Halikarnassos_B_s2: case CardId.Halikarnassos_B_s3: phase = GamePhase.Halikarnassos; break; case CardId.Bilkis: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.Bilkis); break; case CardId.Solomon: phase = GamePhase.Solomon; break; case CardId.Rhodos_B_s1: // Add the 3 coins immediately. The 3 victory points will be included in total for wonders // The Military will also need to be included in the shield calculation. addTransaction(3); break; case CardId.Rhodos_B_s2: addTransaction(4); break; case CardId.Roma_B_s1: // Roma (B) stage 1: draw 4 more leaders from the pile of unused leaders // to add to the players list of recruitable leaders { for (int i = 0; i < 4; i++) { Card c = gm.deckList[0].GetTopCard(); draftedLeaders.Add(c); } string strMsg = "LeadrIcn"; foreach (Card c in draftedLeaders) { strMsg += string.Format("&{0}=", c.Id); } gm.gmCoordinator.sendMessage(this, strMsg); addTransaction(5); } break; case CardId.Roma_B_s2: case CardId.Roma_B_s3: // the player needs to choose another leader from his leader d phase = GamePhase.RomaB; break; case CardId.Courtesans_Guild: phase = GamePhase.Courtesan; break; case CardId.Gambling_Den: addTransaction(6); rightNeighbour.addTransaction(1); leftNeighbour.addTransaction(1); break; case CardId.Secret_Warehouse: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.SecretWarehouse); break; case CardId.Gambling_House: addTransaction(9); rightNeighbour.addTransaction(2); leftNeighbour.addTransaction(2); break; case CardId.Black_Market: if (!resourceMgr.GetCommerceEffect().HasFlag(ResourceManager.CommerceEffects.BlackMarket1)) resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.BlackMarket1); else resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.BlackMarket2); break; case CardId.Architect_Cabinet: hasArchitectCabinet = true; break; } } else if (effect is CommercialDiscountEffect) { switch (card.Id) { case CardId.Marketplace: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.Marketplace); break; case CardId.Clandestine_Dock_West: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.ClandestineDockWest); break; case CardId.Clandestine_Dock_East: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.ClandestineDockEast); break; case CardId.West_Trading_Post: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.WestTradingPost); break; case CardId.East_Trading_Post: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.EastTradingPost); break; case CardId.Olympia_B_s1: resourceMgr.AddCommerceEffect(ResourceManager.CommerceEffects.WestTradingPost | ResourceManager.CommerceEffects.EastTradingPost); break; } } else if (effect is PlayACardForFreeOncePerAgeEffect) { throw new Exception("This ability needs to be dealt with on the end-of-turn action queue."); } else if (effect is LossOfCoinsEffect) { LossOfCoinsEffect loce = effect as LossOfCoinsEffect; Player p = rightNeighbour; while (p != this) { switch(loce.lc) { case LossOfCoinsEffect.LossCounter.Constant: p.addCoinLossTransaction(loce.coinsLost); break; case LossOfCoinsEffect.LossCounter.ConflictToken: p.addCoinLossTransaction(p.conflictTokenOne + p.conflictTokenTwo + p.conflictTokenThree); break; case LossOfCoinsEffect.LossCounter.WonderStage: p.addCoinLossTransaction(p.currentStageOfWonder - 1); break; } p = p.rightNeighbour; } } else if (effect is DiplomacyEffect) { // Aspasia, Residence, Consulate, Embassy, Wonder stage on Byzantium & China B diplomacyEnabled = true; } else if ( effect is ScienceWildEffect || effect is ScienceEffect || effect is MilitaryEffect || effect is FreeLeadersEffect || effect is StructureDiscountEffect || effect is CopyScienceSymbolFromNeighborEffect) { // nothing to do; this card will be included in the end of game point total, or // - Military cards are used at the end of each age to resolve conflicts // - Science cards are used at the end of the game. // - Free Leaders effects are captured when the cards are put into play } else { throw new Exception("Unimplemented effect type"); } // any other effects do not require immediate action, they will be dealt with at the end of the turn, // end of the age, or the end of the game. }
/// <summary> /// Stored actions to be executed at the end of each turn /// </summary> /// <param name="s"></param> public void storeCardEffect(Card c) { if (c.effect is ResourceEffect || c.effect is CoinsAndPointsEffect || c.effect is PlayACardForFreeOncePerAgeEffect) { // the effects of these cards do not come into play until the next turn. // put them on the actions queue to be run after all players have turned // in their card. Any actions that require UI updates must go on here // (e.g. enabling the Olympia button) actions.Add(c.effect); } else { // other actions executeActionNow(c); } }
/// <summary> /// Add a card to the Player's played structure pile /// </summary> /// <param name="card"></param> public void addPlayedCardStructure(Card card) { playedStructure.Add(card); bUIRequiresUpdating = true; }
/// <summary> /// Set the coordinator and handle CommerceInformation, which contains all necessary UI data, from GameManager /// </summary> public NewCommerce(Coordinator coordinator, Card cardToBuild, bool isWonderStage, /* List<Card> cardList, */ /*string cardName, int wonderStage,*/ NameValueCollection qscoll) { //intialise all the UI components in the xaml file (labels, etc.) to avoid null pointer InitializeComponent(); this.coordinator = coordinator; leftName = "Left Neighbor"; middleName = "Player"; rightName = "Right Neighbor"; this.cardToBuild = cardToBuild; this.isStage = isWonderStage; if (isStage) { string strWonderName = qscoll["WonderStageCard"]; cardToBuild = coordinator.FindCard(strWonderName); } cardCost = cardToBuild.cost; string strLeaderDiscounts = qscoll["LeaderDiscountCards"]; if (strLeaderDiscounts != string.Empty) { foreach (string strCardId in strLeaderDiscounts.Split(',')) { Card leaderDiscountCard = coordinator.FindCard(strCardId); if (((StructureDiscountEffect)leaderDiscountCard.effect).discountedStructureType == cardToBuild.structureType) { leaderDiscountCardId = leaderDiscountCard.Id.ToString(); } } } leftRawMarket = qscoll["hasWestTradingPost"] != null; rightRawMarket = qscoll["hasEastTradingPost"] != null; marketplace = qscoll["hasMarketplace"] != null; leftDock = qscoll["hasClandestineDockWest"] != null; rightDock = qscoll["hasClandestineDockEast"] != null; hasSecretWarehouse = qscoll["hasSecretWarehouse"] != null; string strBlackMarkets = qscoll["nBlackMarket"]; if (strBlackMarkets != null) { nBlackMarkets = int.Parse(strBlackMarkets); } else { nBlackMarkets = 0; } PLAYER_COIN = int.Parse(qscoll["coin"]); CreateDag(middleDag, qscoll["PlayerResources"]); CreateDag(leftDag, qscoll["LeftResources"]); CreateDag(rightDag, qscoll["RightResources"]); //set the name labels leftNameLabel.Content = leftName; middleNameLabel.Content = middleName; rightNameLabel.Content = rightName; //set the player's total coins playerCoinsLabel.Content = PLAYER_COIN; bankCoinsLabel.Content = cardCost.coin; //set the market images leftRawImage.Source = FindResource(leftRawMarket ? "1r" : "2r") as BitmapImage; rightRawImage.Source = FindResource(rightRawMarket ? "1r" : "2r") as BitmapImage; leftManuImage.Source = rightManuImage.Source = FindResource(marketplace ? "1m" : "2m") as BitmapImage; if (leftDock) clandestineDockWestImage.Source = FindResource("Icons/Clandestine_Dock_West") as BitmapImage; if (rightDock) clandestineDockEastImage.Source = FindResource("Icons/Clandestine_Dock_East") as BitmapImage; if (leaderDiscountCardId != null) { middleDag.add(new ResourceEffect(false, "WSBOCGP")); } if (nBlackMarkets != 0) { string strBlackMarketResources = "WSBOCGP"; foreach (ResourceEffect re in middleDag.getResourceList(false)) { // The Black Market only excludes resources produced by this // city's brown or grey structures, which only have 1 or 2 resource types // So this excludes the Caravansery, Forum, and any Wonder stages. if (re.resourceTypes.Length <= 2) { foreach (char c in re.resourceTypes) { int index = strBlackMarketResources.IndexOf(c); if (index >= 0) strBlackMarketResources = strBlackMarketResources.Remove(index, 1); } } } if (strBlackMarketResources != string.Empty) { for (int i = 0; i < nBlackMarkets; i++) middleDag.add(new ResourceEffect(false, strBlackMarketResources)); } } hasBilkis = qscoll["Bilkis"] != null; if (hasBilkis) { imgBilkisPower.Visibility = Visibility.Visible; // Add Bilkis' choice middleDag.add(new ResourceEffect(false, "WSBOCGP")); } if (hasSecretWarehouse) { SecretWarehouseImage.Source = FindResource("Icons/Secret_Warehouse") as BitmapImage; } //generate mutable elements (DAG buttons, Price representations, currentResources, etc.) reset(); }