diff --git a/pydoku.py b/pydoku.py index 3b2921d..432f824 100644 --- a/pydoku.py +++ b/pydoku.py @@ -4,6 +4,8 @@ from dataclasses import dataclass, field from enum import Enum from typing import Set +import threading + import os from websudoku import * @@ -68,22 +70,34 @@ cursorSurface = pg.Surface((CURSOR_SIZE, CURSOR_SIZE), pg.SRCALPHA) cursor = Cursor() input_method = InputMethod.FILL -# TODO: We have to make this async -sudoku = get_sudoku_puzzle(Difficulty.EVIL) -# sudoku = get_sudoku_puzzle_test() - board = [] - -for i in range(81): - if sudoku.editmask[i] == 0: - board.append(Cell(sudoku.solution[i], True)) - else: - board.append(Cell()) - pencil_marks = [] -for i in range(81): - pm = PencilMark() if not board[i].given else None - pencil_marks.append(pm) +sudoku = None + +data_lock = threading.Lock() + +def data_callback(sudoku_data): + # Handle the data here, e.g., store it in a global variable + for i in range(81): + if sudoku_data.editmask[i] == 0: + board.append(Cell(sudoku_data.solution[i], True)) + else: + board.append(Cell()) + + for i in range(81): + pm = PencilMark() if not board[i].given else None + pencil_marks.append(pm) + global sudoku + with data_lock: + sudoku = sudoku_data + + +def http_request_thread(): + data = get_sudoku_puzzle(Difficulty.EVIL) + data_callback(data) + +http_thread = threading.Thread(target=http_request_thread) +http_thread.start() def draw_grid(): @@ -214,7 +228,7 @@ while running: if num.isdigit() and num != '0': num = int(num) idx = (cursor.row - 1) * 9 + cursor.col - 1 - if not board[idx].given: + if board and not board[idx].given: match input_method: case InputMethod.FILL: board[idx].value = num @@ -260,7 +274,9 @@ while running: screen.fill('cornflower blue') draw_grid() - draw_numbers() + with data_lock: + if sudoku is not None: + draw_numbers() draw_cursor() draw_hud() draw_buttons() diff --git a/pydoku.todo b/pydoku.todo index 6873459..7754872 100644 --- a/pydoku.todo +++ b/pydoku.todo @@ -13,10 +13,18 @@ * DONE Add "Done" button * DONE Check if puzzle is complete * DONE Improve pencil mark colors +* DONE Async http request * TODO Show errors +* TODO Generalized button code * TODO Pass difficulty through command line +* TODO Choose difficulty buttons +* TODO Button to load a new puzzle +* 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 * TODO Create a pip file -* TODO Help labels +* TODO Show current input method +* TODO Show keybindings somehow +* TODO Pause button +* TODO Support undo diff --git a/websudoku.py b/websudoku.py index d4a8a31..17e4a27 100644 --- a/websudoku.py +++ b/websudoku.py @@ -1,4 +1,4 @@ -import http.client +from urllib.request import urlopen import re from enum import Enum from dataclasses import dataclass @@ -17,7 +17,7 @@ class Difficulty(Enum): host = "five.websudoku.com" -def get_sudoku_puzzle_test(): +async def get_sudoku_puzzle_test(): cheat = [ 1,7,6,5,9,4,3,2,8, 3,5,8,6,7,2,9,1,4, 2,9,4,8,1,3,6,5,7, @@ -39,7 +39,6 @@ def get_sudoku_puzzle_test(): return Sudoku(cheat, editmask) - def get_sudoku_puzzle(difficulty: Difficulty) -> Sudoku: """Makes a web request to websudoku.com to grab a sudoku puzzle @@ -49,22 +48,15 @@ def get_sudoku_puzzle(difficulty: Difficulty) -> Sudoku: Returns: A Sudoku object which contains the cheat and the editmask """ - - conn = http.client.HTTPSConnection(host) - - conn.request("GET", "/?level=2") - - response = conn.getresponse() + response = urlopen("https://five.websudoku.com/?level=4") if response.status == 200: html_content = response.read().decode('utf-8') - # print(html_content) for line in html_content.split('\n'): if "editmask" in line: editmask = [ int(n) for n in re.findall(r'\d', line) ] if "var cheat" in line: cheat = [ int(n) for n in re.findall(r'\d', line) ] - conn.close() return Sudoku(cheat, editmask) else: print("Error getting sudoku puzzle:", response.status, response.reason)