Пример #1
0
		protected override ChoiceResult Decide_Stonemason(Choice choice)
		{
			switch (choice.ChoiceType)
			{
				case ChoiceType.Options:
					for (int index = choice.Options.Count - 1; index >= 0; index--)
					{
						// Overpay by as much as we can properly gain Action cards
						Currency overpayAmount = new DominionBase.Currency(choice.Options[index].Text);
						if (this._Game.Table.Supplies.Values.Any(s => s.CanGain() && (s.Category & Category.Action) == Category.Action && s.CurrentCost == overpayAmount))
							return new ChoiceResult(new List<String>() { choice.Options[index].Text });
					}
					return base.Decide_Stonemason(choice);
				case ChoiceType.Cards:
					return new ChoiceResult(new CardCollection(FindBestCardsToTrash(choice.Cards, 1)));

				case ChoiceType.Supplies:
					if (choice.Text.StartsWith("Gain a card costing less than"))
						return new ChoiceResult(FindBestCardForCost(choice.Supplies.Values, null, false));
					else
						return new ChoiceResult(FindBestCardForCost(choice.Supplies.Values, null, false));

				default:
					return base.Decide_Stonemason(choice);
			}
		}
Пример #2
0
		protected override ChoiceResult Decide_Doctor(Choice choice)
		{
			switch (choice.ChoiceType)
			{
				case ChoiceType.Options:
					if (choice.Text.StartsWith("Do you want to discard"))
					{
						// Choose to trash Copper roughly 1/3 of the time (a little odd, but it should work decently)
						// Let's change this to be a bit more aggressive
						// If it's a Curse, Ruins, Hovel, Overgrown Estate, or Rats, trash it
						// If it's a Copper, or if it's a Silver/Talisman/Quarry and we have at least 1 Platinum and at least 3 Ventures, or if it's a Loan and we have fewer than 3 Coppers
						if (choice.CardTriggers[0].CardType == Cards.Universal.TypeClass.Curse ||
							(choice.CardTriggers[0].Category & Category.Ruins) == Category.Ruins ||
							choice.CardTriggers[0].CardType == Cards.DarkAges.TypeClass.Hovel ||
							choice.CardTriggers[0].CardType == Cards.DarkAges.TypeClass.OvergrownEstate ||
							choice.CardTriggers[0].CardType == Cards.DarkAges.TypeClass.Rats ||
							choice.CardTriggers[0].CardType == Cards.Universal.TypeClass.Copper ||
							((choice.CardTriggers[0].CardType == Cards.Universal.TypeClass.Silver ||
								choice.CardTriggers[0].CardType == Cards.Prosperity.TypeClass.Talisman ||
								choice.CardTriggers[0].CardType == Cards.Prosperity.TypeClass.Quarry) &&
								this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.Prosperity.TypeClass.Platinum, true, false) > 0 &&
								this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.Prosperity.TypeClass.Venture, true, false) > 3) ||
							(choice.CardTriggers[0].CardType == Cards.Prosperity.TypeClass.Loan &&
								this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.Universal.TypeClass.Copper, true, false) < 3))
							return new ChoiceResult(new List<String>() { choice.Options[1].Text }); // Trash
						else if (
								((choice.CardTriggers[0].Category & Category.Victory) == Category.Victory &&
								(choice.CardTriggers[0].Category & Category.Action) != Category.Action &&
								(choice.CardTriggers[0].Category & Category.Treasure) != Category.Treasure) ||
							choice.CardTriggers[0].CardType == Cards.Universal.TypeClass.Copper
							)
							return new ChoiceResult(new List<String>() { choice.Options[0].Text }); // Discard
						else
							return new ChoiceResult(new List<String>() { choice.Options[2].Text }); // Put it back
					}
					else
					{
						for (int index = choice.Options.Count - 1; index >= 0; index--)
						{
							// Overpay by up to 4
							Currency overpayAmount = new DominionBase.Currency(choice.Options[index].Text);
							if (overpayAmount.Potion.Value > 0 || overpayAmount.Coin.Value > 4)
								continue;

							return new ChoiceResult(new List<String>() { choice.Options[index].Text });
						}
						return base.Decide_Doctor(choice);
					}

				case ChoiceType.Cards:
					CardCollection doctorCards = new CardCollection(choice.Cards);
					// Order them in roughly random order
					Utilities.Shuffler.Shuffle(doctorCards);
					return new ChoiceResult(doctorCards);

				case ChoiceType.SuppliesAndCards:
					// This should choose cards we don't want.  Obvious first targets are Curses, Ruins, Coppers, and perhaps Estates (early, early on)
					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.Universal.TypeClass.Curse, false, true) > 0)
						return new ChoiceResult(choice.Supplies.FirstOrDefault(kvp => kvp.Value.CardType == Cards.Universal.TypeClass.Curse).Value);

					// Let's get rid of Rats as quickly as possible -- We, as the AI, *HATE* Rats
					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.Rats, false, true) > 0)
						return new ChoiceResult(choice.Supplies.FirstOrDefault(kvp => kvp.Value.CardType == Cards.DarkAges.TypeClass.Rats).Value);

					// These priorities are based on nothing more than my intuition of how "good" each of the following Ruins cards are
					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.RuinedVillage, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.RuinedVillage) });
					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.RuinedMarket, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.RuinedMarket) });
					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.Survivors, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.Survivors) });

					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.Hovel, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.Hovel) });

					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.AbandonedMine, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.AbandonedMine) });
					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.RuinedLibrary, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.RuinedLibrary) });

					if (this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.DarkAges.TypeClass.OvergrownEstate, false, true) > 0)
						return new ChoiceResult(new CardCollection() { choice.Cards.FirstOrDefault(c => c.CardType == Cards.DarkAges.TypeClass.OvergrownEstate) });

					if (this.GameProgress > 0.65 && this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.Universal.TypeClass.Estate, false, true) > 0)
						return new ChoiceResult(choice.Supplies.FirstOrDefault(kvp => kvp.Value.CardType == Cards.Universal.TypeClass.Estate).Value);
					if (this.GameProgress < 0.65 && this.RealThis.CountAll(this.RealThis, c => c.CardType == Cards.Universal.TypeClass.Copper, false, true) > 0)
						return new ChoiceResult(choice.Supplies.FirstOrDefault(kvp => kvp.Value.CardType == Cards.Universal.TypeClass.Copper).Value);

					// We don't want to trash anything useful, so just choose Curse
					return new ChoiceResult(choice.Supplies.FirstOrDefault(kvp => kvp.Value.CardType == Cards.Universal.TypeClass.Curse).Value);

				default:
					return base.Decide_Doctor(choice);
			}
		}
