2

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

Alex Mihoc
  • 80
  • 1
  • 7

1 Answers1

2

When you generate the board, you only return the first row instead of the entire board.

Make this change in your code:

def generate_board():
    .........
    # for line in board: return line  # remove this line
    return board   # return full board
Mike67
  • 11,175
  • 2
  • 7
  • 15