Skip to content

Commit

Permalink
Created a basic funcationing UI
Browse files Browse the repository at this point in the history
  • Loading branch information
dantheman0007 committed Apr 26, 2020
1 parent d3d0903 commit 0b1aedf
Show file tree
Hide file tree
Showing 7 changed files with 897 additions and 8 deletions.
674 changes: 674 additions & 0 deletions COPYING.txt

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# sudoku-solver
Solves sudokus using backtracking
# Sudoku Solver
Real straightforward sudoku solver, using a basic baxcktracking algorithm.

## CMD Usage
Run the following command
```
python3 main.py path/to/board.txt
```
### Board.txt
The `board.txt` file is simply a text file that represents the sudoku board. It should contain 9 lines each with 9 numbers seperated by a whitespace. There should not be a whitespace at the end of the line, only a newline character.

Example from `boards/board0.txt`

```txt
0 0 3 0 2 0 6 0 0
9 0 0 3 0 5 0 0 1
0 0 1 8 0 6 4 0 0
0 0 8 1 0 2 9 0 0
7 0 0 0 0 0 0 0 8
0 0 6 7 0 8 2 0 0
0 0 2 6 0 9 5 0 0
8 0 0 2 0 3 0 0 9
0 0 5 0 1 0 3 0 0
```
# License
This project is licensed under the **GNU General Public License v3.0** which you can find in `COPYING.txt`
Binary file modified __pycache__/boardGui.cpython-38.pyc
Binary file not shown.
Binary file modified __pycache__/solver.cpython-38.pyc
Binary file not shown.
177 changes: 173 additions & 4 deletions boardGui.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,178 @@
import tkinter
import sys
from functools import partial
import solver

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtCore import Qt

class BoardGui():

class BoardGui(QMainWindow):

def __init__(self):
top = tkinter.Tk()
super().__init__()

# Where the user's cursor is at: row, col
self.currentCursPos = [0, 0]

self.setWindowTitle("Sudoku Solver")
self.setGeometry(650, 300, 650, 600)

self.generalLayout = QVBoxLayout()
self._centralWidget = QWidget(self)
self.setCentralWidget(self._centralWidget)
self._centralWidget.setLayout(self.generalLayout)

self._createHeaderBox()
self._createInputs()
pass

def _createHeaderBox(self):
self.headerPanelLayout = QGridLayout()
titleMessage = QLabel('<h1>Sudoku Solver</h1>')
infoMessasge = QLabel('<p>Hello, and welcome to this app which will actually be the death of me</p>')

timeMessage = QLabel("")

self.solveButton = QPushButton("Solve")
self.solveButton.setFixedSize(70, 30)
self.loadButton = QPushButton("Load")
self.loadButton.setFixedSize(70, 30)

self.headerPanelLayout.addWidget(titleMessage, 0, 0)
self.headerPanelLayout.addWidget(infoMessasge, 1, 0)
self.headerPanelLayout.addWidget(timeMessage, 0, 2)
self.headerPanelLayout.addWidget(self.solveButton, 1, 1)
self.headerPanelLayout.addWidget(self.loadButton, 1, 2)

self.generalLayout.addLayout(self.headerPanelLayout)

def _createInputs(self):
self.inputs = []
self.inputLayout = QGridLayout()

for y in range(9):
tempRow = []
for x in range(9):

# Create the edit box
currentEdit = QLineEdit()

# Do some parameter stuff
currentEdit.setMaximumWidth(45)
currentEdit.setMinimumWidth(45)
currentEdit.setMaximumHeight(45)
currentEdit.setMinimumHeight(45)
currentEdit.setMaxLength(1)
currentEdit.setAlignment(Qt.AlignCenter)

font = currentEdit.font()
font.setPointSize(38)
currentEdit.setFont(font)

self.inputLayout.addWidget(currentEdit, y, x)
tempRow.append(currentEdit)
pass

self.inputs.append(tempRow)
pass

self.generalLayout.addLayout(self.inputLayout)

pass


class BoardController():

def __init__(self, view, solver):
self._view = view
self.solver = solver

self._connectSignals()

def cleanData(self):
grid = []
for row in range(9):
grid_row = []
for col in range(9):
cell = self._view.inputs[row][col]
sanitized_value = 0
try:
sanitized_value = int(cell.text())
pass
except ValueError:
print("Found a character or an empty space. Substituting with 0")

grid_row.append(sanitized_value)
pass
grid.append(grid_row)
pass
return grid

def solve(self):
cleanedGrid = self.cleanData()
self.solver.setGrid(cleanedGrid)
self.solver.solve()
print(self.solver.getGrid())
print(self.solver.solvedGrid)
self.populateUi(self.solver.getGrid())

def populateUi(self, grid):
for row in range(9):
for col in range(9):
self._view.inputs[row][col].setText(str(grid[row][col]))
pass
pass
pass

def loadFromFile(self):
filename = QFileDialog.getOpenFileName(self._view, "Select File", "./", "Text Files (*.txt)")
grid = []
with open(filename[0], mode='r') as board_file:
for col in board_file:
# Remove whitespace from end of line and seperate numbers
col_rows = col.strip().split(" ")

# Transform strings to int
col_rows = [int(x) for x in col_rows]

# Add the current row to the board
grid.append(col_rows)
pass
pass
self.populateUi(grid)
pass

def moveCursor(self, x, y):

pass

def _connectSignals(self):
self._view.solveButton.clicked.connect(partial(self.solve))
self._view.loadButton.clicked.connect(partial(self.loadFromFile))

for row in range(9):
for col in range(9):
self._view.inputs[row][col].textChanged.connect(partial(self.moveCursor, col, row))


def main():
sudoku_solver = QApplication([])
solving_machine = solver.Solver()

view = BoardGui()
view.show()
BoardController(view=view, solver=solving_machine)

sys.exit(sudoku_solver.exec_())


top.mainloop()
if __name__ != '__main__':
main()
9 changes: 9 additions & 0 deletions boards/board1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
2 0 0 0 8 0 3 0 0
0 6 0 0 7 0 0 8 4
0 3 0 5 0 0 2 0 9
0 0 0 1 0 5 4 0 8
0 0 0 0 0 0 0 0 0
4 0 2 7 0 6 0 0 0
3 0 1 0 0 7 0 4 0
7 2 0 0 4 0 0 6 0
0 0 4 0 1 0 0 0 3
17 changes: 15 additions & 2 deletions solver.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import numpy as np
import copy


class Solver:
def __init__(self, grid):
def __init__(self, grid=[]):
self.grid = grid
self.currentIndex = [0, 0]
self.attempt = 0
self.execTime = 0

self.solvedGrid = []

def setGrid(self, grid):
self.grid = grid
pass

def isPossible(self, posx, posy, num):
# Let us check if the number is in the column
Expand Down Expand Up @@ -48,8 +57,12 @@ def solve(self):
return

self.printGrid()
self.solvedGrid = copy.deepcopy(self.grid)
pass

def getGrid(self):
return self.solvedGrid

def printGrid(self):
print(np.matrix(self.grid), end='\r')
print(np.matrix(self.grid))
pass

0 comments on commit 0b1aedf

Please sign in to comment.