Writing a number/text in a Pygame Rect

Viewed 728

At the moment I create a Visualization Tool for my Sudoku solver.

Now I want to display the numbers in the grid with pygame.

def draw(win):
global grid
w = 70
x,y = 0,0

for row in grid:
    for col in grid:
        
        rect = pygame.Rect(x,y,w,w)
        pygame.draw.rect(win,BLACK,rect)
        rect2 = pygame.Rect(x+2, y+2, w-1, w-1)
        pygame.draw.rect(win,WHITE,rect2)

    
        pygame.display.flip()
        x = x + w
    y = y + w 
    x = 0

The code is ugly, I know but my grid works. And I can iterate over it. My problem now, I don't know how to fill the Rect with a Number? I want to add the Number from the Sudoku grid at the position [row][col] within rect2.

I hope one of you guys can help me.

2 Answers

To draw text in a rectangle there's a few things you need. The first is a pygame Font object. This is basically just a configured font. You can pass it a full path to a True Type Font (possibly others), or use a system font.

number_font = pygame.font.SysFont( None, 16 )   # default font, size 16

Then to render a number, pass it as text to the font's render() method, giving it a foreground and background colour. The second parameter is whether you want the font nice and smooth. Generally I always leave this True.

number_font  = pygame.font.SysFont( None, 16 )                # Default font, Size 16
number_image = number_font.render( "8", True, BLACK, WHITE )  # Number 8

So that creates a number_image - a pyagme.Surface containing the "rendered" number.
Now that has to be centred in each cell. We can do this by working out the size difference between the surrounding rectangle, and the size of the number-image. Splitting this in half should give us a centre position. I just guessed at a font-size of 16, it might be too big for your grid (or way too small).

# Creating the font object needs to be only done once, so don't put it inside a loop
number_font = pygame.font.SysFont( None, 16 )   # default font, size 16

...

for row in grid:
    for col in grid:
        
        rect = pygame.Rect(x,y,w,w)
        pygame.draw.rect(win,BLACK,rect)
        rect2 = pygame.Rect(x+2, y+2, w-1, w-1)
        pygame.draw.rect(win,WHITE,rect2)

        # make the number from grid[row][col] into an image
        number_text  = str( grid[row][col] )
        number_image = number_font.render( number_text, True, BLACK, WHITE )

        # centre the image in the cell by calculating the margin-distance
        margin_x = ( w-1 - number_image.width ) // 2
        margin_y = ( w-1 - number_image.height ) // 2

        # Draw the number image
        win.blit( number_image, ( x+2 + margin_x, y+2 + margin_y ) )

I dont know how soduku works but this is how you render text in pygame. Create a font first.

fontName = pygame.font.get_default_font()
size = 10 # This means the text will be 10 pixels in height.
          # The width will be scaled automatically.
font = pygame.font.Font(fontName, size)

Then create a text surface from the font.

text = number 
antislias = True
color = (0, 0, 0)
surface = font.render(f"{text}", antialias, color)

Note that text argument always has to be a string, so in your case you have to use an fstring because you are rendering number. This surface is like any other surface in pygame, so you can simply render it using win.blit(surface, (row, col)).

Related