public Boolean AddAction(Type sourceCard, Type card, CardsDiscardAction action) { Tuple <Type, Type> key = new Tuple <Type, Type>(sourceCard, card); if (this.Actions.ContainsKey(key)) { return(false); } this.Actions[key] = action; return(true); }
public void Discard(DeckLocation fromLocation, IEnumerable<Card> cards, CardsDiscardAction discardAction) { Discard(fromLocation, c => cards.Contains(c), discardAction); }
private void PerformCleanup() { // Sets up card movements to indicate where each card should go. CardMovementCollection cardsToMove = new CardMovementCollection(this.SetAside, c => c.CanCleanUp, DeckLocation.SetAside, DeckLocation.Discard); cardsToMove.AddRange(this.Hand, DeckLocation.Hand, DeckLocation.Discard); cardsToMove.AddRange(this.InPlay, DeckLocation.InPlay, DeckLocation.Discard); foreach (Card durationCard in this.InPlay.Where(c => !c.CanCleanUp)) cardsToMove[durationCard].Destination = DeckLocation.SetAside; IEnumerable<CardMovement> inPlayCards = cardsToMove.Where(cm => cm.CurrentLocation == DeckLocation.InPlay); ParallelQuery<CardMovement> pqCardsToMove = cardsToMove.AsParallel().Where(cm => cm.CurrentLocation == DeckLocation.InPlay && cm.Destination == DeckLocation.SetAside && cm.Card.ModifiedBy != null && cardsToMove.Contains(cm.Card.ModifiedBy.PhysicalCard) && cardsToMove[cm.Card.ModifiedBy.PhysicalCard].Destination == DeckLocation.Discard); pqCardsToMove.ForAll(cm => cardsToMove[cm.Card.ModifiedBy.PhysicalCard].Destination = DeckLocation.SetAside); int drawSize = 5; if (CleaningUp != null) { Boolean cancelled = false; // Possibly changing events that can happen in the game CleaningUpEventArgs cuea = null; do { cuea = new CleaningUpEventArgs(this, 5, ref cardsToMove); cuea.Cancelled |= cancelled; CleaningUp(this, cuea); OptionCollection options = new OptionCollection(); IEnumerable<Type> cardTypes = cuea.Actions.Keys; foreach (Type key in cardTypes) options.Add(new Option(cuea.Actions[key].Text, false)); if (options.Count > 0) { options.Sort(); Choice choice = new Choice("Performing Clean-up", options, this, cuea); ChoiceResult result = this.MakeChoice(choice); if (result.Options.Count > 0) cuea.Actions.First(kvp => kvp.Value.Text == result.Options[0]).Value.Method(this, ref cuea); else break; } else break; cancelled |= cuea.Cancelled; } while (CleaningUp != null); if (cuea != null) cancelled |= cuea.Cancelled; if (cancelled) return; if (cuea.NextPlayer != null) _CurrentTurn.NextPlayer = cuea.NextPlayer; _CurrentTurn.NextGrantedBy = cuea.NextGrantedBy; drawSize = cuea.DrawSize; } // Discard any Revealed cards (should be none?) this.DiscardRevealed(); CardsDiscardAction cdaHand = null; if (cardsToMove.Count(c => c.CurrentLocation == DeckLocation.Hand) > 0) cdaHand = new CardsDiscardAction(this, null, "Discard hand", player_DiscardHand, true) { Data = cardsToMove }; // Discard non-Duration (or Duration-modifying) cards in In Play & Set Aside at the same time this.Discard(DeckLocation.InPlayAndSetAside, cardsToMove.Where(cm => (cm.CurrentLocation == DeckLocation.InPlay || cm.CurrentLocation == DeckLocation.SetAside) && cm.Destination == DeckLocation.Discard).Select<CardMovement, Card>(cm => cm.Card), cdaHand); // Discard Hand this.AddCardsInto(DeckLocation.Discard, this.RetrieveCardsFrom(DeckLocation.Hand, c => cardsToMove[c].CurrentLocation == DeckLocation.Hand && cardsToMove[c].Destination == DeckLocation.Discard)); // Move Duration (and Duration-modifying) cards from In Play into Set Aside this.MoveInPlayToSetAside(c => cardsToMove.Contains(c) && cardsToMove[c].CurrentLocation == DeckLocation.InPlay && cardsToMove[c].Destination == DeckLocation.SetAside); // Move any cards that have had their Destination changed to their appropriate locations IEnumerable<Card> replaceCards = cardsToMove.Where(cm => cm.Destination == DeckLocation.Deck).Select(cm => cm.Card); if (replaceCards.Count() > 0) { Choice replaceChoice = new Choice("Choose order of cards to put back on your deck", null, replaceCards, this, true, replaceCards.Count(), replaceCards.Count()); ChoiceResult replaceResult = this.MakeChoice(replaceChoice); this.RetrieveCardsFrom(DeckLocation.InPlay, c => cardsToMove[c].CurrentLocation == DeckLocation.InPlay && replaceResult.Cards.Contains(c)); this.RetrieveCardsFrom(DeckLocation.SetAside, c => cardsToMove[c].CurrentLocation == DeckLocation.SetAside && replaceResult.Cards.Contains(c)); this.AddCardsToDeck(replaceResult.Cards, DeckPosition.Top); } #if DEBUG if (this.InPlay.Count > 0) throw new Exception("Something happened -- there are cards left in the player's In Play area!"); #endif if (CurrentTurn != null) CurrentTurn.Finished(); _Actions = _Buys = 0; _Currency.Coin.Value = 0; _Currency.Potion.Value = 0; _ActionsPlayed = 0; #if DEBUG // Check to see that there are no duplicate cards anywhere CardCollection allCards = new CardCollection(); allCards.AddRange(this.Hand); allCards.AddRange(this.Revealed); allCards.AddRange(this.Private); allCards.AddRange(this.InPlay); allCards.AddRange(this.SetAside); allCards.AddRange(this.DrawPile.LookThrough(c => true)); allCards.AddRange(this.DiscardPile.LookThrough(c => true)); foreach (CardMat mat in this.PlayerMats.Values) allCards.AddRange(mat); ParallelQuery<Card> duplicateCards = allCards.AsParallel().Where(c => allCards.Count(ct => ct == c) > 1); //IEnumerable<Card> duplicateCards = allCards.FindAll(c => allCards.Count(ct => ct == c) > 1); if (duplicateCards.Count() > 0) { // Ruh Roh throw new Exception("Duplicate cards found! Something went wrong!"); } #endif DrawHand(drawSize); if (CleanedUp != null) { CleanedUp(this, new CleanedUpEventArgs(this, drawSize)); } if (TurnEnded != null) { TurnEnded(this, new TurnEndedEventArgs(this)); } }
public void Discard(DeckLocation fromLocation, Predicate<Card> match, int count, CardsDiscardAction discardAction) { CardCollection matchingCards = this.ResolveDeck(fromLocation)[match]; if (count >= 0 && count < matchingCards.Count) { matchingCards.RemoveRange(count, matchingCards.Count - count); if (matchingCards.Count != count) throw new Exception("Incorrect number of cards found!"); } if (matchingCards.Count == 0) return; if (CardsDiscarding != null) { CardsDiscardEventArgs cdea = null; List<Object> handledBy = new List<Object>(); Boolean actionPerformed = false; Boolean cancelled = false; do { actionPerformed = false; cdea = new CardsDiscardEventArgs(fromLocation, matchingCards); cdea.Cancelled = cancelled; cdea.HandledBy.AddRange(handledBy); CardsDiscarding(this, cdea); handledBy = cdea.HandledBy; matchingCards = cdea.Cards; cancelled |= cdea.Cancelled; OptionCollection options = new OptionCollection(); IEnumerable<Tuple<Type, Type>> cardTypes = cdea.Actions.Keys; foreach (Tuple<Type, Type> key in cardTypes) options.Add(new Option(cdea.Actions[key].Text, cdea.Actions[key].IsRequired)); if (options.Count > 0) { if (discardAction != null && !cdea.HandledBy.Contains(this)) { cdea.AddAction(this.GetType(), discardAction); options.Add(new Option(discardAction.Text, true)); } options.Sort(); Choice choice = new Choice(String.Format("You are discarding {0}", Utilities.StringUtility.Plural("card", matchingCards.Count)), options, this, cdea); ChoiceResult result = this.MakeChoice(choice); if (result.Options.Count > 0) { CardsDiscardAction action = cdea.Actions.First(kvp => kvp.Value.Text == result.Options[0]).Value; cdea.Data = action.Data; action.Method(this, ref cdea); actionPerformed = true; handledBy = cdea.HandledBy; matchingCards = cdea.Cards; cancelled |= cdea.Cancelled; } } } while (CardsDiscarding != null && actionPerformed); if (cancelled) return; } this.RetrieveCardsFrom(fromLocation, matchingCards); if (CardsDiscard != null) { CardsDiscardEventArgs cdea = null; List<Object> handledBy = new List<Object>(); cdea = new CardsDiscardEventArgs(fromLocation, matchingCards); cdea.HandledBy.AddRange(handledBy); CardsDiscard(this, cdea); handledBy = cdea.HandledBy; matchingCards = cdea.Cards; } this.AddCardsInto(DeckLocation.Discard, matchingCards); if (CardsDiscarded != null) { CardsDiscardEventArgs cdea = null; List<Object> handledBy = new List<Object>(); Boolean actionPerformed = false; do { actionPerformed = false; cdea = new CardsDiscardEventArgs(fromLocation, matchingCards); cdea.HandledBy.AddRange(handledBy); CardsDiscarded(this, cdea); handledBy = cdea.HandledBy; OptionCollection options = new OptionCollection(); IEnumerable<Tuple<Type, Type>> cardTypes = cdea.Actions.Keys; foreach (Tuple<Type, Type> key in cardTypes) options.Add(new Option(cdea.Actions[key].Text, false)); if (options.Count > 0) { options.Sort(); Choice choice = new Choice(String.Format("You discarded {0}", Utilities.StringUtility.Plural("card", matchingCards.Count)), options, this, cdea); ChoiceResult result = this.MakeChoice(choice); if (result.Options.Count > 0) { cdea.Actions.First(kvp => kvp.Value.Text == result.Options[0]).Value.Method(this, ref cdea); actionPerformed = true; } } } while (CardsDiscarded != null && actionPerformed); } }
public void Discard(DeckLocation fromLocation, Predicate<Card> match, CardsDiscardAction discardAction) { Discard(fromLocation, match, -1, discardAction); }
public Boolean AddAction(Type sourceCard, Type card, CardsDiscardAction action) { Tuple<Type, Type> key = new Tuple<Type,Type>(sourceCard, card); if (this.Actions.ContainsKey(key)) return false; this.Actions[key] = action; return true; }
public Boolean AddAction(Type card, CardsDiscardAction action) { return AddAction(card, card, action); }
public Boolean AddAction(Type card, CardsDiscardAction action) { return(AddAction(card, card, action)); }