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); }
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; } } }
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); }