private void AddSupplementaryMove(Move move, Pile pile, HoldingSet holdingSet, bool undoHolding)
        {
            // Add moves to the holding piles.
            for (int i = 0; i < holdingSet.Count; i++)
            {
                HoldingInfo holding     = holdingSet[i];
                Move        holdingMove = new Move(MoveType.Basic, MoveFlags.Holding, move.From, -holding.Length, holding.To);
                WorkingTableau.Move(holdingMove);
                SupplementaryMoves.Add(holdingMove);
            }

            // Add the primary move.
            WorkingTableau.UncheckedMove(new Move(move.From, move.FromRow, move.To));
            SupplementaryMoves.Add(move);

            if (undoHolding)
            {
                // Undo moves from the holding piles.
                for (int i = holdingSet.Count - 1; i >= 0; i--)
                {
                    HoldingInfo holding     = holdingSet[i];
                    Move        holdingMove = new Move(MoveType.Basic, MoveFlags.UndoHolding, holding.To, -holding.Length, move.To);
                    if (!WorkingTableau.TryMove(holdingMove))
                    {
                        break;
                    }
                    SupplementaryMoves.Add(holdingMove);
                }
            }
        }
Exemplo n.º 2
0
        public int AddHolding(HoldingSet holdingSet)
        {
            if (holdingSet.Count == 0)
            {
                return(-1);
            }
            int first = SupplementaryList.Count;

            for (int i = 0; i < holdingSet.Count; i++)
            {
                HoldingInfo holding     = holdingSet[i];
                int         holdingNext = i < holdingSet.Count - 1 ? SupplementaryList.Count + 1 : -1;
                SupplementaryList.Add(new Move(holding.From, holding.FromRow, holding.To, holding.Length, -1, holdingNext));
            }
            return(first);
        }
Exemplo n.º 3
0
        public int AddHolding(HoldingSet holdingSet1, HoldingSet holdingSet2)
        {
            if (holdingSet1.Count == 0 && holdingSet2.Count == 0)
            {
                return(-1);
            }
            if (holdingSet1.Count == 0)
            {
                return(AddHolding(holdingSet2));
            }
            if (holdingSet2.Count == 0)
            {
                return(AddHolding(holdingSet1));
            }
            int  first1      = AddHolding(holdingSet1);
            int  first2      = AddHolding(holdingSet2);
            int  last1       = first1 + holdingSet1.Count - 1;
            Move holdingMove = SupplementaryList[last1];

            holdingMove.Next         = first2;
            SupplementaryList[last1] = holdingMove;
            return(first1);
        }
