The concept of the program is to create a sudoku puzzle that can then be solved via pygame. Where I got stuck is this error:
Traceback (most recent call last):
File "C:\Users\Lenovo\Desktop\Sudoku Solver\GUI.py", line 307, in <module>
main()
File "C:\Users\Lenovo\Desktop\Sudoku Solver\GUI.py", line 245, in main
board = Grid(9, 9, 540, 540)
File "C:\Users\Lenovo\Desktop\Sudoku Solver\GUI.py", line 105, in __init__
self.cubes = [[Cube(self.board[i][j], i, j, width, height) for j in range(cols)] for i in range(rows)]
File "C:\Users\Lenovo\Desktop\Sudoku Solver\GUI.py", line 105, in <listcomp>
self.cubes = [[Cube(self.board[i][j], i, j, width, height) for j in range(cols)] for i in range(rows)]
File "C:\Users\Lenovo\Desktop\Sudoku Solver\GUI.py", line 105, in <listcomp>
self.cubes = [[Cube(self.board[i][j], i, j, width, height) for j in range(cols)] for i in range(rows)]
TypeError: 'int' object is not subscriptable
[Finished in 0.6s with exit code 1]
But the interesting part is that when I pass in a handmade matrix there is no error. I could replicate the generated matrix and pass it in and it would work but making a function like the one bellow to generate one won't.
def generate_board():
base = 3
side = base*base
def pattern(r,c): return (base*(r%base)+r//base+c)%side
from random import sample
def shuffle(s): return sample(s,len(s))
rBase = range(base)
rows = [ g*base + r for g in shuffle(rBase) for r in shuffle(rBase) ]
cols = [ g*base + c for g in shuffle(rBase) for c in shuffle(rBase) ]
nums = shuffle(range(1,base*base+1))
# produce board using randomized baseline pattern
board = [ [nums[pattern(r,c)] for c in cols] for r in rows ]
squares = side*side
empties = squares * 3//4
for p in sample(range(squares),empties):
board[p//side][p%side] = 0
numSize = len(str(side))
for line in board: return line
generated_board = generate_board()
For getting a better view at the program take a look at the part of the problem where the error is thrown in, the initialization of the GRID class that creates for each self.cubes a cube object:
class Grid:
board = generated_board
def __init__(self, rows, cols, width, height):
self.rows = rows
self.cols = cols
self.cubes = [[Cube(self.board[i][j], i, j, width, height) for j in range(cols)] for i in range(rows)]
self.width = width
self.height = height
self.model = None
self.selected = None
I don't think this is needed but this is the Cube class which is created 9x9 in the init of the Grid class.
class Cube:
rows = 9
cols = 9
def __init__(self, value, row, col, width ,height):
self.value = value
self.temp = 0
self.row = row
self.col = col
self.width = width
self.height = height
self.selected = False
def draw(self, win):
fnt = pygame.font.SysFont("comicsans", 40)
gap = self.width / 9
x = self.col * gap
y = self.row * gap
if self.temp != 0 and self.value == 0:
text = fnt.render(str(self.temp), 1, (128,128,128))
win.blit(text, (x+5, y+5))
elif not(self.value == 0):
text = fnt.render(str(self.value), 1, (0, 0, 0))
win.blit(text, (x + (gap/2 - text.get_width()/2), y + (gap/2 - text.get_height()/2)))
if self.selected:
pygame.draw.rect(win, (255,0,0), (x,y, gap ,gap), 3)
def set(self, val):
self.value = val
def set_temp(self, val):
self.temp = val
So once again passing in a board like
board = [
[7, 8, 0, 4, 0, 0, 1, 2, 0],
[6, 0, 0, 0, 7, 5, 0, 0, 9],
[0, 0, 0, 6, 0, 1, 0, 7, 8],
[0, 0, 7, 0, 4, 0, 2, 6, 0],
[0, 0, 1, 0, 5, 0, 9, 3, 0],
[9, 0, 4, 0, 6, 0, 0, 0, 5],
[0, 7, 0, 3, 0, 0, 0, 1, 2],
[1, 2, 0, 0, 0, 7, 4, 0, 0],
[0, 4, 9, 2, 0, 6, 0, 0, 7]
]
would do the job, the board to be passed in the grid class. But generating one outside the class, then plucking it in even tho the generated board is in this exact format won't stick me with the error above. Please anybody who had this kind of problem or knows how to debug this to help me, many thanks