diff --git a/docs/css/styles.css b/docs/css/styles.css index 54aeb9b..f6ea185 100644 --- a/docs/css/styles.css +++ b/docs/css/styles.css @@ -620,21 +620,6 @@ body.dtark-theme td { /* Pseudo-element for the board */ /* ------------------- */ - #input-board, .board-example { - font-family: monospace; /* Use a monospace font */ - width: calc(12ch + 5px); /* 9 characters wide plus a little extra for padding/border */ - white-space: pre-wrap; /* Allows text to wrap */ - overflow-wrap: break-word; /* Ensures long words can break and wrap to the next line */ - resize: none; /* Optional: Prevents resizing */ - border: 1px solid #000; /* Add a border for contrast */ - min-height: 150px; /* Adjust as needed */ - /* add spaces between chars */ - letter-spacing: 3px; - margin:0; - padding:0; - padding-left: 5px; - padding-top: 3px; - } .actions { display: flex; diff --git a/docs/index.html b/docs/index.html index 95ef5d8..6fdb0a3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,17 +8,21 @@ <meta name="author" content="Dor Pascal"> <meta property="og:title" content="Snap & Solve: Turn Puzzle Images into Sudoku Answers" /> <meta property="og:image" content="https://dorpascal.com/AlphaSudokuGo/sudoku-solver.png" /> - <meta property="og:description" content="Fastest Sudoku solver ever. Enter a board, click solve, and see the magic happen. Built by Dor." /> + <meta property="og:description" + content="Fastest Sudoku solver ever. Enter a board, click solve, and see the magic happen. Built by Dor." /> <meta property="og:url" content="https://dorpascal.com/AlphaSudokuGo/" /> <meta property="og:type" content="website" /> <link rel="canonical" href="https://dorpascal.com/AlphaSudokuGo/" /> - <meta name="description" content="Fastest Sudoku solver ever. Enter a board, click solve, and see the magic happen. Built by Dor." /> + <meta name="description" + content="Fastest Sudoku solver ever. Enter a board, click solve, and see the magic happen. Built by Dor." /> <meta name="keywords" content="sudoku, solver, puzzle, game, board, image, recognition, AI, OCR, tesseract"> <meta name="robots" content="index, follow"> <meta name="theme-color" content="#368dd9"> <link rel="icon" href="./favicon.ico"> <link rel="preload" href="./css/styles.css" as="style"> - <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&family=Roboto:wght@400;700&display=swap" rel="stylesheet"> + <link + href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&family=Roboto:wght@400;700&display=swap" + rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"> <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css" rel="stylesheet" /> <link rel="stylesheet" href="./css/styles.css"> @@ -124,7 +128,8 @@ <h2>How to use the Interactive Board</h2> <p>Try to copy and paste the hardest Sudoku puzzle ever (according to <a href="https://www.telegraph.co.uk/news/science/science-news/9359579/Worlds-hardest-sudoku-can-you-crack-it.html" target="_blank">The Telegraph</a>).</p> - <textarea class="board-example">8..........36......7..9.2...5...7.......457.....1...3...1....68..85...1..9....4..</textarea> + <textarea + class="board-example">8..........36......7..9.2...5...7.......457.....1...3...1....68..85...1..9....4..</textarea> <br> <button class="copy-btn" data-text="8..........36......7..9.2...5...7.......457.....1...3...1....68..85...1..9....4.." @@ -135,19 +140,16 @@ <h2>How to use the Interactive Board</h2> </div> </div> </div> - -<textarea id="input-board"></textarea> -<div class="actions"> - <button class="reset-button" onclick="resetBoard()"> - <i class="fas fa-sync-alt"></i> - </button> - <button onclick="solveSudoku()" class="solve-button"> - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" - stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> - <polygon points="5 3 19 12 5 21 5 3"></polygon> - </svg> - </button> - </div> + <input id="input-board" type="text" placeholder="Enter board as one line..."> + <button class="reset-button" onclick="resetBoard()"> + <i class="fas fa-sync-alt"></i> + </button> + <button onclick="solveSudoku()" class="solve-button" aria-label="Solve Sudoku" id="solve-button"> + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" + stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> + <polygon points="5 3 19 12 5 21 5 3"></polygon> + </svg> + </button> </div> </main> <footer> @@ -155,56 +157,39 @@ <h2>How to use the Interactive Board</h2> <script>document.write(new Date().getFullYear());</script> </p> </footer> - <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js" ></script> - <script src="https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js" ></script> - <script src="./js/sudoku.js" ></script> - <script src="./js/tutorial.js" ></script> - <script src="./js/parser.js" ></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script> + <script src="https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js"></script> + <script src="./js/sudoku.js"></script> + <script src="./js/tutorial.js"></script> <script> - const fileInput = document.getElementById('fileInput'); - const themeToggle = document.getElementById('theme-toggle'); - const tutorialPopup = document.getElementById('tutorial-popup'); + const fileInput = document.getElementById('fileInput'); + const themeToggle = document.getElementById('theme-toggle'); + const tutorialPopup = document.getElementById('tutorial-popup'); - function toggleTheme() { - themeToggle.classList.toggle('toggle-on'); - document.body.classList.toggle('dark-theme'); - } + function toggleTheme() { + themeToggle.classList.toggle('toggle-on'); + document.body.classList.toggle('dark-theme'); + } - function closePopup() { - tutorialPopup.style.display = 'none'; - } + function closePopup() { + tutorialPopup.style.display = 'none'; + } - themeToggle.addEventListener('click', toggleTheme); - fileInput.addEventListener('change', function () { - handleFileSelection(this.files); - }); + themeToggle.addEventListener('click', toggleTheme); - document.addEventListener('drop', function (event) { - event.preventDefault(); - handleFileSelection(event.dataTransfer.files); - }); - document.addEventListener('dragover', function (event) { - event.preventDefault(); - }); - document.body.addEventListener('click', function (e) { - if (e.target.classList.contains('close-btn')) { - closePopup(); - } - }); + document.addEventListener('dragover', function (event) { + event.preventDefault(); + }); - document.getElementById('cancelCrop').addEventListener('click', function () { - document.getElementById('parser').style.display = 'none'; - // kill all workers - if (typeof worker !== 'undefined') { - worker.terminate(); - } - if (typeof cropper !== 'undefined') { - cropper.destroy(); - } - resetUI(); - }); + document.body.addEventListener('click', function (e) { + if (e.target.classList.contains('close-btn')) { + closePopup(); + } + }); + + function solveSudoku() { const boardStr = readBoard(); @@ -223,8 +208,6 @@ <h2>How to use the Interactive Board</h2> const solvedBoardStr = csp.getBoard(); console.log(solvedBoardStr); updateBoard(solvedBoardStr); - - celebrate(); } function readBoard() { @@ -249,7 +232,7 @@ <h2>How to use the Interactive Board</h2> } function resetBoard() { - /* if in the middle of solving or parsing, reset the board */ + /* if in the middle of solving or parsing, reset the board */ updateBoard('.................................................................................'); } @@ -287,10 +270,12 @@ <h2>How to use the Interactive Board</h2> changeTheme(); }, 4000); } - const script = document.createElement('script'); + const script = document.createElement('script'); script.src = './src/sudoku_solver.js'; document.body.appendChild(script); </script> + <script src="./js/parser.js"></script> + </body> </html> \ No newline at end of file diff --git a/docs/js/parser.js b/docs/js/parser.js index da5c7c1..2c709b6 100644 --- a/docs/js/parser.js +++ b/docs/js/parser.js @@ -1,5 +1,26 @@ // const DEBUG = localStorage.getItem('debug') === 'true' || new URLSearchParams(window.location.search).get('debug') === 'true'; const DEBUG = false; + + document.getElementById('cancelCrop').addEventListener('click', function () { + document.getElementById('parser').style.display = 'none'; + // kill all workers + if (typeof worker !== 'undefined') { + worker.terminate(); + } + if (typeof cropper !== 'undefined') { + cropper.destroy(); + } + resetUI(); + }); + fileInput.addEventListener('change', function () { + handleFileSelection(this.files); + }); + + document.addEventListener('drop', function (event) { + event.preventDefault(); + handleFileSelection(event.dataTransfer.files); + }); + async function handleFileSelection(files) { if (files.length > 0) { console.log('Handling file selection'); @@ -73,7 +94,7 @@ let cropper; document.getElementById('sudoku-board').style.display = 'grid'; document.getElementById('parser').style.display = 'none'; } - document.getElementsByClassName('actions')[0].style.display = 'block'; + document.getElementById('solve-button').style.display = 'block'; document.getElementById('rotationSlider').style.display = 'none'; if (cropper) { let croppedCanvas = cropper.getCroppedCanvas(); diff --git a/docs/js/sudoku.js b/docs/js/sudoku.js index ced1787..51df5fa 100644 --- a/docs/js/sudoku.js +++ b/docs/js/sudoku.js @@ -261,43 +261,5 @@ document.addEventListener('DOMContentLoaded', () => { } } } -// Handle arrow key navigation and spinning -document.addEventListener('keydown', function (e) { - const { row, col } = getCurrentCellPosition(); - const cell = document.querySelector(`.spinner[data-row='${row}'][data-col='${col}']`); - // Check if cell exists - if (!cell) { - console.error(`No cell found at row ${row}, col ${col}`); - return; // Exit the function if no cell is found - } - - const wheel = cell.querySelector('.wheel'); - - // Check if wheel exists - if (!wheel) { - console.error(`No wheel found in cell at row ${row}, col ${col}`); - return; // Exit the function if no wheel is found - } - - let currentTransform = parseInt(wheel.style.transform.split('(')[1].split('px')[0]); - - if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { - e.preventDefault(); - let delta = e.key === 'ArrowUp' ? -50 : 50; - let newTransform = currentTransform + delta; - let closestDigit = findClosestDigit(newTransform); - wheel.style.transform = `translateY(${digitTransforms[closestDigit]}px)`; - cell.dataset.value = closestDigit; - synchronizeInputBoard(); - } - - if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') { - e.preventDefault(); - if (e.key === 'ArrowLeft') { - moveToPreviousCell(row, col); - } else if (e.key === 'ArrowRight') { - moveToNextCell(row, col); - } - } -}); \ No newline at end of file +