Sudoku Pygame Building Using Python


How to create Sudoku Pygame using Python3

Sudoku Pygame

Hello The Codezine Mates, welcome back to our Pygame Series, today we are going to build another game using pygame. This day I am going to show you how you can create a Python Sudoku game. Interesting, isn’t it?

What is Sudoku Game: It is a puzzle-based strategy game in which players place the numbers 1 to 9 into a grid-shaped box consisting of 9 squares. It is divided into 9 smaller squares in such a way that every number shows once in each line. Simply speaking, it is is a logic-based, multi number-placement puzzle game.

Requirements for the Game:

  • A fast processing & high graphics PC with a Python environment installed. Typically, You can choose Mac Book, Asus Zenbook, Dell Inspiron, or any Pc with a high-level processor.
  • A Code Ide or Code Editor like an atom or vs code.
  • A notebook with a pen for writing important points.
  • Your concentration.

Working:

Our GUI game is coded to allow a particular player to solve within a defined time. If a player can solve it within the given then a player wins & an alert pops out and the opposite happens if the player loses. It also grants a user to solve the puzzle automatically if he is unable to solve it.

Steps to build a Sudoku Game:

  • Firstly, make a folder named any in your laptop & drag it to your code ide.
  • Secondly, open your command prompt(CMD) & install the Pygame package by typing Pip install Pygame command.[It will permit your system to built pygame based game]
  • Thirdly, make a file called main.py.
  • Now, Set your codes which are given under the section to your respective files.
  • Lastly, run your Pygame by typing Python main.py in your Command. That’s it you have your game.

Code

# main.py
import pygame
import time
pygame.font.init() #Defining Board Size class Grid: 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] ]
#defining titles def __init__(self, rows, cols, width, height, win): 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.update_model() self.selected = None self.win = win def update_model(self): self.model = [[self.cubes[i][j].value for j in range(self.cols)] for i in range(self.rows)] def place(self, val): row, col = self.selected if self.cubes.value == 0: self.cubes.set(val) self.update_model() if valid(self.model, val, (row,col)) and self.solve(): return True else: self.cubes.set(0) self.cubes.set_temp(0) self.update_model() return False def sketch(self, val): row, col = self.selected self.cubes.set_temp(val) def draw(self): # Drawing Grid Lines gap = self.width / 9 for i in range(self.rows+1): if i % 3 == 0 and i != 0: thick = 4 else: thick = 1 pygame.draw.line(self.win, (0,0,0), (0, i*gap), (self.width, i*gap), thick) pygame.draw.line(self.win, (0, 0, 0), (i * gap, 0), (i * gap, self.height), thick) # Drawing Cubes for i in range(self.rows): for j in range(self.cols): self.cubes[i][j].draw(self.win) def select(self, row, col): # Reset all other for i in range(self.rows): for j in range(self.cols): self.cubes[i][j].selected = False self.cubes.selected = True self.selected = (row, col) def clear(self): row, col = self.selected if self.cubes.value == 0: self.cubes.set_temp(0) def click(self, pos): """ :param: pos :return: (row, col) """ if pos[0] < self.width and pos[1] < self.height: gap = self.width / 9 x = pos[0] // gap y = pos[1] // gap return (int(y),int(x)) else: return None def is_finished(self): for i in range(self.rows): for j in range(self.cols): if self.cubes[i][j].value == 0: return False return True def solve(self): find = find_empty(self.model) if not find: return True else: row, col = find for i in range(1, 10): if valid(self.model, i, (row, col)): self.model = i if self.solve(): return True self.model = 0 return False def solve_gui(self): find = find_empty(self.model) if not find: return True else: row, col = find for i in range(1, 10): if valid(self.model, i, (row, col)): self.model = i self.cubes.set(i) self.cubes.draw_change(self.win, True) self.update_model() pygame.display.update() pygame.time.delay(100) if self.solve_gui(): return True self.model = 0 self.cubes.set(0) self.update_model() self.cubes.draw_change(self.win, False) pygame.display.update() pygame.time.delay(100) return False 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 draw_change(self, win, g=True): fnt = pygame.font.SysFont("comicsans", 40) gap = self.width / 9 x = self.col * gap y = self.row * gap pygame.draw.rect(win, (255, 255, 255), (x, y, gap, gap), 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 g: pygame.draw.rect(win, (0, 255, 0), (x, y, gap, gap), 3) else: 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 def find_empty(bo): for i in range(len(bo)): for j in range(len(bo[0])): if bo[i][j] == 0: return (i, j) # row, col return None def valid(bo, num, pos): # Check row for i in range(len(bo[0])): if bo[pos[0]][i] == num and pos[1] != i: return False # Check column for i in range(len(bo)): if bo[i][pos[1]] == num and pos[0] != i: return False # Check box box_x = pos[1] // 3 box_y = pos[0] // 3 for i in range(box_y*3, box_y*3 + 3): for j in range(box_x * 3, box_x*3 + 3): if bo[i][j] == num and (i,j) != pos: return False return True def redraw_window(win, board, time, strikes): win.fill((255,255,255)) # Draw time fnt = pygame.font.SysFont("comicsans", 40) text = fnt.render("Time: " + format_time(time), 1, (0,0,0)) win.blit(text, (540 - 160, 560)) # Draw Strikes text = fnt.render("X " * strikes, 1, (255, 0, 0)) win.blit(text, (20, 560)) # Draw grid and board board.draw() def format_time(secs): sec = secs%60 minute = secs//60 hour = minute//60 mat = " " + str(minute) + ":" + str(sec) return mat #Title Portion
def main(): win = pygame.display.set_mode((540,600)) pygame.display.set_caption("Sudoku Pygame (Press Space to do auto solve) ") board = Grid(9, 9, 540, 540, win) key = None run = True start = time.time() strikes = 0 while run: play_time = round(time.time() - start) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_1: key = 1 if event.key == pygame.K_2: key = 2 if event.key == pygame.K_3: key = 3 if event.key == pygame.K_4: key = 4 if event.key == pygame.K_5: key = 5 if event.key == pygame.K_6: key = 6 if event.key == pygame.K_7: key = 7 if event.key == pygame.K_8: key = 8 if event.key == pygame.K_9: key = 9 if event.key == pygame.K_DELETE: board.clear() key = None if event.key == pygame.K_SPACE: board.solve_gui() # Click Event if event.key == pygame.K_RETURN: i, j = board.selected if board.cubes[i][j].temp != 0: if board.place(board.cubes[i][j].temp): print("Success") else: print("Wrong") strikes += 1 key = None if board.is_finished(): print("Game over") if event.type == pygame.MOUSEBUTTONDOWN: pos = pygame.mouse.get_pos() clicked = board.click(pos) if clicked: board.select(clicked[0], clicked[1]) key = None if board.selected and key != None: board.sketch(key) redraw_window(win, board, play_time, strikes) pygame.display.update() main()
pygame.quit()

Conclusion

Though, It is a simple beginner-friendly Game this is easy for any beginner to built & understand it is important to follow the steps carefully. So, that you don’t get any error. Lastly, if you find useful please share it. Thank You.

Source: https://thecodezine.com/sudoku-pygame-building-using-python/



You might also like this video