I am making Sudoku for iOS that will be simple project for my classes. The problem is the checking of the Sudoku. There can be three results form the checked Sudoku:
- Not filled
- Correct
- Incorect
Depending on enumeration with those values there will be a sheet that will display the result of the checked Sudoku.
Here is the enumeration:
// MARK: Statuses
/// Statuses that can result from checking the sudoku.
enum Statuses {
case correct
case incorrect
case notFilled
}
Here is the struct that will hold the enumeration value and a bool variable that will be used to display the sheet.
// MARK: SudokuStatus
/// Struct that is used to combine the status and if the sudoku is checked.
struct SudokuStatus {
public var status: Statuses
public var isChecked: Bool
/// Initialiser of the struct making the status not checked and empty.
init () {
self.status = .notFilled
self.isChecked = false
}
/// Function that will update the status.
/// - Parameter status: The status form the sudoku.
/// - Returns: There is no return.
mutating func setStatus(status: Statuses) -> Void {
self.status = status
self.isChecked = true
}
}
Here is the content view.
// MARK: ContentView
/// The main view of the app.
struct ContentView: View {
/// Variable that will create a sudoku object.
let sudoku: Sudoku = Sudoku()
/// Array that will hold the numbers in the sudoku.
/// If the numbers is equals to 0 it means its empty.
@State var numbers: [[Number]] = Array(repeating: Array(repeating: Number(), count: 9), count: 9)
/// Variable that will keep the selected number.
/// The value at begging will be 0 representing that no number is selected.
@State var selectedNumber: Int = 0
/// Variable used to selected the difficulty of the game.
@State var selectedDifficulty: Difficulties = .easy
/// Variable that will keep the status form the sudoku.
@State var sudokuStatus: SudokuStatus = SudokuStatus()
/// The main body of the struct.
var body: some View {
GeometryReader { geo in
VStack(spacing: geo.size.height / 20) {
Title (
width: geo.size.width / 1.2,
height: geo.size.height / 10
)
Board (
size: geo.size.width / 1.2,
selectedNumber: $selectedNumber,
numbers: $numbers
)
NumberSelection (
width: geo.size.width,
height: geo.size.height / 10,
selectedNumber: $selectedNumber
)
BottomBar (
width: geo.size.width,
height: geo.size.height / 10,
onStartGameClicked: onStartGameClicked,
onCheckGameClicked: onCheckGameClicked,
selectedDifficulty: $selectedDifficulty
)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.sheet(isPresented: $sudokuStatus.isChecked, content: {
SudokuStatusSheet(status: sudokuStatus.status)
})
}
}
/// Function called when the start button is clicked.
/// - Returns: There is no return. The function fills the array with the numbers.
func onStartGameClicked() -> Void {
let grid: [[Int]] = sudoku.generateSudoku(difficulty: selectedDifficulty)
for i in 0..<9 {
for j in 0..<9 {
if grid[i][j] == 0 {
numbers[i][j].value = 0
numbers[i][j].isGenerated = false
}
else {
numbers[i][j].value = grid[i][j]
numbers[i][j].isGenerated = true
}
}
}
}
/// Function called when the check button is clicked.
/// - Returns: There is no return. The function updates the sudoku status variable.
func onCheckGameClicked() -> Void {
var grid: [[Int]] = Array(repeating: Array(repeating: 0, count: 9), count: 9)
for i in 0..<9 {
for j in 0..<9 {
if numbers[i][j].value == 0 {
sudokuStatus.setStatus(status: .notFilled)
return
}
grid[i][j] = numbers[i][j].value
}
}
if Sudoku.checkSudoku(grid: grid) {
sudokuStatus.setStatus(status: .correct)
} else {
sudokuStatus.setStatus(status: .incorrect)
}
}
}
As you can see the function that check the Sudoku is very simple. It goes through the inputed numbers which a struct that hold the value of the number and bool variable to check if the number is generated or inputed by the user. If the number is equal to zero, which means empty, and it will update the value to not filled and return. Then it will do the check by the class Sudoku with work correctly and if the result is true it will make it correct to incorrect. The problem is that each time the app start or the preview is restarted the first time you check the Sudoku it will always says that it is not filled. After that the code works perfectly fine, but not the first time it checks.
I changed the value of the default initialiser of the struct Sudoku status and learned that the first value that will be displayed will the default that is set. I really have no idea how to solve that so I didn't try much more except searching the Internet with the same problem, or using our favourite AI, but it didn't help.