Ejemplo n.º 1
0
 private void MakeSimpleMove(int from, int fromRow, int to)
 {
     if (fromRow < 0)
     {
         fromRow += Tableau[from].Count;
     }
     if (Diagnostics)
     {
         Utils.WriteLine("    MSM: {0}/{1} -> {2}", from, fromRow, to);
     }
     Debug.Assert(Tableau[from].Count != 0);
     Debug.Assert(fromRow < Tableau[from].Count);
     Debug.Assert(Tableau.CountSuits(from, fromRow) == 1);
     Debug.Assert(Tableau[to].Count == 0 || Tableau[from][fromRow].IsSourceFor(Tableau[to][Tableau[to].Count - 1]));
     MakeMove(new Move(from, fromRow, to, Tableau[to].Count));
 }
Ejemplo n.º 2
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;
                }
            }
        }
Ejemplo n.º 3
0
        private string SafeMakeMoveUsingSpaces(int from, int fromRow, int to)
        {
            if (fromRow < 0)
            {
                fromRow += Tableau[from].Count;
            }
            if (Diagnostics)
            {
                Utils.WriteLine("MMUS: {0}/{1} -> {2}", from, fromRow, to);
            }
            int toRow      = Tableau[to].Count;
            int extraSuits = Tableau.CountSuits(from, fromRow) - 1;

            if (extraSuits < 0)
            {
                return("not a single run");
            }
            if (extraSuits == 0)
            {
                MakeSimpleMove(from, fromRow, to);
                return(null);
            }
            int numberOfSpaces = Tableau.NumberOfSpaces;

            Spaces.Copy(Tableau.Spaces);
            if (toRow == 0)
            {
                Spaces.Remove(to);
                numberOfSpaces--;
            }
            int maxExtraSuits = ExtraSuits(numberOfSpaces);

            if (extraSuits > maxExtraSuits)
            {
                return("insufficient spaces");
            }
            int suits          = 0;
            int currentFromRow = Tableau[from].Count;

            SpacesMoveStack.Clear();
            for (int n = numberOfSpaces; n > 0; n--)
            {
                for (int i = 0; i < n; i++)
                {
                    int runLength = Tableau.GetRunUp(from, currentFromRow);
                    currentFromRow -= runLength;
                    MakeSimpleMove(from, -runLength, Spaces[i]);
                    SpacesMoveStack.Push(new Move(Spaces[i], -runLength, to));
                    suits++;
                    if (suits == extraSuits)
                    {
                        break;
                    }
                }
                if (suits == extraSuits)
                {
                    break;
                }
                for (int i = n - 2; i >= 0; i--)
                {
                    int runLength = Tableau[Spaces[i]].Count;
                    MakeSimpleMove(Spaces[i], -runLength, Spaces[n - 1]);
                    SpacesMoveStack.Push(new Move(Spaces[n - 1], -runLength, Spaces[i]));
                }
            }
            MakeSimpleMove(from, fromRow, to);
            while (SpacesMoveStack.Count != 0)
            {
                Move move = SpacesMoveStack.Pop();
                MakeSimpleMove(move.From, move.FromRow, move.To);
            }
            return(null);
        }
Ejemplo n.º 4
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);
            }
        }