internal void player_Action(Player player, ref CleaningUpEventArgs e) { //e.CardsMovements[this].Destination = DeckLocation.Deck; e.CardsMovements.Remove(e.CardsMovements.Find(cm => cm.Card == this.PhysicalCard)); //e.CardsMovements.MoveToEnd(this); e.CurrentPlayer.AddCardToDeck(e.CurrentPlayer.RetrieveCardFrom(DeckLocation.InPlay, this.PhysicalCard), DeckPosition.Top); }
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)); } }
void player_CleaningUp(object sender, CleaningUpEventArgs e) { if (!e.CurrentPlayer.InPlay.Contains(this.PhysicalCard) || e.Actions.ContainsKey(TypeClass.WalledVillage)) return; if (_CanPutOnDeck) e.Actions[TypeClass.WalledVillage] = new CleaningUpAction(this, String.Format("Put {0} on top your deck", this.PhysicalCard), player_Action); }
private CardCollection GetSelectableCards(CleaningUpEventArgs e) { CardCollection allInPlayCards = new CardCollection(); allInPlayCards.AddRange(e.CardsMovements.Where(cm => ((cm.Card.Category & Cards.Category.Action) == Cards.Category.Action) && cm.CurrentLocation == DeckLocation.InPlay && (cm.Destination == DeckLocation.SetAside || cm.Destination == DeckLocation.Discard)).Select(cm => cm.Card)); // This is used to separate the In Play from the Set Aside for the Choice.MakeChoice call allInPlayCards.Add(new Universal.Dummy()); allInPlayCards.AddRange(e.CardsMovements.Where(cm => ((cm.Card.Category & Cards.Category.Action) == Cards.Category.Action) && cm.CurrentLocation == DeckLocation.SetAside && cm.Destination == DeckLocation.Discard).Select(cm => cm.Card)); if (allInPlayCards.FirstOrDefault() is Universal.Dummy) allInPlayCards.RemoveAt(0); if (allInPlayCards.LastOrDefault() is Universal.Dummy) allInPlayCards.RemoveAt(allInPlayCards.Count - 1); return allInPlayCards; }
internal void player_Action(Player player, ref CleaningUpEventArgs e) { if (_CleaningUpEventHandlers.Count > 0) { player.CleaningUp -= _CleaningUpEventHandlers[0]; _CleaningUpEventHandlers.RemoveAt(0); } CardCollection allInPlayCards = this.GetSelectableCards(e); if (allInPlayCards.Count > 0) { int schemeChoices = (int)e.Actions[TypeClass.Scheme].Data; Choice choice = new Choice( String.Format("Select up to {0} Action {1} to place on top of your deck", schemeChoices, Utilities.StringUtility.Plural("card", schemeChoices, false)), this, allInPlayCards, player, false, true, 0, schemeChoices); ChoiceResult result = player.MakeChoice(choice); _CardsToTopDeck.Clear(); foreach (Card cardToMove in result.Cards) _CardsToTopDeck.Add(cardToMove); if (_CardsToTopDeck.Count > 0) { _CardsDiscardingEventHandler = new Player.CardsDiscardingEventHandler(player_CardsDiscarding); e.CurrentPlayer.CardsDiscarding += _CardsDiscardingEventHandler; _CleanedUpEventHandler = new Player.CleanedUpEventHandler(player_CleanedUp); e.CurrentPlayer.CleanedUp += _CleanedUpEventHandler; } } }
void player_CleaningUp(object sender, CleaningUpEventArgs e) { if (e.Actions.ContainsKey(TypeClass.Scheme)) { e.Actions[TypeClass.Scheme].Data = ((int)e.Actions[TypeClass.Scheme].Data) + 1; return; } // Check to see if Scheme has been resolved yet if (_CardsToTopDeck.Count == 0) e.Actions[TypeClass.Scheme] = new CleaningUpAction(this, String.Format("Resolve {0}", this), player_Action) { Data = 1 }; }
void player_CleaningUp(object sender, CleaningUpEventArgs e) { if (_TurnStartedEventHandler != null) return; e.DrawSize = 3; if (e.CurrentPlayer._Game.TurnsTaken.Count > 1 && e.CurrentPlayer._Game.TurnsTaken[e.CurrentPlayer._Game.TurnsTaken.Count - 2].Player != e.CurrentPlayer) { e.NextPlayer = e.CurrentPlayer; e.NextGrantedBy = this; } }