Beispiel #1
0
        public static IEnumerable <Cell[, ]> Solve(Cell[,] board)
        {
            board = board.Copy();
            var i        = 0;
            var unknowns = board.Points()
                           .Where(s => board[s.x, s.y] == Cell.Unknown)
                           .ToArray();

            while (i >= 0)
            {
                var(x, y) = unknowns[i];
                var cell           = board[x, y];
                int nextGuessIndex = cell == Cell.Unknown ? 0 : Array.IndexOf(FillOptions, cell) + 1;
                if (nextGuessIndex >= FillOptions.Length)
                {
                    board[x, y] = Cell.Unknown;
                    i--;
                    continue;
                }
                board[x, y] = FillOptions[nextGuessIndex];
                if (board.LegalSquare(x, y) && board.LegalNumbers(x, y))
                {
                    if (i < unknowns.Length - 1)
                    {
                        i++;
                    }
                    else if (board[x, y] == Cell.Full && board.LegalPath(x, y) || board[x, y] != Cell.Full && board.LegalPath())
                    {
                        yield return(board.Copy());
                    }
                }
            }
        }
Beispiel #2
0
 public static bool Legal(this Cell[,] board) =>
 board.LegalSquare() &&
 board.LegalPath() &&
 board.LegalNumbers();
Beispiel #3
0
 public static bool LegalNumbers(this Cell[,] board) => !board.Points()
 .Any(s => board[s.x, s.y] >= 0 && !board.LegalNumbers(s.x, s.y));
Beispiel #4
0
 public static bool LegalNumbers(this Cell[,] board, int x, int y)
 {
     if (!board.Contains(x, y))
     {
         return(true);
     }
     if (board[x, y] >= 0)
     {
         var cellNumber   = (int)board[x, y];
         var countUnknown = 0;
         var countFull    = 0;
         foreach (var(dx, dy) in Cardinals)
         {
             var scale        = 1;
             var foundUnknown = false;
             while (true)
             {
                 var newX = x + dx * scale;
                 var newY = y + dy * scale;
                 if (!board.Contains(newX, newY) || board[newX, newY] == Cell.Empty || board[newX, newY] >= 0)
                 {
                     break;
                 }
                 if (foundUnknown || board[newX, newY] == Cell.Unknown)
                 {
                     foundUnknown = true;
                     countUnknown++;
                 }
                 else if (board[newX, newY] == Cell.Full && ++countFull > cellNumber)
                 {
                     return(false);
                 }
                 scale++;
             }
         }
         return(countUnknown + countFull >= cellNumber && (cellNumber != 0 || countFull <= 0));
     }
     foreach (var(dx, dy) in Cardinals)
     {
         var scale = 1;
         while (true)
         {
             var newX = x + dx * scale;
             var newY = y + dy * scale;
             if (!board.Contains(newX, newY))
             {
                 break;
             }
             if (board[newX, newY] >= 0)
             {
                 if (!board.LegalNumbers(newX, newY))
                 {
                     return(false);
                 }
                 break;
             }
             scale++;
         }
     }
     return(true);
 }
Beispiel #5
0
 public static bool Legal(this Cell[,] board, int x, int y) =>
 board.LegalSquare(x, y) &&
 board.LegalNumbers(x, y);