Exemplo n.º 4
0
        private void Check(int from, int fromRow, int extraSuits, int maxExtraSuits)
        {
            if (fromRow == 0 && FindTableau.GetDownCount(from) != 0)
            {
                // Would turn over a card.
                return;
            }

            Pile fromPile       = FindTableau[from];
            Card fromCard       = fromPile[fromRow];
            Card fromCardParent = Card.Empty;
            bool inSequence     = true;

            if (fromRow != 0)
            {
                fromCardParent = fromPile[fromRow - 1];
                inSequence     = fromCardParent.IsTargetFor(fromCard);
            }
            HoldingStack fromHoldingStack = HoldingStacks[from];

            for (int to = 0; to < NumberOfPiles; to++)
            {
                Pile toPile = FindTableau[to];
                if (to == from || toPile.Count == 0)
                {
                    continue;
                }
                int splitRow = toPile.Count - RunFinder.GetRunUpAnySuit(to);
                int toRow    = -1;
                if (inSequence)
                {
                    // Try to find from counterpart in the first to run.
                    toRow = splitRow + (int)(toPile[splitRow].Face - fromCard.Face);
                    if (toRow < splitRow || toRow >= toPile.Count)
                    {
                        // Sequence doesn't contain our counterpart.
                        continue;
                    }
                }
                else
                {
                    // Try to swap with both runs out of sequence.
                    toRow = splitRow;
                    if (fromRow != 0 && !fromCardParent.IsTargetFor(toPile[toRow]))
                    {
                        // Cards don't match.
                        continue;
                    }
                }
                if (toRow == 0)
                {
                    if (fromRow == 0)
                    {
                        // No point in swap both entire piles.
                        continue;
                    }
                    if (FindTableau.GetDownCount(to) != 0)
                    {
                        // Would turn over a card.
                        continue;
                    }
                }
                else if (!toPile[toRow - 1].IsTargetFor(fromCard))
                {
                    // Cards don't match.
                    continue;
                }

                int toSuits = RunFinder.CountSuits(to, toRow);
                if (extraSuits + toSuits <= maxExtraSuits)
                {
                    // Swap with no holding piles.
                    Algorithm.ProcessCandidate(new Move(MoveType.Swap, from, fromRow, to, toRow));
                    continue;
                }

                HoldingStack toHoldingStack = HoldingStacks[to];
                if (extraSuits + toSuits > maxExtraSuits + fromHoldingStack.Suits + toHoldingStack.Suits)
                {
                    // Not enough spaces.
                    continue;
                }

                Used.Clear();
                Used.Add(from);
                Used.Add(to);
                int fromHoldingCount = 0;
                int toHoldingCount   = 0;
                int fromHoldingSuits = 0;
                int toHoldingSuits   = 0;
                while (true)
                {
                    if (fromHoldingCount < fromHoldingStack.Count &&
                        fromHoldingStack[fromHoldingCount].FromRow >= fromRow &&
                        !Used.Contains(fromHoldingStack[fromHoldingCount].To))
                    {
                        Used.Add(fromHoldingStack[fromHoldingCount].To);
                        fromHoldingSuits = fromHoldingStack[fromHoldingCount].Suits;
                        fromHoldingCount++;
                    }
                    else if (toHoldingCount < toHoldingStack.Count &&
                             toHoldingStack[toHoldingCount].FromRow >= toRow &&
                             !Used.Contains(toHoldingStack[toHoldingCount].To))
                    {
                        Used.Add(toHoldingStack[toHoldingCount].To);
                        toHoldingSuits = toHoldingStack[toHoldingCount].Suits;
                        toHoldingCount++;
                    }
                    else
                    {
                        // Out of options.
                        break;
                    }
                    if (extraSuits + toSuits > maxExtraSuits + fromHoldingSuits + toHoldingSuits)
                    {
                        // Not enough spaces.
                        continue;
                    }

                    // We've found a legal swap.
                    Debug.Assert(toRow == 0 || toPile[toRow - 1].IsTargetFor(fromCard));
                    Debug.Assert(fromRow == 0 || fromCardParent.IsTargetFor(toPile[toRow]));
                    HoldingSet fromHoldingSet = new HoldingSet(fromHoldingStack, fromHoldingCount);
                    HoldingSet toHoldingSet   = new HoldingSet(toHoldingStack, toHoldingCount);
                    Algorithm.ProcessCandidate(new Move(MoveType.Swap, from, fromRow, to, toRow, AddHolding(fromHoldingSet, toHoldingSet)));
                    break;
                }
            }
        }
