Esempio 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);
                }
            }
        }
Esempio n. 2
0
        private int MoveOffUsingSpaces(int from, int fromRow, int to, int remainingSuits, int n)
        {
            int suits = Math.Min(remainingSuits, n);

            if (Diagnostics)
            {
                Utils.WriteLine("MOUS: {0} -> {1}: {2}", from, to, suits);
            }
            for (int i = n - suits; i < n; i++)
            {
                // Move as much as possible but not too much.
                Pile fromPile       = Tableau[from];
                int  currentFromRow = fromPile.Count - Tableau.GetRunUp(from, fromPile.Count);
                if (currentFromRow < fromRow)
                {
                    currentFromRow = fromRow;
                }
                int runLength = fromPile.Count - currentFromRow;
                MakeSimpleMove(from, -runLength, Spaces[i]);
                MoveStack.Push(new Move(Spaces[i], -runLength, to));
            }
            for (int i = n - 2; i >= n - suits; i--)
            {
                int runLength = Tableau[Spaces[i]].Count;
                MakeSimpleMove(Spaces[i], -runLength, Spaces[n - 1]);
                MoveStack.Push(new Move(Spaces[n - 1], -runLength, Spaces[i]));
            }
            return(suits);
        }
        void UseMovementStack()
        {
            GameObject capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule);
            MoveStack  mover   = capsule.AddComponent <MoveStack>();

            mover.AddMove(Moves.None);
            mover.AddMove(Moves.Forward);
            mover.AddMove(Moves.None);
            mover.AddMove(Moves.None);
            mover.AddMove(Moves.Right);
            mover.AddMove(Moves.None);
            mover.AddMove(Moves.Right);
            mover.Move();
        }
Esempio n. 4
0
        private void UnloadToSpaces(int from, int fromRow, int to)
        {
            if (Diagnostics)
            {
                Utils.WriteLine("ULTS: {0}/{1} -> {2}", from, fromRow, to);
            }
            int numberOfSpaces = Tableau.NumberOfSpaces;
            int suits          = Tableau.CountSuits(from, fromRow);

            if (suits > ExtraSuits(numberOfSpaces))
            {
                throw new InvalidMoveException("insufficient spaces");
            }
            Spaces.Copy(Tableau.Spaces);
            int totalSuits      = Tableau.CountSuits(from, fromRow);
            int remainingSuits  = totalSuits;
            int currrentFromRow = Tableau[from].Count;

            for (int n = 0; n < numberOfSpaces; n++)
            {
                int m = Math.Min(numberOfSpaces, n + remainingSuits);
                for (int i = m - 1; i >= n; i--)
                {
                    int runLength = Tableau.GetRunUp(from, currrentFromRow);
                    currrentFromRow -= runLength;
                    currrentFromRow  = Math.Max(currrentFromRow, fromRow);
                    MakeSimpleMove(from, -runLength, Spaces[i]);
                    MoveStack.Push(new Move(Spaces[i], -runLength, to));
                    remainingSuits--;
                }
                for (int i = n + 1; i < m; i++)
                {
                    int runLength = Tableau[Spaces[i]].Count;
                    MakeSimpleMove(Spaces[i], -runLength, Spaces[n]);
                    MoveStack.Push(new Move(Spaces[n], -runLength, Spaces[i]));
                }
                if (remainingSuits == 0)
                {
                    break;
                }
            }
        }
Esempio n. 5
0
 /// <summary>
 /// Synchronizes the Moves and MoveStack lists if the specified move
 /// is not already in both lists.
 /// </summary>
 /// <param name="move">The move to check.</param>
 private void SyncMoveStack(ISpace move)
 {
     // If the move diverges from the move stack, synchronize
     // the Moves and MoveStack lists.
     if (Moves.Count > MoveStack.Count)
     {
         // The move goes beyond the MoveStack, so add
         // the move to the MoveStack.
         MoveStack.Add(move);
     }
     else
     {
         var stackMove = MoveStack[Moves.Count - 1];
         if ((stackMove == null && stackMove != move) ||
             (stackMove != null && !stackMove.Equals(move)))
         {
             // The move is different from same position in
             // the MoveStack, so reset the MoveStack to match
             // the Moves list.
             MoveStack = new List <ISpace>(Moves);
         }
     }
 }
Esempio n. 6
0
        /// <summary>
        /// Returns the game to the state it was in after the specified number of turns.
        /// </summary>
        /// <param name="turnCount">The number of turns.</param>
        /// <returns>A list of the spaces affected by the last move, starting with the space
        /// of the move and including the spaces of all the pieces captured by the move.</returns>
        private IAsyncOperation <IList <ISpace> > ResetAsync(int turnCount)
        {
            if (turnCount < 0 || turnCount > MoveStack.Count)
            {
                throw new ArgumentException("must be 0 or greater and " +
                                            "no higher than MoveStack.Count.", "turnCount");
            }

            if (turnCount == Moves.Count)
            {
                throw new ArgumentException("must be different than " +
                                            "Moves.Count.", "turnCount");
            }

            // Use a lock to prevent this method from modifying the game state at
            // the same time a different thread is in the locked MoveAsync method.
            lock (_lockObject)
            {
                IList <ISpace> newMoves;
                if (turnCount < Moves.Count)
                {
                    // Backward navigation resets the board to its initial state in
                    // preparation for replaying all moves up to the indicated move.
                    SetUpEmptyBoard();
                    newMoves = Moves.Take(turnCount).ToList();
                    Moves.Clear();
                }
                else
                {
                    // Forward navigation retrieves previously-undone moves in
                    // preparation for their replay from the current board state.
                    newMoves = MoveStack.Skip(Moves.Count)
                               .Take(turnCount - Moves.Count).ToList();
                }
                return(MoveAsync(newMoves));
            }
        }
Esempio n. 7
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");
            }
        }
Esempio n. 8
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);
            }
        }