Add pausing functionality. Keybinding for "Check"

This commit is contained in:
Joseph Ferano 2023-11-15 19:39:35 +07:00
parent cd09420da5
commit c56d14bdf6
2 changed files with 43 additions and 7 deletions

View File

@ -32,6 +32,10 @@ class Button:
txt: pg.Surface txt: pg.Surface
rect: Rect rect: Rect
# @dataclass
# class PlayerInput:
class InputMethod(Enum): class InputMethod(Enum):
""" """
This enum helps representing Snyder notation in the cells This enum helps representing Snyder notation in the cells
@ -48,9 +52,10 @@ class Status(Enum):
@dataclass @dataclass
class GameState: class GameState:
start_time: float = 0 elapsed_time: float = 0
status: Status = Status.FETCHING status: Status = Status.FETCHING
status_msg: str = "" status_msg: str = ""
paused: bool = False
################## ##################
# PYGAME INIT # PYGAME INIT
@ -92,7 +97,6 @@ board = []
pencil_marks = [] pencil_marks = []
sudoku = None sudoku = None
start_time = [0]
game_state = GameState() game_state = GameState()
data_lock = threading.Lock() data_lock = threading.Lock()
@ -110,7 +114,6 @@ def data_callback(sudoku_data):
pencil_marks.append(pm) pencil_marks.append(pm)
global sudoku global sudoku
with data_lock: with data_lock:
game_state.start_time = time.time()
game_state.status = Status.SOLVING game_state.status = Status.SOLVING
game_state.status_msg = "" game_state.status_msg = ""
sudoku = sudoku_data sudoku = sudoku_data
@ -180,12 +183,20 @@ def new_button(id, label, color, x, y, w, h):
return Button(id, return Button(id,
btn_font.render(label, True, color), btn_font.render(label, True, color),
Rect(x, y, w, h)) Rect(x, y, w, h))
pause_btns = [
new_button("pause", "Pause", "black", screen.get_width() - 10 - 150, 90, 150, 30),
new_button("pause", "Resume", "black", screen.get_width() - 10 - 150, 90, 150, 30),
]
buttons = [ buttons = [
new_button("check", "Check", "black", screen.get_width() - 10 - 100, 10, 100, 30), new_button("check", "Check", "black", screen.get_width() - 10 - 100, 10, 100, 30),
new_button("load", "Load new", "black", screen.get_width() - 10 - 150, 50, 150, 30), new_button("load", "Load new", "black", screen.get_width() - 10 - 150, 50, 150, 30),
pause_btns[0],
] ]
def draw_buttons(): def draw_buttons():
# God this is hacky
buttons[2] = pause_btns[1] if game_state.paused else pause_btns[0]
for btn in buttons: for btn in buttons:
pg.draw.rect(screen, "gray", btn.rect) pg.draw.rect(screen, "gray", btn.rect)
pg.draw.rect(screen, "black", btn.rect, width=2) pg.draw.rect(screen, "black", btn.rect, width=2)
@ -198,6 +209,19 @@ def draw_numbers():
for col in range(9): for col in range(9):
idx = row * 9 + col idx = row * 9 + col
cell = board[idx] cell = board[idx]
if game_state.paused:
if row == 4 and col > 1 and col < 7:
paused = "PAUSE"
letter = filled_num_font.render(paused[col - 2], True, "dark blue")
pos = (GRID_X + CELL_SIZE * col + CELL_SIZE // 2 - letter.get_width() // 2,
# Here we divide the height by 2.3 because there seems to be some extra
# padding at the bottom of the surface
GRID_Y + CELL_SIZE * row + CELL_SIZE // 2 - letter.get_height() // 2.3)
screen.blit(letter, pos)
continue
if cell.value > 0: if cell.value > 0:
color = "black" if cell.given else "dark blue" color = "black" if cell.given else "dark blue"
digit = filled_num_font.render(str(cell.value), True, color) digit = filled_num_font.render(str(cell.value), True, color)
@ -221,6 +245,9 @@ def draw_hud():
screen.blit(status_txt, (screen.get_width() // 2 - status_txt.get_width() // 2, screen.blit(status_txt, (screen.get_width() // 2 - status_txt.get_width() // 2,
screen.get_height() - status_txt.get_height() - 70)) screen.get_height() - status_txt.get_height() - 70))
def toggle_pause():
game_state.paused = not game_state.paused
def check_board(): def check_board():
for i,cell in enumerate(board): for i,cell in enumerate(board):
if cell.value != 0 and cell.value != sudoku.solution[i]: if cell.value != 0 and cell.value != sudoku.solution[i]:
@ -230,7 +257,7 @@ def check_board():
if cell.value == 0: if cell.value == 0:
game_state.status_msg = "You still have to finish the puzzle!" game_state.status_msg = "You still have to finish the puzzle!"
return return
completion_time = time.time() - game_state.start_time completion_time = game_state.elapsed_time
mins = int(completion_time // 60) mins = int(completion_time // 60)
secs = int(completion_time % 60) secs = int(completion_time % 60)
game_state.status_msg = f"You finished it in {mins} min {secs} sec!" game_state.status_msg = f"You finished it in {mins} min {secs} sec!"
@ -240,6 +267,7 @@ def main():
running = True running = True
input_method = InputMethod.FILL input_method = InputMethod.FILL
while running: while running:
dt = clock.tick(60) / 1000
for event in pg.event.get(): for event in pg.event.get():
if event.type == pg.QUIT: if event.type == pg.QUIT:
running = False running = False
@ -262,6 +290,8 @@ def main():
case "check": case "check":
if game_state.status == Status.SOLVING: if game_state.status == Status.SOLVING:
check_board() check_board()
case "pause":
toggle_pause()
case "load": case "load":
pass pass
@ -311,6 +341,10 @@ def main():
input_method = InputMethod.CENTER input_method = InputMethod.CENTER
case pg.K_b: case pg.K_b:
input_method = InputMethod.BORDER input_method = InputMethod.BORDER
case pg.K_p:
toggle_pause()
case pg.K_RETURN:
check_board()
############## ##############
# Debug stuff # Debug stuff
@ -332,6 +366,8 @@ def main():
with data_lock: with data_lock:
if sudoku is not None: if sudoku is not None:
draw_numbers() draw_numbers()
if not game_state.paused:
game_state.elapsed_time += dt
draw_cursor() draw_cursor()
draw_hud() draw_hud()
draw_buttons() draw_buttons()
@ -339,7 +375,6 @@ def main():
pg.display.flip() pg.display.flip()
dt = clock.tick(60) / 1000
pg.quit() pg.quit()

View File

@ -20,7 +20,8 @@
* DONE Pass difficulty through command line * DONE Pass difficulty through command line
* DONE Toast on valid solve * DONE Toast on valid solve
* DONE Show the time it took * DONE Show the time it took
* TODO Pausing functionality * DONE Keybinding to check so you don't have to use the mouse
* DONE Pausing functionality
* TODO Show current input method * TODO Show current input method
* TODO Show keybindings somehow * TODO Show keybindings somehow
* TODO Show errors * TODO Show errors
@ -28,7 +29,7 @@
* TODO Choose difficulty buttons * TODO Choose difficulty buttons
* TODO Save current game * TODO Save current game
* TODO Create a pip file * TODO Create a pip file
* TODO Support undo? * TODO Support undo
* TODO Sudoku generator * TODO Sudoku generator
* TODO Sudoku solver * TODO Sudoku solver
* TODO Sudoku difficulty generator * TODO Sudoku difficulty generator