Exemplo n.º 5
0
        public void Find()
        {
            Candidates.Clear();
            SupplementaryList.Clear();

            int numberOfSpaces       = FindTableau.NumberOfSpaces;
            int maxExtraSuits        = ExtraSuits(numberOfSpaces);
            int maxExtraSuitsToSpace = ExtraSuits(numberOfSpaces - 1);

            for (int from = 0; from < NumberOfPiles; from++)
            {
                HoldingStack holdingStack = HoldingStacks[from];
                Pile         fromPile     = FindTableau[from];
                holdingStack.Clear();
                holdingStack.StartingRow = fromPile.Count;
                int extraSuits = 0;
                for (int fromRow = fromPile.Count - 1; fromRow >= 0; fromRow--)
                {
                    Card fromCard = fromPile[fromRow];
                    if (fromCard.IsEmpty)
                    {
                        break;
                    }
                    if (fromRow < fromPile.Count - 1)
                    {
                        Card previousCard = fromPile[fromRow + 1];
                        if (!previousCard.IsSourceFor(fromCard))
                        {
                            break;
                        }
                        if (fromCard.Suit != previousCard.Suit)
                        {
                            // This is a cross-suit run.
                            extraSuits++;
                            if (extraSuits > maxExtraSuits + holdingStack.Suits)
                            {
                                break;
                            }
                        }
                    }

                    // Add moves to other piles.
                    if (fromCard.Face < Face.King)
                    {
                        PileList piles = FaceLists[(int)fromCard.Face + 1];
                        for (int i = 0; i < piles.Count; i++)
                        {
                            for (int count = 0; count <= holdingStack.Count; count++)
                            {
                                HoldingSet holdingSet = new HoldingSet(holdingStack, count);
                                if (extraSuits > maxExtraSuits + holdingSet.Suits)
                                {
                                    continue;
                                }
                                int to = piles[i];
                                if (from == to || holdingSet.Contains(from))
                                {
                                    continue;
                                }

                                // We've found a legal move.
                                Pile toPile = FindTableau[to];
                                Algorithm.ProcessCandidate(new Move(from, fromRow, to, toPile.Count, AddHolding(holdingSet)));

                                // Update the holding pile move.
                                int holdingSuits = extraSuits;
                                if (fromRow > 0 && (!fromPile[fromRow - 1].IsTargetFor(fromCard) || fromCard.Suit != fromPile[fromRow - 1].Suit))
                                {
                                    holdingSuits++;
                                }
                                if (holdingSuits > holdingStack.Suits)
                                {
                                    int length = holdingStack.FromRow - fromRow;
                                    holdingStack.Push(new HoldingInfo(from, fromRow, to, holdingSuits, length));
                                }

                                break;
                            }
                        }
                    }

                    // Add moves to an space.
                    for (int i = 0; i < FindTableau.NumberOfSpaces; i++)
                    {
                        int to = FindTableau.Spaces[i];

                        if (fromRow == 0)
                        {
                            // No point in moving from a full pile
                            // from one open position to another unless
                            // there are more cards to turn over.
                            if (FindTableau.GetDownCount(from) == 0)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // No point in moving anything less than
                            // as much as possible to an space.
                            Card nextCard = fromPile[fromRow - 1];
                            if (fromCard.Suit == nextCard.Suit)
                            {
                                if (nextCard.IsTargetFor(fromCard))
                                {
                                    continue;
                                }
                            }
                        }

                        for (int count = 0; count <= holdingStack.Count; count++)
                        {
                            HoldingSet holdingSet = new HoldingSet(holdingStack, count);
                            if (holdingSet.FromRow == fromRow)
                            {
                                // No cards left to move.
                                continue;
                            }
                            if (extraSuits > maxExtraSuitsToSpace + holdingSet.Suits)
                            {
                                // Not enough spaces.
                                continue;
                            }

                            // We've found a legal move.
                            Pile toPile = FindTableau[to];
                            Algorithm.ProcessCandidate(new Move(from, fromRow, to, toPile.Count, AddHolding(holdingSet)));
                            break;
                        }

                        // Only need to check the first space
                        // since all spaces are the same
                        // except for undealt cards.
                        break;
                    }
                }
            }
        }
        private void CheckOne(Move uncoveringMove)
        {
            // Prepare data structures.
            order = 0;
            int runs = Roots.Count - 1;

            Offload = OffloadInfo.Empty;
            SupplementaryMoves.Clear();

            // Initialize the pile map.
            WorkingTableau.Clear();
            WorkingTableau.CopyUpPiles(FindTableau);
            WorkingTableau.BlockDownPiles(FindTableau);

            if (!uncoveringMove.IsEmpty)
            {
                // Update the map for the uncovering move but don't
                // include its order contribution so we don't make
                // the uncovering move unless it is really necessary.
                MoveStack.Clear();
                for (int next = uncoveringMove.HoldingNext; next != -1; next = SupplementaryList[next].Next)
                {
                    Move holdingMove = SupplementaryList[next];
                    Move forwardMove = new Move(MoveType.Basic, MoveFlags.Holding, holdingMove.From, holdingMove.FromRow, holdingMove.To);
                    SupplementaryMoves.Add(forwardMove);
                    WorkingTableau.Move(forwardMove);
                    MoveStack.Push(new Move(MoveType.Basic, MoveFlags.UndoHolding, holdingMove.To, -holdingMove.ToRow, uncoveringMove.To));
                }
                SupplementaryMoves.Add(uncoveringMove);
                WorkingTableau.Move(uncoveringMove);
                while (MoveStack.Count > 0)
                {
                    Move holdingMove = MoveStack.Pop();
                    if (!WorkingTableau.IsValid(holdingMove))
                    {
                        break;
                    }
                    SupplementaryMoves.Add(holdingMove);
                    WorkingTableau.Move(holdingMove);
                }
            }

            // Check all the roots.
            int offloads = 0;

            for (int n = 1; n < Roots.Count; n++)
            {
                int  rootRow       = Roots[n];
                Card rootCard      = fromPile[rootRow];
                int  runLength     = Roots[n - 1] - Roots[n];
                int  suits         = fromPile.CountSuits(rootRow, rootRow + runLength);
                int  maxExtraSuits = ExtraSuits(GetNumberOfSpacesLeft());
                bool suitsMatch    = false;
                HoldingStack.Clear();

                // Try to find the best matching target.
                int to = -1;
                for (int i = 0; i < NumberOfPiles; i++)
                {
                    if (i == from)
                    {
                        continue;
                    }
                    Card card = WorkingTableau.GetCard(i);
                    if (card.IsTargetFor(rootCard))
                    {
                        if (!Offload.IsEmpty && to == Offload.To)
                        {
                            to         = -1;
                            suitsMatch = false;
                        }
                        if (!suitsMatch && card.Suit == rootCard.Suit)
                        {
                            to         = i;
                            suitsMatch = true;
                        }
                        else if (to == -1)
                        {
                            to = i;
                        }
                    }
                }

                MoveType type      = MoveType.Basic;
                bool     isOffload = false;
                if (to != -1)
                {
                    // Check for inverting.
                    if (!Offload.IsEmpty && to == Offload.To)
                    {
                        if (!Offload.SinglePile)
                        {
                            // Not enough spaces to invert.
                            return;
                        }
                    }

                    // Try to move this run.
                    if (suits - 1 > maxExtraSuits)
                    {
                        // Try using holding piles.
                        suits -= FindHolding(WorkingTableau, HoldingStack, false, fromPile, from, rootRow, rootRow + runLength, to, maxExtraSuits);
                        if (suits - 1 > maxExtraSuits)
                        {
                            // Not enough spaces.
                            return;
                        }
                    }

                    // Record the order improvement.
                    order += GetOrder(true, suitsMatch);
                }
                else
                {
                    if (!Offload.IsEmpty)
                    {
                        // Already have an offload.
                        return;
                    }

                    // It doesn't make sense to offload the last root.
                    if (rootRow == 0)
                    {
                        if (runs - 1 >= 2)
                        {
                            AddMove(order);
                        }
                        return;
                    }

                    // Check for partial offload.
                    if (offloads > 0)
                    {
                        AddMove(order);
                    }

                    // Try to offload this run.
                    if (GetNumberOfSpacesLeft() == 0)
                    {
                        // Not enough spaces.
                        return;
                    }
                    to = WorkingTableau.Spaces[0];
                    int maxExtraSuitsOnePile = ExtraSuits(GetNumberOfSpacesLeft() - 1) + 1;
                    if (suits > maxExtraSuitsOnePile)
                    {
                        // Try using holding piles.
                        suits -= FindHolding(WorkingTableau, HoldingStack, false, fromPile, from, rootRow, rootRow + runLength, to, maxExtraSuits);
                        if (suits > maxExtraSuits)
                        {
                            // Still not enough spaces.
                            return;
                        }
                    }
                    int numberOfSpacesUsed = SpacesUsed(GetNumberOfSpacesLeft(), suits);
                    Offload   = new OffloadInfo(to, numberOfSpacesUsed);
                    type      = Offload.SinglePile ? MoveType.Basic : MoveType.Unload;
                    isOffload = true;
                    offloads++;
                }

                // Do the move and the holding moves.
                HoldingSet holdingSet  = HoldingStack.Set;
                bool       undoHolding = !isOffload;
                AddSupplementaryMove(new Move(type, from, rootRow, to), fromPile, holdingSet, undoHolding);

                // Check whether the offload matches the new from or to piles.
                if (!isOffload)
                {
                    CheckOffload(to);
                }

                // Check whether any of the one run piles now match
                // the new from or to piles.
                for (int i = 0; i < OneRunPiles.Count; i++)
                {
                    if (CheckOneRun(to, OneRunPiles[i]))
                    {
                        // Found an emptying move.
                        return;
                    }
                }
            }

            // Check for unload that needs to be reloaded.
            if (!Offload.IsEmpty && !Offload.SinglePile)
            {
                if (FindTableau.GetDownCount(from) != 0)
                {
                    // Can't reload.
                    return;
                }
                else
                {
                    // Reload the offload onto the now empty space.
                    SupplementaryMoves.Add(new Move(MoveType.Reload, Offload.To, 0, from, 0));
                }
            }

            // Add the move.
            AddMove(order);
        }
