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