Wrote a widget for a game where it’s sudoku, but there is a wordle-like element. I haven’t coded in forever, and the ten-hours of back and forth I had with the chatbot reminded me very much why I decided not to pursue a career in computer programming. The chatbot was sometimes great at catching bugs, but in the next iteration it would put the same bug right back in. Sometimes I would have to comb the code to find the problem myself. That was an odd feeling because I’m pretty rusty, but I was able to understand what everything did, partially due to the really helpful comments that the chatbot put in. It was kinda like trying to write an essay in a language that I can read, but can’t speak conversationally.

I’ll summarize how the process felt with this old coder joke:

99 little bugs in the code

99 lovely bugs

you take one down, you patch it around

143 bugs in the code.

Sudoku with Letters body { font-family: ‘Arial’, sans-serif; background-color: #f7f7f7; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; } h1 { color: #333; margin-bottom: 20px; } #word-guess { margin-bottom: 20px; } #word-guess input { width: 30px; height: 30px; text-align: center; font-size: 18px; font-weight: bold; margin: 2px; border: 2px solid #ccc; border-radius: 5px; outline: none; } #word-guess input.correct { background-color: #ccffcc; border-color: #00cc00; } #word-guess input.present { background-color: #ffffcc; border-color: #ffcc00; } #word-guess input.absent { background-color: #f0f0f0; border-color: #ccc; } table { border-collapse: collapse; border: 3px solid #333; background-color: #fff; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } td { width: 50px; height: 50px; text-align: center; border: 1px solid #ccc; font-size: 20px; font-weight: bold; color: #333; } td input { width: 100%; height: 100%; text-align: center; font-size: 20px; font-weight: bold; border: none; outline: none; background-color: transparent; color: #333; } .fixed { background-color: #e0e0e0; } .thick-border-right { border-right: 3px solid #333; } .thick-border-bottom { border-bottom: 3px solid #333; } .highlight { background-color: #ffcccc; } button { margin-top: 20px; padding: 10px 20px; font-size: 16px; font-weight: bold; color: #fff; background-color: #333; border: none; border-radius: 5px; cursor: pointer; transition: background-color 0.3s ease; } button:hover { background-color: #555; } #result { margin-top: 20px; font-size: 18px; font-weight: bold; color: #333; } #timer { margin-top: 10px; font-size: 18px; font-weight: bold; color: #333; } #message { margin-top: 20px; font-size: 16px; color: #333; } #copy-button { margin-top: 10px; }

Sudoku with Letters

Check Word
Check Sudoku
Time: 0s

Copy Message to Clipboard const word = “DISCOVERY”; // 9-letter word with unique letters let board = generateSudoku(); let solution = JSON.parse(JSON.stringify(board)); // Create a copy of the solved board BEFORE removing numbers removeNumbers(board); // Remove numbers to create the puzzle displaySudoku(board); let startTime = Date.now(); let timerInterval; let solvedTime = null; let wordSolved = false; let wordSolvedTime = null; // Start the timer startTimer(); function startTimer() { timerInterval = setInterval(() => { const elapsedTime = Math.floor((Date.now() – startTime) / 1000); document.getElementById(‘timer’).textContent = `Time: ${elapsedTime}s`; }, 1000); } function stopTimer() { clearInterval(timerInterval); } function generateSudoku() { const board = Array.from({ length: 9 }, () => Array(9).fill(0)); fillDiagonal(board); fillRemaining(board, 0, 3); return board; } function fillDiagonal(board) { for (let i = 0; i < 9; i += 3) { fillBox(board, i, i); } } function fillBox(board, row, col) { let num; for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { do { num = Math.floor(Math.random() * 9) + 1; } while (!isValidInBox(board, row, col, num)); board[row + i][col + j] = num; } } } function isValidInBox(board, row, col, num) { for (let i = 0; i < 3; i++) { for (let j = 0; j = 9 && row = 9 && col >= 9) { return true; } if (row < 3) { if (col < 3) { col = 3; } } else if (row = 9) { return true; } } } for (let num = 1; num <= 9; num++) { if (isValid(board, row, col, num)) { board[row][col] = num; if (fillRemaining(board, row, col + 1)) { return true; } board[row][col] = 0; } } return false; } function isValid(board, row, col, num) { return !isInRow(board, row, num) && !isInCol(board, col, num) && !isInBox(board, row – row % 3, col – col % 3, num); } function isInRow(board, row, num) { for (let col = 0; col < 9; col++) { if (board[row][col] === num) { return true; } } return false; } function isInCol(board, col, num) { for (let row = 0; row < 9; row++) { if (board[row][col] === num) { return true; } } return false; } function isInBox(board, startRow, startCol, num) { for (let row = 0; row < 3; row++) { for (let col = 0; col < 3; col++) { if (board[startRow + row][startCol + col] === num) { return true; } } } return false; } function removeNumbers(board) { let count = 30; // Number of cells to empty (increased from 20 to 30) while (count !== 0) { let row = Math.floor(Math.random() * 9); let col = Math.floor(Math.random() * 9); if (board[row][col] !== 0) { board[row][col] = 0; count–; } } } function displaySudoku(board) { const table = document.getElementById('sudoku'); for (let i = 0; i < 9; i++) { const row = document.createElement('tr'); for (let j = 0; j < 9; j++) { const cell = document.createElement('td'); // Apply thicker borders to enclose each 3×3 section if (j === 2 || j === 5 || j === 8) { cell.classList.add('thick-border-right'); } if (i === 2 || i === 5 || i === 8) { cell.classList.add('thick-border-bottom'); } if (board[i][j] !== 0) { cell.textContent = word[board[i][j] – 1]; cell.classList.add('fixed'); } else { const input = document.createElement('input'); input.type = 'text'; input.maxLength = 1; input.oninput = function() { this.value = this.value.toUpperCase(); }; cell.appendChild(input); } row.appendChild(cell); } table.appendChild(row); } } function checkSolution() { const table = document.getElementById('sudoku'); let isCorrect = true; clearHighlights(table); for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { const cell = table.rows[i].cells[j]; if (cell.classList.contains('fixed')) { continue; } const input = cell.querySelector('input'); const userValue = input ? input.value.toUpperCase() : ''; const correctValue = word[solution[i][j] – 1]; // Compare to the solution if (userValue !== correctValue) { isCorrect = false; highlightConflicts(table, i, j, userValue); } } } if (isCorrect) { stopTimer(); solvedTime = new Date(); const elapsedTime = Math.floor((Date.now() – startTime) / 1000); let message = `Congratulations! You solved the Sudoku puzzle in ${elapsedTime}s.`; if (wordSolved) { const wordTime = Math.floor((wordSolvedTime – startTime) / 1000); message += `\nYou solved the word puzzle ${wordTime}s into the game.`; } else { message += "\nYou didn't solve the word puzzle, but great job on the Sudoku!"; } document.getElementById('message').textContent = message; document.getElementById('copy-button').style.display = 'block'; document.getElementById('result').textContent = 'Correct! 🎉'; } else { document.getElementById('result').textContent = 'Incorrect! ❌'; } } function clearHighlights(table) { for (let i = 0; i < 9; i++) { for (let j = 0; j < 9; j++) { const cell = table.rows[i].cells[j]; cell.classList.remove('highlight'); } } } function highlightConflicts(table, row, col, value) { if (!value) return; // Highlight conflicts in the same row for (let j = 0; j < 9; j++) { const cell = table.rows[row].cells[j]; const cellValue = cell.textContent || (cell.querySelector('input') ? cell.querySelector('input').value.toUpperCase() : ''); if (cellValue === value) { cell.classList.add('highlight'); } } // Highlight conflicts in the same column for (let i = 0; i < 9; i++) { const cell = table.rows[i].cells[col]; const cellValue = cell.textContent || (cell.querySelector('input') ? cell.querySelector('input').value.toUpperCase() : ''); if (cellValue === value) { cell.classList.add('highlight'); } } // Highlight conflicts in the same 3×3 box const startRow = Math.floor(row / 3) * 3; const startCol = Math.floor(col / 3) * 3; for (let i = startRow; i < startRow + 3; i++) { for (let j = startCol; j { guess += input.value.toUpperCase(); }); if (guess.length !== 9) { alert(‘Please enter a 9-letter word.’); return; } inputs.forEach((input, index) => { const letter = input.value.toUpperCase(); if (letter === word[index]) { input.classList.add(‘correct’); input.classList.remove(‘present’, ‘absent’); } else if (word.includes(letter)) { input.classList.add(‘present’); input.classList.remove(‘correct’, ‘absent’); } else { input.classList.add(‘absent’); input.classList.remove(‘correct’, ‘present’); } }); if (guess === word) { wordSolved = true; wordSolvedTime = Date.now(); alert(‘Congratulations! You solved the word puzzle!’); } } function moveToNext(currentInput, nextIndex) { if (currentInput.value.length === 1) { const nextInput = document.querySelector(`#word-guess input:nth-child(${nextIndex + 1})`); if (nextInput) { nextInput.focus(); } } } function handleBackspace(currentInput, currentIndex) { if (event.key === ‘Backspace’ && currentInput.value === ”) { const prevInput = document.querySelector(`#word-guess input:nth-child(${currentIndex – 1})`); if (prevInput) { prevInput.focus(); prevInput.value = ”; // Clear the previous input } } } function copyMessage() { const message = document.getElementById(‘message’).textContent; navigator.clipboard.writeText(message).then(() => { alert(‘Message copied to clipboard!’); }); }

Leave a comment