Exemplo n.º 7
0
 public int AddHolding(HoldingSet holdingSet1, HoldingSet holdingSet2)
 {
     if (holdingSet1.Count == 0 && holdingSet2.Count == 0)
     {
         return -1;
     }
     if (holdingSet1.Count == 0)
     {
         return AddHolding(holdingSet2);
     }
     if (holdingSet2.Count == 0)
     {
         return AddHolding(holdingSet1);
     }
     int first1 = AddHolding(holdingSet1);
     int first2 = AddHolding(holdingSet2);
     int last1 = first1 + holdingSet1.Count - 1;
     Move holdingMove = SupplementaryList[last1];
     holdingMove.Next = first2;
     SupplementaryList[last1] = holdingMove;
     return first1;
 }
Exemplo n.º 8
0
        private void Check(int from, int fromRow, int extraSuits, int maxExtraSuits)
        {
            if (fromRow == 0 && FindTableau.GetDownCount(from) != 0)
            {
                // Would turn over a card.
                return;
            }

            Pile fromPile = FindTableau[from];
            Card fromCard = fromPile[fromRow];
            Card fromCardParent = Card.Empty;
            bool inSequence = true;
            if (fromRow != 0)
            {
                fromCardParent = fromPile[fromRow - 1];
                inSequence = fromCardParent.IsTargetFor(fromCard);
            }
            HoldingStack fromHoldingStack = HoldingStacks[from];
            for (int to = 0; to < NumberOfPiles; to++)
            {
                Pile toPile = FindTableau[to];
                if (to == from || toPile.Count == 0)
                {
                    continue;
                }
                int splitRow = toPile.Count - RunFinder.GetRunUpAnySuit(to);
                int toRow = -1;
                if (inSequence)
                {
                    // Try to find from counterpart in the first to run.
                    toRow = splitRow + (int)(toPile[splitRow].Face - fromCard.Face);
                    if (toRow < splitRow || toRow >= toPile.Count)
                    {
                        // Sequence doesn't contain our counterpart.
                        continue;
                    }
                }
                else
                {
                    // Try to swap with both runs out of sequence.
                    toRow = splitRow;
                    if (fromRow != 0 && !fromCardParent.IsTargetFor(toPile[toRow]))
                    {
                        // Cards don't match.
                        continue;
                    }
                }
                if (toRow == 0)
                {
                    if (fromRow == 0)
                    {
                        // No point in swap both entire piles.
                        continue;
                    }
                    if (FindTableau.GetDownCount(to) != 0)
                    {
                        // Would turn over a card.
                        continue;
                    }
                }
                else if (!toPile[toRow - 1].IsTargetFor(fromCard))
                {
                    // Cards don't match.
                    continue;
                }

                int toSuits = RunFinder.CountSuits(to, toRow);
                if (extraSuits + toSuits <= maxExtraSuits)
                {
                    // Swap with no holding piles.
                    Algorithm.ProcessCandidate(new Move(MoveType.Swap, from, fromRow, to, toRow));
                    continue;
                }

                HoldingStack toHoldingStack = HoldingStacks[to];
                if (extraSuits + toSuits > maxExtraSuits + fromHoldingStack.Suits + toHoldingStack.Suits)
                {
                    // Not enough spaces.
                    continue;
                }

                Used.Clear();
                Used.Add(from);
                Used.Add(to);
                int fromHoldingCount = 0;
                int toHoldingCount = 0;
                int fromHoldingSuits = 0;
                int toHoldingSuits = 0;
                while (true)
                {
                    if (fromHoldingCount < fromHoldingStack.Count &&
                        fromHoldingStack[fromHoldingCount].FromRow >= fromRow &&
                        !Used.Contains(fromHoldingStack[fromHoldingCount].To))
                    {
                        Used.Add(fromHoldingStack[fromHoldingCount].To);
                        fromHoldingSuits = fromHoldingStack[fromHoldingCount].Suits;
                        fromHoldingCount++;
                    }
                    else if (toHoldingCount < toHoldingStack.Count &&
                        toHoldingStack[toHoldingCount].FromRow >= toRow &&
                        !Used.Contains(toHoldingStack[toHoldingCount].To))
                    {
                        Used.Add(toHoldingStack[toHoldingCount].To);
                        toHoldingSuits = toHoldingStack[toHoldingCount].Suits;
                        toHoldingCount++;
                    }
                    else
                    {
                        // Out of options.
                        break;
                    }
                    if (extraSuits + toSuits > maxExtraSuits + fromHoldingSuits + toHoldingSuits)
                    {
                        // Not enough spaces.
                        continue;
                    }

                    // We've found a legal swap.
                    Debug.Assert(toRow == 0 || toPile[toRow - 1].IsTargetFor(fromCard));
                    Debug.Assert(fromRow == 0 || fromCardParent.IsTargetFor(toPile[toRow]));
                    HoldingSet fromHoldingSet = new HoldingSet(fromHoldingStack, fromHoldingCount);
                    HoldingSet toHoldingSet = new HoldingSet(toHoldingStack, toHoldingCount);
                    Algorithm.ProcessCandidate(new Move(MoveType.Swap, from, fromRow, to, toRow, AddHolding(fromHoldingSet, toHoldingSet)));
                    break;
                }
            }
        }
        private void AddSupplementaryMove(Move move, Pile pile, HoldingSet holdingSet, bool undoHolding)
        {
            // Add moves to the holding piles.
            for (int i = 0; i < holdingSet.Count; i++)
            {
                HoldingInfo holding = holdingSet[i];
                Move holdingMove = new Move(MoveType.Basic, MoveFlags.Holding, move.From, -holding.Length, holding.To);
                WorkingTableau.Move(holdingMove);
                SupplementaryMoves.Add(holdingMove);
            }

            // Add the primary move.
            WorkingTableau.UncheckedMove(new Move(move.From, move.FromRow, move.To));
            SupplementaryMoves.Add(move);

            if (undoHolding)
            {
                // Undo moves from the holding piles.
                for (int i = holdingSet.Count - 1; i >= 0; i--)
                {
                    HoldingInfo holding = holdingSet[i];
                    Move holdingMove = new Move(MoveType.Basic, MoveFlags.UndoHolding, holding.To, -holding.Length, move.To);
                    if (!WorkingTableau.TryMove(holdingMove))
                    {
                        break;
                    }
                    SupplementaryMoves.Add(holdingMove);
                }
            }
        }