Пример #3
0
		protected override ChoiceResult Decide_Herald(Choice choice)
		{
			switch (choice.ChoiceType)
			{
				case ChoiceType.Options:
					for (int index = choice.Options.Count - 1; index >= 0; index--)
					{
						// Overpay by up to the amount of cards we have in our discard pile,
						// excluding Coppers, Curses, Ruins, Victory cards, & Shelters
						Currency overpayAmount = new DominionBase.Currency(choice.Options[index].Text);
						if (overpayAmount.Potion.Value > 0)
							continue;

						if (this.DiscardPile.LookThrough(c => 
							c.CardType != Cards.Universal.TypeClass.Copper &&
							c.CardType != Cards.Universal.TypeClass.Curse &&
							(c.Category & Category.Ruins) != Category.Ruins &&
							(c.Category & Category.Shelter) != Category.Shelter &&
							c.Category != Category.Victory &&
							c.CardType != Cards.Hinterlands.TypeClass.Tunnel).Count >= overpayAmount.Coin.Value)
							return new ChoiceResult(new List<String>() { choice.Options[index].Text });
					}
					return base.Decide_Herald(choice);

				case ChoiceType.Cards:
					// Find highest in-deck value cards to put on top
					// While ignoring Victory cards, Curses, & Shelters
					CardCollection heraldCards = new CardCollection(choice.Cards
						.Where(c => c.Category != Category.Victory &&
							c.CardType != Cards.Universal.TypeClass.Curse &&
							c.CardType != Cards.Hinterlands.TypeClass.Tunnel &&
							(c.Category & Category.Shelter) != Category.Shelter)
						.OrderByDescending(c => ComputeValueInDeck(c))
						.Take(choice.Minimum));

					// If this doesn't lead to enough cards, then include Shelters
					if (heraldCards.Count < choice.Minimum)
						heraldCards.AddRange(choice.Cards
							.Where(c => (c.Category & Category.Shelter) == Category.Shelter)
							.Take(choice.Minimum - heraldCards.Count));

					// If this *still* doesn't include enough cards, include Victory cards
					if (heraldCards.Count < choice.Minimum)
						heraldCards.AddRange(choice.Cards
							.Where(c => c.Category == Category.Victory ||
								c.CardType == Cards.Hinterlands.TypeClass.Tunnel)
							.OrderByDescending(c => ComputeValueInDeck(c))
							.Take(choice.Minimum - heraldCards.Count));

					// Uh... our deck is absolutely shit.  Just take the first however many cards
					if (heraldCards.Count < choice.Minimum)
						heraldCards = new CardCollection(choice.Cards
						.OrderByDescending(c => ComputeValueInDeck(c))
						.Take(choice.Minimum));

					return new ChoiceResult(heraldCards);

				default:
					return base.Decide_Herald(choice);
			}
		}
