From 913e4b8858c7e7f5d3ea15b5828fe068421d7dda Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Wed, 1 Nov 2023 11:23:05 +0700 Subject: [PATCH] Wrap around the board, backspace center pms, difficulty arg --- pydoku.py | 199 +++++++++++++++++++++++++++------------------------ pydoku.todo | 10 ++- websudoku.py | 3 +- 3 files changed, 115 insertions(+), 97 deletions(-) diff --git a/pydoku.py b/pydoku.py index 7b6c041..63d735e 100644 --- a/pydoku.py +++ b/pydoku.py @@ -5,14 +5,15 @@ from enum import Enum from typing import Set import threading +import sys import os from websudoku import * @dataclass class Cursor: - row: int = 5 - col: int = 5 + row: int = 4 + col: int = 4 @dataclass class Cell: @@ -51,7 +52,6 @@ pg.display.set_caption("Pydoku") pg.key.set_repeat(200, 35) clock = pg.time.Clock() -running = True ################## # FONTS @@ -74,7 +74,6 @@ GRID_Y = screen.get_height() / 2 - 9 * CELL_SIZE // 2 cursorSurface = pg.Surface((CURSOR_SIZE, CURSOR_SIZE), pg.SRCALPHA) cursor = Cursor() -input_method = InputMethod.FILL board = [] pencil_marks = [] @@ -99,7 +98,11 @@ def data_callback(sudoku_data): def http_request_thread(): - data = get_sudoku_puzzle(Difficulty.EVIL) + if len(sys.argv) > 1: + difficulty = Difficulty[sys.argv[1].upper()] + else: + difficulty = Difficulty.MEDIUM + data = get_sudoku_puzzle(difficulty) data_callback(data) http_thread = threading.Thread(target=http_request_thread) @@ -132,8 +135,8 @@ def draw_grid(): def draw_cursor(): pad_diff = (CURSOR_SIZE - CELL_SIZE) // 2 pg.draw.rect(cursorSurface, (100, 0, 155, 100), [0, 0, CURSOR_SIZE, CURSOR_SIZE]) - rect = Rect(CELL_SIZE * (cursor.col - 1) + GRID_X - pad_diff, - CELL_SIZE * (cursor.row - 1) + GRID_Y - pad_diff, + rect = Rect(CELL_SIZE * cursor.col + GRID_X - pad_diff, + CELL_SIZE * cursor.row + GRID_Y - pad_diff, CURSOR_SIZE, CURSOR_SIZE) screen.blit(cursorSurface, rect) @@ -206,103 +209,113 @@ def check_board(): return print("You completed it!") -while running: - for event in pg.event.get(): - if event.type == pg.QUIT: - running = False - if event.type == pg.MOUSEBUTTONDOWN: - if event.button == 1: - grid_max_x = GRID_X + CELL_SIZE * 9 - grid_max_y = GRID_Y + CELL_SIZE * 9 - mx = event.pos[0] - my = event.pos[1] - if (mx >= GRID_X - and mx <= grid_max_x - and my >= GRID_Y - and my <= grid_max_y): - cursor.row = int((my - GRID_Y) // CELL_SIZE + 1) - cursor.col = int((mx - GRID_X) // CELL_SIZE + 1) +def main(): + running = True + input_method = InputMethod.FILL - for btn in buttons: - if btn_rect.collidepoint(event.pos): - match btn_rect.id: - case "check": - check_board() - case "load": - pass + while running: + for event in pg.event.get(): + if event.type == pg.QUIT: + running = False + if event.type == pg.MOUSEBUTTONDOWN: + if event.button == 1: + grid_max_x = GRID_X + CELL_SIZE * 9 + grid_max_y = GRID_Y + CELL_SIZE * 9 + mx = event.pos[0] + my = event.pos[1] + if (mx >= GRID_X + and mx <= grid_max_x + and my >= GRID_Y + and my <= grid_max_y): + cursor.row = int((my - GRID_Y) // CELL_SIZE) + cursor.col = int((mx - GRID_X) // CELL_SIZE) + + for btn in buttons: + if btn.rect.collidepoint(event.pos): + match btn.id: + case "check": + check_board() + case "load": + pass - if event.type == pg.KEYDOWN: - # keys = pg.key.get_pressed() - if (event.key == pg.K_h or event.key == pg.K_a) and cursor.col > 1: - cursor.col -= 1 - if (event.key == pg.K_k or event.key == pg.K_w) and cursor.row > 1: - cursor.row -= 1 - if (event.key == pg.K_j or event.key == pg.K_s) and cursor.row < 9: - cursor.row += 1 - if (event.key == pg.K_l or event.key == pg.K_d) and cursor.col < 9: - cursor.col += 1 + if event.type == pg.KEYDOWN: + # keys = pg.key.get_pressed() + if (event.key == pg.K_h or event.key == pg.K_a): + cursor.col = (cursor.col - 1) % 9 + if (event.key == pg.K_k or event.key == pg.K_w): + cursor.row = (cursor.row - 1) % 9 + if (event.key == pg.K_j or event.key == pg.K_s): + cursor.row = (cursor.row + 1) % 9 + if (event.key == pg.K_l or event.key == pg.K_d): + cursor.col = (cursor.col + 1) % 9 - num = pg.key.name(event.key) - if num.isdigit() and num != '0': - num = int(num) - idx = (cursor.row - 1) * 9 + cursor.col - 1 - if board and not board[idx].given: - match input_method: - case InputMethod.FILL: - board[idx].value = num - case InputMethod.CENTER: - if num in pencil_marks[idx].center: - pencil_marks[idx].center.remove(num) - # Max 3 center pencil marks - elif len(pencil_marks[idx].center) < 3: - pencil_marks[idx].center.add(num) - case InputMethod.BORDER: - if num in pencil_marks[idx].border: - pencil_marks[idx].border.remove(num) - else: - pencil_marks[idx].border.add(num) + num = pg.key.name(event.key) + if num.isdigit() and num != '0': + num = int(num) + idx = cursor.row * 9 + cursor.col + if board and not board[idx].given: + match input_method: + case InputMethod.FILL: + board[idx].value = num + case InputMethod.CENTER: + if num in pencil_marks[idx].center: + pencil_marks[idx].center.remove(num) + # Max 3 center pencil marks + elif len(pencil_marks[idx].center) < 3: + pencil_marks[idx].center.add(num) + case InputMethod.BORDER: + if num in pencil_marks[idx].border: + pencil_marks[idx].border.remove(num) + else: + pencil_marks[idx].border.add(num) - if event.key == pg.K_BACKSPACE: - idx = (cursor.row - 1) * 9 + cursor.col - 1 - if not board[idx].given: - board[idx].value = 0 + if event.key == pg.K_BACKSPACE: + idx = cursor.row * 9 + cursor.col + if not board[idx].given: + if board[idx].value > 0: + board[idx].value = 0 + elif pencil_marks[idx].center: + pencil_marks[idx].center.pop() - match event.key: - case pg.K_f: - input_method = InputMethod.FILL - case pg.K_c: - input_method = InputMethod.CENTER - case pg.K_b: - input_method = InputMethod.BORDER + match event.key: + case pg.K_f: + input_method = InputMethod.FILL + case pg.K_c: + input_method = InputMethod.CENTER + case pg.K_b: + input_method = InputMethod.BORDER - ############## - # Debug stuff - ############## - if event.key == pg.K_F1: - print(sudoku) - if event.key == pg.K_F2: - idx = (cursor.row - 1) * 9 + cursor.col - 1 - if not board[idx].given: - pencil_marks[idx].border = {i for i in range(1, 10)} - if event.key == pg.K_F3: - for i,cell in enumerate(board): - cell.value = sudoku.solution[i] + ############## + # Debug stuff + ############## + if event.key == pg.K_F1: + print(sudoku) + if event.key == pg.K_F2: + idx = cursor.row * 9 + cursor.col + if not board[idx].given: + pencil_marks[idx].border = {i for i in range(1, 10)} + if event.key == pg.K_F3: + for i,cell in enumerate(board): + cell.value = sudoku.solution[i] - screen.fill('cornflower blue') + screen.fill('cornflower blue') - draw_grid() - with data_lock: - if sudoku is not None: - draw_numbers() - draw_cursor() - draw_hud() - draw_buttons() + draw_grid() + with data_lock: + if sudoku is not None: + draw_numbers() + draw_cursor() + draw_hud() + draw_buttons() - pg.display.flip() + pg.display.flip() - dt = clock.tick(60) / 1000 + dt = clock.tick(60) / 1000 -pg.quit() + pg.quit() + +if __name__ == "__main__": + main() diff --git a/pydoku.todo b/pydoku.todo index 60635ec..ad48d44 100644 --- a/pydoku.todo +++ b/pydoku.todo @@ -15,11 +15,12 @@ * DONE Improve pencil mark colors * DONE Async http request * DONE Generalized button code +* DONE Wrap around the board +* DONE Delete center pencil marks 1 num at a time +* DONE Pass difficulty through command line * TODO Button to load a new puzzle * TODO Show errors -* TODO Pass difficulty through command line * TODO Choose difficulty buttons -* TODO Delete center pencil marks 1 num at a time * TODO Toast on valid solve * TODO Show the time it took * TODO Save current game @@ -27,4 +28,7 @@ * TODO Show current input method * TODO Show keybindings somehow * TODO Pause button -* TODO Support undo +* TODO Support undo? +* TODO Sudoku generator +* TODO Sudoku solver +* TODO Sudoku difficulty generator diff --git a/websudoku.py b/websudoku.py index 17e4a27..dccfe07 100644 --- a/websudoku.py +++ b/websudoku.py @@ -48,7 +48,8 @@ def get_sudoku_puzzle(difficulty: Difficulty) -> Sudoku: Returns: A Sudoku object which contains the cheat and the editmask """ - response = urlopen("https://five.websudoku.com/?level=4") + d = str(difficulty.value) + response = urlopen("https://six.websudoku.com/?level="+d, timeout=5) if response.status == 200: html_content = response.read().decode('utf-8')