Exemplo n.º 10
0
 public int AddHolding(HoldingSet holdingSet)
 {
     if (holdingSet.Count == 0)
     {
         return -1;
     }
     int first = SupplementaryList.Count;
     for (int i = 0; i < holdingSet.Count; i++)
     {
         HoldingInfo holding = holdingSet[i];
         int holdingNext = i < holdingSet.Count - 1 ? SupplementaryList.Count + 1 : -1;
         SupplementaryList.Add(new Move(holding.From, holding.FromRow, holding.To, holding.Length, -1, holdingNext));
     }
     return first;
 }
Exemplo n.º 11
0
        public void Find()
        {
            Candidates.Clear();
            SupplementaryList.Clear();

            int numberOfSpaces = FindTableau.NumberOfSpaces;
            int maxExtraSuits = ExtraSuits(numberOfSpaces);
            int maxExtraSuitsToSpace = ExtraSuits(numberOfSpaces - 1);

            for (int from = 0; from < NumberOfPiles; from++)
            {
                HoldingStack holdingStack = HoldingStacks[from];
                Pile fromPile = FindTableau[from];
                holdingStack.Clear();
                holdingStack.StartingRow = fromPile.Count;
                int extraSuits = 0;
                for (int fromRow = fromPile.Count - 1; fromRow >= 0; fromRow--)
                {
                    Card fromCard = fromPile[fromRow];
                    if (fromCard.IsEmpty)
                    {
                        break;
                    }
                    if (fromRow < fromPile.Count - 1)
                    {
                        Card previousCard = fromPile[fromRow + 1];
                        if (!previousCard.IsSourceFor(fromCard))
                        {
                            break;
                        }
                        if (fromCard.Suit != previousCard.Suit)
                        {
                            // This is a cross-suit run.
                            extraSuits++;
                            if (extraSuits > maxExtraSuits + holdingStack.Suits)
                            {
                                break;
                            }
                        }
                    }

                    // Add moves to other piles.
                    if (fromCard.Face < Face.King)
                    {
                        PileList piles = FaceLists[(int)fromCard.Face + 1];
                        for (int i = 0; i < piles.Count; i++)
                        {
                            for (int count = 0; count <= holdingStack.Count; count++)
                            {
                                HoldingSet holdingSet = new HoldingSet(holdingStack, count);
                                if (extraSuits > maxExtraSuits + holdingSet.Suits)
                                {
                                    continue;
                                }
                                int to = piles[i];
                                if (from == to || holdingSet.Contains(from))
                                {
                                    continue;
                                }

                                // We've found a legal move.
                                Pile toPile = FindTableau[to];
                                Algorithm.ProcessCandidate(new Move(from, fromRow, to, toPile.Count, AddHolding(holdingSet)));

                                // Update the holding pile move.
                                int holdingSuits = extraSuits;
                                if (fromRow > 0 && (!fromPile[fromRow - 1].IsTargetFor(fromCard) || fromCard.Suit != fromPile[fromRow - 1].Suit))
                                {
                                    holdingSuits++;
                                }
                                if (holdingSuits > holdingStack.Suits)
                                {
                                    int length = holdingStack.FromRow - fromRow;
                                    holdingStack.Push(new HoldingInfo(from, fromRow, to, holdingSuits, length));
                                }

                                break;
                            }
                        }
                    }

                    // Add moves to an space.
                    for (int i = 0; i < FindTableau.NumberOfSpaces; i++)
                    {
                        int to = FindTableau.Spaces[i];

                        if (fromRow == 0)
                        {
                            // No point in moving from a full pile
                            // from one open position to another unless
                            // there are more cards to turn over.
                            if (FindTableau.GetDownCount(from) == 0)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // No point in moving anything less than
                            // as much as possible to an space.
                            Card nextCard = fromPile[fromRow - 1];
                            if (fromCard.Suit == nextCard.Suit)
                            {
                                if (nextCard.IsTargetFor(fromCard))
                                {
                                    continue;
                                }
                            }
                        }

                        for (int count = 0; count <= holdingStack.Count; count++)
                        {
                            HoldingSet holdingSet = new HoldingSet(holdingStack, count);
                            if (holdingSet.FromRow == fromRow)
                            {
                                // No cards left to move.
                                continue;
                            }
                            if (extraSuits > maxExtraSuitsToSpace + holdingSet.Suits)
                            {
                                // Not enough spaces.
                                continue;
                            }

                            // We've found a legal move.
                            Pile toPile = FindTableau[to];
                            Algorithm.ProcessCandidate(new Move(from, fromRow, to, toPile.Count, AddHolding(holdingSet)));
                            break;
                        }

                        // Only need to check the first space
                        // since all spaces are the same
                        // except for undealt cards.
                        break;
                    }
                }
            }
        }
Exemplo n.º 12
0
 public int AddHolding(HoldingSet holdingSet1, HoldingSet holdingSet2)
 {
     return game.AddHolding(holdingSet1, holdingSet2);
 }
Exemplo n.º 13
0
 public int AddHolding(HoldingSet holdingSet)
 {
     return game.AddHolding(holdingSet);
 }
Exemplo n.º 14
0
 public int AddHolding(HoldingSet holdingSet1, HoldingSet holdingSet2)
 {
     return(game.AddHolding(holdingSet1, holdingSet2));
 }
Exemplo n.º 15
0
 public int AddHolding(HoldingSet holdingSet)
 {
     return(game.AddHolding(holdingSet));
 }