Add neat arena
This commit is contained in:
70
src/lib/snakeAI/workerPool.ts
Normal file
70
src/lib/snakeAI/workerPool.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import EvolutionWorker from './evolution.worker?worker';
|
||||
import type { Population, Individual } from './evolution';
|
||||
import type { EvolutionConfig } from './types';
|
||||
|
||||
export class WorkerPool {
|
||||
private workers: Worker[] = [];
|
||||
private poolSize: number;
|
||||
|
||||
constructor(size: number = navigator.hardwareConcurrency || 4) {
|
||||
this.poolSize = size;
|
||||
for (let i = 0; i < size; i++) {
|
||||
this.workers.push(new EvolutionWorker());
|
||||
}
|
||||
}
|
||||
|
||||
terminate() {
|
||||
this.workers.forEach(w => w.terminate());
|
||||
this.workers = [];
|
||||
}
|
||||
|
||||
async evaluateParallel(population: Population, config: EvolutionConfig): Promise<Population> {
|
||||
// Split individuals into chunks
|
||||
const chunkSize = Math.ceil(population.individuals.length / this.poolSize);
|
||||
const chunks: Individual[][] = [];
|
||||
|
||||
for (let i = 0; i < population.individuals.length; i += chunkSize) {
|
||||
chunks.push(population.individuals.slice(i, i + chunkSize));
|
||||
}
|
||||
|
||||
// Dispatch chunks to workers
|
||||
const promises = chunks.map((chunk, index) => {
|
||||
return new Promise<Individual[]>((resolve, reject) => {
|
||||
const worker = this.workers[index];
|
||||
|
||||
// One-time listener for this request
|
||||
const handler = (e: MessageEvent) => {
|
||||
if (e.data.type === 'EVAL_RESULT') {
|
||||
worker.removeEventListener('message', handler);
|
||||
resolve(e.data.payload);
|
||||
} else if (e.data.type === 'ERROR') {
|
||||
worker.removeEventListener('message', handler);
|
||||
reject(e.data.payload);
|
||||
}
|
||||
};
|
||||
|
||||
worker.addEventListener('message', handler);
|
||||
|
||||
worker.postMessage({
|
||||
type: 'EVALUATE_ONLY',
|
||||
payload: {
|
||||
individuals: chunk,
|
||||
config
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Wait for all chunks
|
||||
const results = await Promise.all(promises);
|
||||
|
||||
// Merge results
|
||||
const mergedIndividuals = results.flat();
|
||||
|
||||
// Reconstruct population with evaluated individuals
|
||||
return {
|
||||
...population,
|
||||
individuals: mergedIndividuals
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user