mags-banko/worker.js

132 lines
2.5 KiB
JavaScript

importScripts("seedrandom.js");
importScripts("generator.js");
let workerId;
let workerName;
let winType;
let numbers;
let batchSize;
let nameIndex = 0;
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 hasWonRow(row, numbers) {
return row.every(number => numbers.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() {
for (let i = 0; i < 100; i++) {
const name = workerName + nameIndex++;
attempts++;
const board = getBoard(name);
const wonRows = getRowsWon(board, numbers);
if (hasWon(wonRows, winType)) {
console.log(board, board.filter(row => hasWonRow(row, numbers)), numbers);
self.postMessage({ type: "winner", name });
self.postMessage({ type: "log", text: `Found winner: ${name}`, 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() {
if (!statsInterval && !guessInterval) return;
clearInterval(statsInterval);
clearInterval(guessInterval);
statsInterval = null;
guessInterval = null;
sendStats();
self.postMessage({ type: "log", text: "Stopping worker", id: workerId });
}
self.onmessage = message => {
switch (message.data.type) {
case "init":
workerId = message.data.id;
workerName = message.data.name;
winType = message.data.winType;
numbers = message.data.numbers;
batchSize = message.data.batchSize;
self.postMessage({ type: "ready" });
break;
case "run":
run();
break;
case "stop":
stop();
break;
case "terminate":
stop();
self.postMessage({ type: "terminate" });
break;
}
};