diff --git a/index.html b/index.html
index ae9f447..dacbb87 100644
--- a/index.html
+++ b/index.html
@@ -31,12 +31,21 @@
 
 				<fieldset class="input-container">
 					<legend>Workers</legend>
-					<input id="workers" type="number" min="1" value="1">
+
+					<label>
+						Amount:
+						<input id="workers" type="number" min="1" value="1" style="width: 70px;">
+					</label>
+
+					<label>
+						Batch size:
+						<input id="batch-size" type="number" min="1" value="1000" style="width: 100px;">
+					</label>
 				</fieldset>
 			</div>
 
-			<div>
-				<fieldset id="numbers-container" class="input-container">
+			<div id="numbers-container">
+				<fieldset class="input-container">
 					<legend>Numbers</legend>
 					<input class="number-input" type="number" min="1" max="90">
 				</fieldset>
@@ -51,10 +60,12 @@
 				</b>
 			</div>
 
-			<fieldset>
-				<legend>Log</legend>
-				<div id="log"></div>
-			</fieldset>
+			<div>
+				<fieldset>
+					<legend>Log</legend>
+					<div id="log"></div>
+				</fieldset>
+			</div>
 		</main>
 	</body>
 </html>
diff --git a/main.js b/main.js
index 598957c..6825fed 100644
--- a/main.js
+++ b/main.js
@@ -2,10 +2,13 @@ let paused = false;
 let workers = [];
 let totalTime = 0;
 let totalAttempts = 0;
+let names = [];
+
+fetch("names.json").then(res => res.json()).then(json => names = json);
 
 function showStats() {
 	document.getElementById("attempts").innerText = totalAttempts;
-	document.getElementById("speed").innerText = (totalAttempts / totalTime).toFixed(2);
+	document.getElementById("speed").innerText = (totalAttempts / totalTime).toFixed(2); // TODO fix totalTime
 }
 
 function log(text, workerId) {
@@ -38,12 +41,21 @@ function runWorkers() {
 	resetWorkers();
 
 	const amount = document.getElementById("workers").valueAsNumber;
+	const batchSize = document.getElementById("batch-size").valueAsNumber;
 
 	log(`Creating ${amount} workers`);
 	log(`* Win type: ${winType}`);
 	log(`* Numbers: ${numbers.join(", ")}`);
 
+	const usedNames = [];
+
 	for (let i = 0; i < amount; i++) {
+		let name;
+		do
+			name = names[Math.floor(Math.random() * names.length)];
+		while (usedNames.includes(name));
+		usedNames.push(name);
+
 		const worker = new Worker("worker.js");
 		worker.addEventListener("message", message => {
 			switch (message.data.type) {
@@ -66,7 +78,7 @@ function runWorkers() {
 			}
 		});
 
-		worker.postMessage({ type: "init", id: i + 1, numbers, winType });
+		worker.postMessage({ type: "init", id: i + 1, numbers, winType, name, batchSize });
 		workers.push(worker);
 	}
 }
diff --git a/style.css b/style.css
index fc619ce..ba19d3b 100644
--- a/style.css
+++ b/style.css
@@ -18,11 +18,26 @@ main {
 .input-container {
 	display: flex;
 	flex-direction: column;
+	flex-wrap: wrap;
 	gap: 0.5rem;
 	background-color: #EEE;
 	margin: 0.5rem;
 }
 
+#numbers-container .input-container {
+	max-height: 800px;
+	display: flex;
+	flex-direction: row;
+}
+
+#numbers-container input {
+	flex-basis: calc(50% - 4px);
+}
+
+#numbers-container {
+	width: 400px;
+}
+
 #results {
 	margin-top: 1rem;
 	width: 400px;
diff --git a/worker.js b/worker.js
index d1eee94..ee4a58d 100644
--- a/worker.js
+++ b/worker.js
@@ -2,10 +2,12 @@ importScripts("seedrandom.js");
 importScripts("generator.js");
 
 let workerId;
+let workerName;
 let winType;
 let numbers;
+let batchSize;
 
-let currentInput = "";
+let nameIndex = 0;
 let attempts = 0;
 let startedAt;
 
@@ -33,25 +35,8 @@ function getBoard(name) {
 	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));
+	return row.every(number => numbers.includes(number));
 }
 
 function getRowsWon(board, numbers) {
@@ -70,16 +55,19 @@ function hasWon(wonRows, winType) {
 }
 
 function guess() {
-	currentInput = generateNextInput(currentInput);
-	attempts++;
+	for (let i = 0; i < 100; i++) {
+		const name = workerName + nameIndex++;
+		attempts++;
 
-	const board = getBoard(currentInput);
-	
-	const wonRows = getRowsWon(board, numbers);
+		const board = getBoard(name);
+		
+		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 });
+		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 });
+		}
 	}
 }
 
@@ -105,9 +93,14 @@ function run() {
 }
 
 function stop() {
+	if (!statsInterval && !guessInterval) return;
+
 	clearInterval(statsInterval);
 	clearInterval(guessInterval);
 
+	statsInterval = null;
+	guessInterval = null;
+
 	sendStats();
 
 	self.postMessage({ type: "log", text: "Stopping worker", id: workerId });
@@ -117,8 +110,10 @@ 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":