Ejemplo n.º 1
0
 /// <summary>
 /// Raises the <see cref="E:MoveStarted"/> event.
 /// </summary>
 /// <param name="args">The <see cref="FreeCell.Core.MoveStartedEventArgs"/> instance containing the event data.</param>
 public void OnMoveStarted(MoveStartedEventArgs args)
 {
     if (MoveStarted != null)
     {
         MoveStarted(this, args);
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Raises the <see cref="E:MoveStarted"/> event.
 /// </summary>
 /// <param name="args">The <see cref="FreeCell.Core.MoveStartedEventArgs"/> instance containing the event data.</param>
 public void OnMoveStarted(MoveStartedEventArgs args)
 {
     if (MoveStarted != null)
         MoveStarted(this, args);
 }
Ejemplo n.º 3
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.");
            }
        }
Ejemplo n.º 4
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.");
            }
        }