importScripts("seedrandom.js"); importScripts("generator.js"); let workerId; let winType; let numbers; let currentInput = ""; let attempts = 0; let startedAt; let statsInterval; let guessInterval; function getBoard(name) { Math.seedrandom(name); let numbers = []; for (let i = 0; i < 9; i++) { numbers = numbers.concat(generate_col(i)); } const activatedCols = generate_rows_check(); const board = [[], [], []]; for (let row = 0; row < 3; row++) { for (const col of activatedCols[row]) { board[row].push(numbers[(col - 1) * 3 + row]); } } return board; } function generateNextInput(input) { const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; if (input.length === 0) return alphabet[0]; for (let i = input.length - 1; i >= 0; i--) { const index = alphabet.indexOf(input[i]); if (index < alphabet.length - 1) { return input.substring(0, i) + alphabet[index + 1] + alphabet[0].repeat(input.length - i - 1); } } return alphabet[0] + input; } function hasWonRow(row, numbers) { return numbers.every(number => row.includes(number)); } function getRowsWon(board, numbers) { return board.filter(row => hasWonRow(row, numbers)).length; } function hasWon(wonRows, winType) { switch (winType) { case "row": return wonRows >= 1; case "two-rows": return wonRows >= 2; case "full-board": return wonRows >= 3; } } function guess() { currentInput = generateNextInput(currentInput); attempts++; const board = getBoard(currentInput); const wonRows = getRowsWon(board, numbers); if (hasWon(wonRows, winType)) { self.postMessage({ type: "winner", name: currentInput }); self.postMessage({ type: "log", text: `Found winner: ${currentInput}`, id: workerId }); } } function sendStats() { if (!startedAt) return; self.postMessage({ type: "stats", attempts, time: Date.now() - startedAt }); resetStats(); } function resetStats() { attempts = 0; startedAt = Date.now(); } function run() { statsInterval = setInterval(sendStats, 1000); guessInterval = setInterval(guess, 0); resetStats(); self.postMessage({ type: "log", text: "Starting worker", id: workerId }); } function stop() { clearInterval(statsInterval); clearInterval(guessInterval); sendStats(); self.postMessage({ type: "log", text: "Stopping worker", id: workerId }); } self.onmessage = message => { switch (message.data.type) { case "init": workerId = message.data.id; winType = message.data.winType; numbers = message.data.numbers; self.postMessage({ type: "ready" }); break; case "run": run(); break; case "stop": stop(); break; case "terminate": stop(); self.postMessage({ type: "terminate" }); break; } };