137 lines
2.7 KiB
JavaScript
137 lines
2.7 KiB
JavaScript
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;
|
|
}
|
|
};
|
|
|