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()); } } } }
public static bool Legal(this Cell[,] board) => board.LegalSquare() && board.LegalPath() && board.LegalNumbers();
public static bool LegalNumbers(this Cell[,] board) => !board.Points() .Any(s => board[s.x, s.y] >= 0 && !board.LegalNumbers(s.x, s.y));
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); }
public static bool Legal(this Cell[,] board, int x, int y) => board.LegalSquare(x, y) && board.LegalNumbers(x, y);