Exemple #1
0
        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns></returns>
        public Cascade Clone()
        {
            Cascade c = new Cascade();

            foreach (Card card in this)
            {
                c.Add(card.Clone());
            }
            return(c);
        }
Exemple #2
0
        /// <summary>
        /// Gets a tableaux from cascade of cards.
        /// </summary>
        /// <param name="cascade">The cascade to get tableaux from.</param>
        /// <param name="rules">The rules to use when determining what makes a tableaux.</param>
        /// <returns>
        /// A list of linking cards from the top of a cascade
        /// </returns>
        public static List <Card> GetTableauxFromCascade(Cascade cascade, IRules rules)
        {
            List <Card> tableaux = new List <Card>();

            for (int i = (cascade.Count - 1); i > 0; i--)
            {
                tableaux.Add(cascade[i]);
                if (!rules.DoCardsLinkInCascade(cascade[i], cascade[i - 1]))
                {
                    break;
                }
            }
            tableaux.Reverse();
            return(tableaux);
        }
        /// <summary>
        /// Checks to see if it is possible to move the specified <see cref="Card"/> to the specified <see cref="Cascade"/>.
        /// </summary>
        /// <param name="card">The <see cref="Card"/> to check if its possible to move to the specified <see cref="Cascade"/></param>
        /// <param name="cascade">The <see cref="Cascade"/> that will be holding the specified <see cref="Card"/></param>
        /// <returns><c>true</c> if the specified <see cref="Card"/> can be moved to the specified <see cref="Stack"/>; otherwise <c>false</c></returns>
        public virtual bool CanMoveToCascade(Card card, Cascade cascade)
        {
            if (!EnforceRules)
            {
                return(true);
            }

            if (cascade.Count == 0)
            {
                return(true);
            }
            if (DoCardsLinkInCascade(card, cascade.Last()))
            {
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Checks to see if it is possible to move the specified <see cref="Card"/> to the specified <see cref="Cascade"/>.
        /// </summary>
        /// <param name="tableaux">The tableaux to try to move to the cascade.</param>
        /// <param name="cascade">The <see cref="Cascade"/> that will be holding the specified <see cref="Card"/></param>
        /// <returns><c>true</c> if the specified <see cref="Card"/> can be moved to the specified <see cref="Stack"/>; otherwise <c>false</c></returns>
        public virtual bool CanMoveToCascade(List <Card> tableaux, Cascade cascade, Game game)
        {
            if (!EnforceRules)
            {
                return(true);
            }

            if (cascade.Count == 0)
            {
                return(true);
            }

            Card landingCard = cascade.Last();

            if (tableaux.Count == 1)
            {
                // MOVING ONE CARD
                if (this.CanMoveToCascade(tableaux.Last(), cascade))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                // MOVING MULTIPLE CARDS... FIND THE MAXIMUM NUMBER OF MOVES AVAILABLE.
                int maxMoves = Utility.GetMaximumMovesForGame(game, (cascade.Count == 0));
                int level    = 1;
                // WALK BACKWARDS OVER TABLEAUX TRYING EACH CARD AS A LINK TO LANDING CARD.
                for (int i = (tableaux.Count - 1); i >= 0; i--)
                {
                    // CHECK FOR THE LINK BETWEEN CURRENT TABLEAUX CARD AND LANDING CARD.
                    if (this.DoCardsLinkInCascade(tableaux[i], landingCard))
                    {
                        // CARDS LINK, CHECK TO SEE IF WE'VE EXCEEDED OUT MAX NUMBER OF MOVES ALLOWED.
                        if (level > maxMoves)
                        {
                            // MAX NUMBER OF MOVES EXCEEDED, MOVE FAILS
                            return(false);
                        }
                        else
                        {
                            // MOVE SUCCESSFUL
                            return(true);
                        }
                    }
                    else
                    {
                        // CARDS DO NOT LINK, CONTINUE ONTO THE NEXT TABLEAUX CARD.
                        if (i == 0)
                        {
                            // THIS IS THE LAST CARD IN THE TABLEAUX, MOVE FAILS BECAUSE NO LINKING CARDS FOUND IN STACK.
                            return(false);
                        }
                    }
                    level++;
                }
            }



            return(false);
        }
Exemple #5
0
        /// <summary>
        /// Moves the specified source.
        /// </summary>
        /// <param name="from">From.</param>
        /// <param name="to">To.</param>
        public virtual void Move(ITarget from, ITarget to)
        {
            MoveStartedEventArgs args = new MoveStartedEventArgs(from, to);

            OnMoveStarted(args);
            if (args.Cancel)
            {
                return;
            }

            if ((from is Cascade) && (to is Cascade))
            {
                if (((Cascade)from).Count == 0)
                {
                    throw new InvalidOperationException("There are no cards in the specified cascade to move to other cascade");
                }

                Cascade source = ((Cascade)from);
                Cascade dest   = ((Cascade)to);

                Card        landingCard = dest.LastOrDefault();
                List <Card> tableaux    = Utility.GetTableauxFromCascade(source, _rules);

                if (tableaux.Count == 1)
                {
                    // MOVING ONE CARD
                    if (_rules.CanMoveToCascade(source.Last(), dest))
                    {
                        dest.Add(source.Last());
                        source.Remove(source.Last());
                        OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                        return;
                    }
                    else
                    {
                        OnMoveFinished(MoveFinishedEventArgs.UnlinkingCardsResult);
                        return;
                    }
                }
                else
                {
                    // MOVING MULTIPLE CARDS... FIND THE MAXIMUM NUMBER OF MOVES AVAILABLE.
                    int maxMoves = Utility.GetMaximumMovesForGame(this, (dest.Count == 0));
                    int level    = 1;
                    // WALK BACKWARDS OVER TABLEAUX TRYING EACH CARD AS A LINK TO LANDING CARD.
                    for (int i = (tableaux.Count - 1); i >= 0; i--)
                    {
                        // CHECK FOR THE LINK BETWEEN CURRENT TABLEAUX CARD AND LANDING CARD.
                        if (_rules.DoCardsLinkInCascade(tableaux[i], landingCard))
                        {
                            // CARDS LINK, CHECK TO SEE IF WE'VE EXCEEDED OUT MAX NUMBER OF MOVES ALLOWED.
                            if (level > maxMoves)
                            {
                                // MAX NUMBER OF MOVES EXCEEDED, MOVE FAILS
                                OnMoveFinished(MoveFinishedEventArgs.NotEnoughFreeSpaceResult);
                            }
                            else
                            {
                                // MOVE CARDS STARTING BY ADDING ALL THE CARDS FROM TABLEAUX AND ADDING THEM TO DESTINATION.
                                for (int j = i; j < tableaux.Count; j++)
                                {
                                    dest.Add(tableaux[j]);
                                    source.Remove(tableaux[j]);
                                }
                                OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                                return;
                            }
                        }
                        else
                        {
                            // CARDS DO NOT LINK, CONTINUE ONTO THE NEXT TABLEAUX CARD.
                            if (i == 0)
                            {
                                // THIS IS THE LAST CARD IN THE TABLEAUX, MOVE FAILS BECAUSE NO LINKING CARDS FOUND IN STACK.
                                OnMoveFinished(MoveFinishedEventArgs.UnlinkingCardsResult);
                            }
                        }
                        level++;
                    }
                }
            }
            else if ((from is Cascade) && (to is Cell))
            {
                if (((Cascade)from).Count == 0)
                {
                    throw new InvalidOperationException("There are no cards in the specified cascade to move to cell");
                }

                if (((Cell)to).HasCard)
                {
                    OnMoveFinished(MoveFinishedEventArgs.OccupiedCellResult);
                    return;
                }

                Card movingCard = ((Cascade)from).Last();
                ((Cascade)from).Remove(movingCard);
                ((Cell)to).Card = movingCard;
                OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                return;
            }
            else if ((from is Cascade) && (to is Foundation))
            {
                if (((Cascade)from).Count == 0)
                {
                    throw new InvalidOperationException("There are no cards in the specified cascade to move to a foundation");
                }

                Card movingCard = ((Cascade)from).Last();
                if (_rules.CanMoveToFoundation(movingCard, ((Foundation)to)))
                {
                    ((Cascade)from).Remove(movingCard);
                    ((Foundation)to).Add(movingCard);
                    OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                    return;
                }
                else
                {
                    OnMoveFinished(MoveFinishedEventArgs.UnlinkingCardsResult);
                    return;
                }
            }
            else if ((from is Cell) && (to is Cell))
            {
                if (!((Cell)from).HasCard)
                {
                    throw new InvalidOperationException("There are no cards in the specified cell to move to cell");
                }

                if (((Cell)to).HasCard)
                {
                    OnMoveFinished(MoveFinishedEventArgs.OccupiedCellResult);
                    return;
                }
                else
                {
                    ((Cell)to).Card   = ((Cell)from).Card.Clone();
                    ((Cell)from).Card = null;
                    OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                    return;
                }
            }
            else if ((from is Cell) && (to is Cascade))
            {
                if (!((Cell)from).HasCard)
                {
                    throw new InvalidOperationException("There are no cards in the specified cell to move to cascade");
                }

                Cascade cascade = ((Cascade)to);
                Cell    cell    = ((Cell)from);

                if (_rules.CanMoveToCascade(cell.Card, cascade))
                {
                    Card movingCard = cell.Card.Clone();
                    cell.Card = null;
                    cascade.Add(movingCard);
                    OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                    return;
                }
                else
                {
                    OnMoveFinished(MoveFinishedEventArgs.UnlinkingCardsResult);
                    return;
                }
            }
            else if ((from is Cell) && (to is Foundation))
            {
                if (!((Cell)from).HasCard)
                {
                    throw new InvalidOperationException("There are no cards in the specified cell to move to foundation");
                }

                Card movingCard = ((Cell)from).Card.Clone();
                if (_rules.CanMoveToFoundation(movingCard, ((Foundation)to)))
                {
                    ((Cell)from).Card = null;
                    ((Foundation)to).Add(movingCard);
                    OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                    return;
                }
                else
                {
                    OnMoveFinished(MoveFinishedEventArgs.UnlinkingCardsResult);
                    return;
                }
            }
            else if ((from is Foundation) && (to is Cell))
            {
                if (_rules.AllowMoveFromFoundation)
                {
                    if (((Foundation)from).Count == 0)
                    {
                        throw new InvalidOperationException("There are no cards in the specified foundation to move to a cell");
                    }

                    if (((Cell)to).HasCard)
                    {
                        OnMoveFinished(MoveFinishedEventArgs.OccupiedCellResult);
                        return;
                    }
                    else
                    {
                        ((Cell)to).Card = ((Foundation)from).Last();
                        OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                        return;
                    }
                }
            }
            else if ((from is Foundation) && (to is Cascade))
            {
                if (_rules.AllowMoveFromFoundation)
                {
                    if (((Foundation)from).Count == 0)
                    {
                        throw new InvalidOperationException("There are no cards in the specified foundation to move to a cascade");
                    }

                    Card movingCard = ((Foundation)from).Last();
                    if (_rules.CanMoveToCascade(movingCard, ((Cascade)to)))
                    {
                        ((Foundation)from).Remove(movingCard);
                        ((Cascade)to).Add(movingCard);
                        OnMoveFinished(MoveFinishedEventArgs.SuccessfulResult);
                        return;
                    }
                    else
                    {
                        OnMoveFinished(MoveFinishedEventArgs.UnlinkingCardsResult);
                        return;
                    }
                }
            }
            else if ((from is Foundation) && (to is Foundation))
            {
                throw new InvalidOperationException("You cannot move a card from one foundation to another.");
            }
        }