Exemplo n.º 1
0
        private void MakeMove(Node node, int i)
        {
            Move move    = node.Moves[i];
            bool toEmpty = move.Type == MoveType.Basic && WorkingTableau[move.To].Count == 0;

            MoveStack.Clear();
            for (int next = move.HoldingNext; next != -1; next = node.SupplementaryList[next].Next)
            {
                Move holdingMove = node.SupplementaryList[next];
                WorkingTableau.Move(new Move(MoveType.Basic, MoveFlags.Holding, holdingMove.From, holdingMove.FromRow, holdingMove.To));
                int undoTo = holdingMove.From == move.From ? move.To : move.From;
                MoveStack.Push(new Move(MoveType.Basic, MoveFlags.UndoHolding, holdingMove.To, -holdingMove.ToRow, undoTo));
            }
            WorkingTableau.Move(new Move(move.Type, move.From, move.FromRow, move.To, move.ToRow));
            if (!toEmpty)
            {
                while (MoveStack.Count > 0)
                {
                    Move holdingMove = MoveStack.Pop();
                    if (!WorkingTableau.IsValid(holdingMove))
                    {
                        break;
                    }
                    WorkingTableau.Move(holdingMove);
                }
            }
        }
Exemplo n.º 2
0
        private void MakeCompositeSinglePileMove(int first)
        {
            if (Diagnostics)
            {
                Utils.WriteLine("MCSPM");
            }
            bool aborted     = false;
            int  offloadPile = -1;

            MoveStack.Clear();
            for (int next = first; next != -1; next = SupplementaryList[next].Next)
            {
                int  numberOfSpaces = Tableau.NumberOfSpaces;
                Move move           = Tableau.Normalize(SupplementaryList[next]);
                if (move.Type == MoveType.Unload)
                {
                    offloadPile = move.To;
                    UnloadToSpaces(move.From, move.FromRow, -1);
                }
                else if (move.Type == MoveType.Reload)
                {
                    if (Diagnostics)
                    {
                        Utils.WriteLine("RL:");
                    }
                    while (MoveStack.Count != 0)
                    {
                        Move subMove = MoveStack.Pop();
                        int  to      = subMove.To != -1 ? subMove.To : move.To;
                        MakeSimpleMove(subMove.From, subMove.FromRow, to);
                    }
                    offloadPile = -1;
                }
                else if (move.Flags.UndoHolding())
                {
                    TryMakeMoveUsingSpaces(move);
                }
                else
                {
                    if (!TryMakeMoveUsingSpaces(move))
                    {
                        // Things got messed up due to a discard.  There might
                        // be another pile with the same target.
                        bool foundAlternative = false;
                        Pile fromPile         = Tableau[move.From];
                        if (move.From >= 0 && move.From < fromPile.Count)
                        {
                            Card fromCard = fromPile[move.FromRow];
                            for (int to = 0; to < NumberOfPiles; to++)
                            {
                                if (to == move.From)
                                {
                                    continue;
                                }
                                Pile toPile = Tableau[to];
                                if (toPile.Count == 0)
                                {
                                    continue;
                                }
                                if (!fromCard.IsSourceFor(toPile[toPile.Count - 1]))
                                {
                                    continue;
                                }
                                if (TryMakeMoveUsingSpaces(new Move(move.From, move.FromRow, to)))
                                {
                                    foundAlternative = true;
                                }
                                break;
                            }
                        }
                        if (!foundAlternative)
                        {
                            // This move is hopelessly messed up.
                            aborted = true;
                            break;
                        }
                    }
                }
            }
            if (!aborted && MoveStack.Count != 0)
            {
                throw new Exception("missing reload move");
            }
        }
Exemplo n.º 3
0
        private void SwapUsingSpaces(int from, int fromRow, int to, int toRow)
        {
            if (Diagnostics)
            {
                Utils.WriteLine("SWUS: {0}/{1} -> {2}/{3}", from, fromRow, to, toRow);
            }
            int fromSuits = Tableau.CountSuits(from, fromRow);
            int toSuits   = Tableau.CountSuits(to, toRow);

            if (fromSuits == 0 && toSuits == 0)
            {
                return;
            }
            if (fromSuits == 0)
            {
                MakeMoveUsingSpaces(to, toRow, from);
                return;
            }
            if (toSuits == 0)
            {
                MakeMoveUsingSpaces(from, fromRow, to);
                return;
            }
            int numberOfSpaces = Tableau.NumberOfSpaces;

            Spaces.Copy(Tableau.Spaces);
            if (fromSuits + toSuits - 1 > ExtraSuits(numberOfSpaces))
            {
                throw new InvalidMoveException("insufficient spaces");
            }
            MoveStack.Clear();
            for (int n = numberOfSpaces; n > 0 && fromSuits + toSuits > 1; n--)
            {
                if (fromSuits >= toSuits)
                {
                    int moveSuits = toSuits != 0 ? fromSuits : fromSuits - 1;
                    fromSuits -= MoveOffUsingSpaces(from, fromRow, to, moveSuits, n);
                }
                else
                {
                    int moveSuits = fromSuits != 0 ? toSuits : toSuits - 1;
                    toSuits -= MoveOffUsingSpaces(to, toRow, from, moveSuits, n);
                }
            }
            if (fromSuits + toSuits != 1 || fromSuits * toSuits != 0)
            {
                throw new Exception("bug: left over swap runs");
            }
            if (fromSuits == 1)
            {
                MakeSimpleMove(from, fromRow, to);
            }
            else
            {
                MakeSimpleMove(to, toRow, from);
            }
            while (MoveStack.Count != 0)
            {
                Move move = MoveStack.Pop();
                MakeSimpleMove(move.From, move.FromRow, move.To);
            }
        }