How to create Sudoku Pygame using Python3
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/