Пример #4
0
		private void UpdateDisplayPlayer(DominionBase.Players.Player player)
		{
			bPlayTreasures.IsEnabled = false;
			bPlayCoinTokens.IsEnabled = false;
			bBuyPhase.IsEnabled = false;

			bTurnDone.IsEnabled = false;
			bUndo.IsEnabled = false;
			bPlayTreasures.Text = "Play basic _Treasures";
			if (player == null)
			{
				return;
			}

			if (player.PlayerType == DominionBase.Players.PlayerType.Human)
			{
				DominionBase.Cards.CardCollection treasures;
				DominionBase.Currency totalCurrency;
				String currency = String.Empty;
				switch (player.Phase)
				{
					case DominionBase.Players.PhaseEnum.Action:
						if (player.PlayerMode == DominionBase.Players.PlayerMode.Normal)
						{
							treasures = player.Hand[c =>
								(c.Category & DominionBase.Cards.Category.Treasure) == DominionBase.Cards.Category.Treasure &&
								(c.Location == DominionBase.Cards.Location.General ||
									c.CardType.GetMethod("Play", new Type[] { typeof(DominionBase.Players.Player) }).DeclaringType == typeof(DominionBase.Cards.Card))];

							bPlayTreasures.IsEnabled = treasures.Count > 0;
							totalCurrency = new DominionBase.Currency();
							foreach (DominionBase.Currency c in treasures.Select(t => t.Benefit.Currency))
								totalCurrency += c;
							currency = totalCurrency.ToStringInline();

							bPlayCoinTokens.IsEnabled = player.TokenPiles.ContainsKey(DominionBase.Cards.Guilds.TypeClass.CoinToken) && 
								player.TokenPiles[DominionBase.Cards.Guilds.TypeClass.CoinToken].Count > 0 &&
								player.CurrentTurn.CardsBought.Count == 0;
							bBuyPhase.IsEnabled = true;
							bTurnDone.IsEnabled = true;
						}
						break;

					case DominionBase.Players.PhaseEnum.ActionTreasure:
					case DominionBase.Players.PhaseEnum.BuyTreasure:
						if (player.PlayerMode == DominionBase.Players.PlayerMode.Normal)
						{
							treasures = player.Hand[c =>
								(c.Category & DominionBase.Cards.Category.Treasure) == DominionBase.Cards.Category.Treasure &&
								(c.Location == DominionBase.Cards.Location.General ||
									c.CardType.GetMethod("Play", new Type[] { typeof(DominionBase.Players.Player) }).DeclaringType == typeof(DominionBase.Cards.Card))];

							bPlayTreasures.IsEnabled = treasures.Count > 0;
							totalCurrency = new DominionBase.Currency();
							foreach (DominionBase.Currency c in treasures.Select(t => t.Benefit.Currency))
								totalCurrency += c;
							currency = totalCurrency.ToStringInline();

							bPlayCoinTokens.IsEnabled = player.TokenPiles.ContainsKey(DominionBase.Cards.Guilds.TypeClass.CoinToken) && 
								player.TokenPiles[DominionBase.Cards.Guilds.TypeClass.CoinToken].Count > 0 &&
								player.CurrentTurn.CardsBought.Count == 0;
							bBuyPhase.IsEnabled = true;
							bTurnDone.IsEnabled = true;
						}
						break;

					case DominionBase.Players.PhaseEnum.Buy:
						if (player.PlayerMode == DominionBase.Players.PlayerMode.Normal)
						{
							bTurnDone.IsEnabled = true;
						}
						break;

					case DominionBase.Players.PhaseEnum.Cleanup:
					case DominionBase.Players.PhaseEnum.Endgame:
						break;
				}

				bUndo.IsEnabled = player.CurrentTurn.CardsPlayed.Count > 0 && player.CurrentTurn.CardsPlayed[player.CurrentTurn.CardsPlayed.Count - 1].CanUndo && player.CurrentTurn.CardsBought.Count == 0;

				if (bPlayTreasures.IsEnabled)
					bPlayTreasures.Text = String.Format("Play basic _Treasures for: {0}", currency);
			}
		}