/// <summary> /// Actually moves the card. /// </summary> /// <param name="from">The stack to move from.</param> /// <param name="to">The stack to move to.</param> /// <param name="cardViewModel">The card.</param> private void DoMoveCard( ObservableCollection <PlayingCardViewModel> from, ObservableCollection <PlayingCardViewModel> to, PlayingCardViewModel cardViewModel) { // Indentify the run of cards we're moving. var run = new List <PlayingCardViewModel>(); for (var i = from.IndexOf(cardViewModel); i < from.Count; i++) { run.Add(from[i]); } // This function will move the card, as well as setting the // playable properties of the cards revealed. foreach (var runCard in run) { from.Remove(runCard); } foreach (var runCard in run) { to.Add(runCard); } // Are there any cards left in the from pile? if (from.Count > 0) { // Reveal the top card and make it playable. var topCard = from.Last(); topCard.IsFaceDown = false; topCard.IsPlayable = true; } }
/// <summary> /// Tries the move the card to its appropriate foundation. /// </summary> /// <param name="cardViewModel">The card.</param> /// <returns>True if card moved.</returns> public bool TryMoveCardToAppropriateFoundation(PlayingCardViewModel cardViewModel) { // Try the top of the waste first. if (Waste.LastOrDefault() == cardViewModel) { if (_foundations.Any(foundation => MoveCard(Waste, foundation, cardViewModel, false))) { return(true); } } // Is the card in a tableau? var inTableau = false; var i = 0; for (; i < _tableaus.Count && inTableau == false; i++) { inTableau = _tableaus[i].Contains(cardViewModel); } // It's if its not in a tablea and it's not the top // of the waste, we cannot move it. if (inTableau == false) { return(false); } // Try and move to each foundation. return(_foundations.Any(foundation => MoveCard(_tableaus[i - 1], foundation, cardViewModel, false))); }
/// <summary> /// Gets the card collection for the specified card. /// </summary> /// <param name="cardViewModel">The card.</param> /// <returns></returns> public IList <PlayingCardViewModel> GetCardCollection(PlayingCardViewModel cardViewModel) { if (Stock.Contains(cardViewModel)) { return(Stock); } if (Waste.Contains(cardViewModel)) { return(Waste); } foreach (var foundation in _foundations.Where(foundation => foundation.Contains(cardViewModel))) { return(foundation); } return(_tableaus.FirstOrDefault(tableau => tableau.Contains(cardViewModel))); }
/// <summary> /// Moves the card. /// </summary> /// <param name="from">The set we're moving from.</param> /// <param name="to">The set we're moving to.</param> /// <param name="cardViewModel">The card we're moving.</param> /// <param name="checkOnly">if set to <c>true</c> we only check if we CAN move, but don't actually move.</param> /// <returns>True if a card was moved.</returns> public bool MoveCard( ObservableCollection <PlayingCardViewModel> from, ObservableCollection <PlayingCardViewModel> to, PlayingCardViewModel cardViewModel, bool checkOnly) { // The trivial case is where from and to are the same. if (from == to) { return(false); } // Are we moving from the waste? if (from == Waste) { // Are we moving to a foundation? if (_foundations.Contains(to)) { // We can move to a foundation only if: // 1. It is empty and we are an ace. // 2. It is card SN and we are suit S and Number N+1 if ((to.Count != 0 || cardViewModel.Value != 0) && (to.Count <= 0 || to.Last().Suit != cardViewModel.Suit || to.Last().Value != cardViewModel.Value - 1)) { return(false); } } // Are we moving to a tableau? else if (_tableaus.Contains(to)) { // We can move to a tableau only if: // 1. It is empty and we are a king. // 2. It is card CN and we are color !C and Number N-1 if ((to.Count != 0 || cardViewModel.Value != 12) && (to.Count <= 0 || to.Last().Colour == cardViewModel.Colour || to.Last().Value != cardViewModel.Value + 1)) { return(false); } } // Any other move from the waste is wrong. else { return(false); } } // Are we moving from a tableau? else if (_tableaus.Contains(from)) { // Are we moving to a foundation? if (_foundations.Contains(to)) { // We can move to a foundation only if: // 1. It is empty and we are an ace. // 2. It is card SN and we are suit S and Number N+1 if ((to.Count != 0 || cardViewModel.Value != 0) && (to.Count <= 0 || to.Last().Suit != cardViewModel.Suit || to.Last().Value != cardViewModel.Value - 1)) { return(false); } } // Are we moving to another tableau? else if (_tableaus.Contains(to)) { // We can move to a tableau only if: // 1. It is empty and we are a king. // 2. It is card CN and we are color !C and Number N-1 if ((to.Count != 0 || cardViewModel.Value != 12) && (to.Count <= 0 || to.Last().Colour == cardViewModel.Colour || to.Last().Value != cardViewModel.Value + 1)) { return(false); } } // Any other move from a tableau is wrong. else { return(false); } } // Are we moving from a foundation? else if (_foundations.Contains(from)) { // Are we moving to a tableau? if (_tableaus.Contains(to)) { // We can move to a tableau only if: // 1. It is empty and we are a king. // 2. It is card CN and we are color !C and Number N-1 if ((to.Count != 0 || cardViewModel.Value != 12) && (to.Count <= 0 || to.Last().Colour == cardViewModel.Colour || to.Last().Value != cardViewModel.Value + 1)) { return(false); } } // Are we moving to another foundation? else if (_foundations.Contains(to)) { // We can move from a foundation to a foundation only // if the source foundation has one card (the ace) and the // destination foundation has no cards). if (from.Count != 1 || to.Count != 0) { return(false); } } // Any other move from a foundation is wrong. else { return(false); } } else { return(false); } // If we were just checking, we're done. if (checkOnly) { return(true); } // If we've got here we've passed all tests // and move the card and update the score. DoMoveCard(from, to, cardViewModel); // If we have moved from the waste, we must // make sure that the top of the waste is playable. if (from == Waste && Waste.Count > 0) { Waste.Last().IsPlayable = true; } // Check for victory. CheckForVictory(); return(true); }