/// <summary> /// Tries the move all cards to appropriate foundations. /// </summary> public void TryMoveAllCardsToAppropriateFoundations() { // Go through the top card in each tableau - keeping // track of whether we moved one. var keepTrying = true; while (keepTrying) { var movedACard = false; if (Waste.Count > 0) { if (TryMoveCardToAppropriateFoundation(Waste.Last())) { movedACard = true; } } foreach (var tableau in _tableaus.Where(tableau => tableau.Count > 0) .Where(tableau => TryMoveCardToAppropriateFoundation(tableau.Last()))) { movedACard = true; } // We'll keep trying if we moved a card. keepTrying = movedACard; } }
/// <summary> /// Turns cards from the stock into the waste. /// </summary> private void DoTurnStock() { // If the stock is empty, put every card from the waste back into the stock. if (Stock.Count == 0) { foreach (var card in Waste) { card.IsFaceDown = true; card.IsPlayable = false; Stock.Insert(0, card); } Waste.Clear(); } else { // Everything in the waste so far must now have no offset. foreach (var wasteCard in Waste) { wasteCard.FaceUpOffset = 0; } if (Stock.Count > 0) { var card = Stock.Last(); Stock.Remove(card); card.IsFaceDown = false; card.IsPlayable = false; card.FaceUpOffset = 30; Waste.Add(card); } } // Everything in the waste must be not playable, // apart from the top card. foreach (var wasteCard in Waste) { wasteCard.IsPlayable = wasteCard == Waste.Last(); } }
/// <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="card">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 <PlayingCard> from, ObservableCollection <PlayingCard> to, PlayingCard card, bool checkOnly) { // The trivial case is where from and to are the same. if (from == to) { return(false); } // This is the complicated operation. int scoreModifier = 0; // 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 && card.Value == 0) || (to.Count > 0 && to.Last().Suit == card.Suit && (to.Last()).Value == (card.Value - 1))) { // Move from waste to foundation. scoreModifier = 10; } else { 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 && card.Value == 12) || (to.Count > 0 && to.Last().Colour != card.Colour && (to.Last()).Value == (card.Value + 1))) { // Move from waste to tableau. scoreModifier = 5; } else { 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 && card.Value == 0) || (to.Count > 0 && to.Last().Suit == card.Suit && (to.Last()).Value == (card.Value - 1))) { // Move from tableau to foundation. scoreModifier = 10; } else { 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 && card.Value == 12) || (to.Count > 0 && to.Last().Colour != card.Colour && (to.Last()).Value == (card.Value + 1))) { // Move from tableau to tableau. scoreModifier = 0; } else { 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 && card.Value == 12) || (to.Count > 0 && to.Last().Colour != card.Colour && (to.Last()).Value == (card.Value + 1))) { // Move from foundation to tableau. scoreModifier = -15; } else { 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) { // The move is valid, but has no impact on the score. scoreModifier = 0; } else { 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, card); Score += scoreModifier; Moves++; // 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); }
/// <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); }