Fix build errors
This commit is contained in:
@@ -8,7 +8,6 @@ export interface Genome {
|
|||||||
|
|
||||||
export class GeneticAlgo {
|
export class GeneticAlgo {
|
||||||
private population: Genome[] = [];
|
private population: Genome[] = [];
|
||||||
private layerSizes: number[];
|
|
||||||
private popSize: number;
|
private popSize: number;
|
||||||
private mutationRate: number;
|
private mutationRate: number;
|
||||||
private mutationScale: number;
|
private mutationScale: number;
|
||||||
@@ -25,7 +24,6 @@ export class GeneticAlgo {
|
|||||||
mutationScale = 0.5 // Gaussian/random perturbation amount (increased)
|
mutationScale = 0.5 // Gaussian/random perturbation amount (increased)
|
||||||
) {
|
) {
|
||||||
this.popSize = popSize;
|
this.popSize = popSize;
|
||||||
this.layerSizes = layerSizes;
|
|
||||||
this.mutationRate = mutationRate;
|
this.mutationRate = mutationRate;
|
||||||
this.mutationScale = mutationScale;
|
this.mutationScale = mutationScale;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class LanderScene extends Phaser.Scene {
|
|||||||
|
|
||||||
preload() {
|
preload() {
|
||||||
// Generate a simple particle texture programmatically
|
// Generate a simple particle texture programmatically
|
||||||
const gfx = this.make.graphics({ x: 0, y: 0, add: false });
|
const gfx = this.make.graphics({ x: 0, y: 0 });
|
||||||
gfx.fillStyle(0xffffff);
|
gfx.fillStyle(0xffffff);
|
||||||
gfx.fillCircle(4, 4, 4); // 8x8 circle
|
gfx.fillCircle(4, 4, 4); // 8x8 circle
|
||||||
gfx.generateTexture('flame', 8, 8);
|
gfx.generateTexture('flame', 8, 8);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ export class LanderSimulation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private crash(reason: string) {
|
private crash(_reason: string) {
|
||||||
this.result = 'CRASHED';
|
this.result = 'CRASHED';
|
||||||
this.isGameOver = true;
|
this.isGameOver = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useRef, useState, useCallback } from 'react';
|
import { useEffect, useRef, useState, useCallback } from 'react';
|
||||||
import type { Genotype, MapData } from './types';
|
import type { Genotype } from './types';
|
||||||
import { generateMap } from './generator';
|
import { generateMap } from './generator';
|
||||||
import { createRandomGenome, evaluatePopulation, evolve, type Individual, POPULATION_SIZE } from './evolution';
|
import { createRandomGenome, evaluatePopulation, evolve, type Individual, POPULATION_SIZE } from './evolution';
|
||||||
|
|
||||||
|
|||||||
@@ -277,10 +277,8 @@ function bfsFlood(grid: Uint8Array, width: number, height: number, startX: numbe
|
|||||||
const d = dists[packed];
|
const d = dists[packed];
|
||||||
|
|
||||||
// Inline neighbors
|
// Inline neighbors
|
||||||
const nOffsets = [-width, width, -1, 1]; // N, S, W, E
|
|
||||||
|
|
||||||
for(let i=0; i<4; i++) {
|
for(let i=0; i<4; i++) {
|
||||||
const idx = packed + nOffsets[i]; // Be careful of edges?
|
|
||||||
// Ideally we check bounds. But since perimeter is always wall (1),
|
// Ideally we check bounds. But since perimeter is always wall (1),
|
||||||
// we technically won't escape if we trust the wall.
|
// we technically won't escape if we trust the wall.
|
||||||
// BUT, index could wrap if we are at x=width-1 and do +1 -> next row x=0.
|
// BUT, index could wrap if we are at x=width-1 and do +1 -> next row x=0.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Phaser from 'phaser';
|
|||||||
import { CarSimulation } from './CarSimulation';
|
import { CarSimulation } from './CarSimulation';
|
||||||
import { Car } from './Car';
|
import { Car } from './Car';
|
||||||
import { DEFAULT_SIM_CONFIG, DEFAULT_CAR_CONFIG } from './types';
|
import { DEFAULT_SIM_CONFIG, DEFAULT_CAR_CONFIG } from './types';
|
||||||
import type { SerializedTrackData, SerializedBody, CarConfig, SimulationConfig } from './types';
|
import type { SerializedTrackData, CarConfig, SimulationConfig } from './types';
|
||||||
import { TrackGenerator } from './Track';
|
import { TrackGenerator } from './Track';
|
||||||
|
|
||||||
// NEAT Imports REMOVED
|
// NEAT Imports REMOVED
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import type { CarConfig, SimulationConfig } from './types';
|
import type { CarConfig, SimulationConfig } from './types';
|
||||||
import type { GAConfig } from './SimpleGA';
|
import type { GAConfig } from './SimpleGA';
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ export class SimpleGA {
|
|||||||
// Duplicating logic is safer to avoid instantiation overhead if large.
|
// Duplicating logic is safer to avoid instantiation overhead if large.
|
||||||
// Logic from DenseNetwork: sum((full_in + 1) * out)
|
// Logic from DenseNetwork: sum((full_in + 1) * out)
|
||||||
// Let's just instantiate one to be sure.
|
// Let's just instantiate one to be sure.
|
||||||
const dummy = new DenseNetwork(this.layerSizes);
|
|
||||||
const size = dummy.getWeights().length;
|
|
||||||
|
|
||||||
for (let i = 0; i < this.config.populationSize; i++) {
|
for (let i = 0; i < this.config.populationSize; i++) {
|
||||||
const dn = new DenseNetwork(this.layerSizes);
|
const dn = new DenseNetwork(this.layerSizes);
|
||||||
@@ -88,8 +86,6 @@ export class SimpleGA {
|
|||||||
let bestFitness = -Infinity;
|
let bestFitness = -Infinity;
|
||||||
|
|
||||||
for (let i = 0; i < k; i++) {
|
for (let i = 0; i < k; i++) {
|
||||||
const randIdx = indices[Math.floor(Math.random() * indices.length)]; // Pick from sorted or unsorted?
|
|
||||||
// Better to pick pure random index from 0..popSize-1
|
|
||||||
const r = Math.floor(Math.random() * indices.length);
|
const r = Math.floor(Math.random() * indices.length);
|
||||||
const realIdx = indices[r];
|
const realIdx = indices[r];
|
||||||
if (fitnesses[realIdx] > bestFitness) {
|
if (fitnesses[realIdx] > bestFitness) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export default function SnakeAI() {
|
|||||||
populationRef.current = population;
|
populationRef.current = population;
|
||||||
}, [population]);
|
}, [population]);
|
||||||
|
|
||||||
const animationFrameRef = useRef<number>();
|
const animationFrameRef = useRef<number>(0);
|
||||||
const lastUpdateRef = useRef<number>(0);
|
const lastUpdateRef = useRef<number>(0);
|
||||||
|
|
||||||
// Compute derived values for display
|
// Compute derived values for display
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const CANVAS_PADDING = 10;
|
|||||||
export default function SnakeCanvas({ network, gridSize, showGrid = true, size = 'normal', showStats = false, playbackSpeed = 15 }: SnakeCanvasProps) {
|
export default function SnakeCanvas({ network, gridSize, showGrid = true, size = 'normal', showStats = false, playbackSpeed = 15 }: SnakeCanvasProps) {
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const [currentGame, setCurrentGame] = useState<GameState | null>(null);
|
const [currentGame, setCurrentGame] = useState<GameState | null>(null);
|
||||||
const animationFrameRef = useRef<number>();
|
const animationFrameRef = useRef<number>(0);
|
||||||
const lastUpdateRef = useRef<number>(0);
|
const lastUpdateRef = useRef<number>(0);
|
||||||
const networkRef = useRef(network);
|
const networkRef = useRef(network);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Genome, InnovationTracker } from './genome';
|
import type { Genome } from './genome';
|
||||||
import { cloneGenome } from './genome';
|
import { cloneGenome } from './genome';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,8 +22,7 @@ const DISABLED_GENE_INHERITANCE_RATE = 0.75;
|
|||||||
*/
|
*/
|
||||||
export function crossover(
|
export function crossover(
|
||||||
parent1: Genome,
|
parent1: Genome,
|
||||||
parent2: Genome,
|
parent2: Genome
|
||||||
innovationTracker?: InnovationTracker
|
|
||||||
): Genome {
|
): Genome {
|
||||||
// Ensure parent1 is fitter (or equal)
|
// Ensure parent1 is fitter (or equal)
|
||||||
if (parent2.fitness > parent1.fitness) {
|
if (parent2.fitness > parent1.fitness) {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export function exportGenome(
|
|||||||
outputCount: config.outputCount,
|
outputCount: config.outputCount,
|
||||||
},
|
},
|
||||||
genome: {
|
genome: {
|
||||||
|
id: genome.id,
|
||||||
nodes: genome.nodes,
|
nodes: genome.nodes,
|
||||||
connections: genome.connections,
|
connections: genome.connections,
|
||||||
fitness: genome.fitness,
|
fitness: genome.fitness,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { Genome, InnovationTracker } from './genome';
|
import type { Genome, InnovationTracker } from './genome';
|
||||||
import {
|
import {
|
||||||
cloneGenome,
|
|
||||||
getNextNodeId,
|
getNextNodeId,
|
||||||
connectionExists,
|
connectionExists,
|
||||||
wouldCreateCycle,
|
wouldCreateCycle,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Genome, NodeGene, ConnectionGene, ActivationFunction } from './genome';
|
import type { Genome, ActivationFunction } from './genome';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feedforward neural network built from a NEAT genome.
|
* Feedforward neural network built from a NEAT genome.
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ function reproduceSpecies(
|
|||||||
|
|
||||||
// Crossover if we have two different parents, otherwise clone
|
// Crossover if we have two different parents, otherwise clone
|
||||||
if (parent2 && parent1 !== parent2 && Math.random() < config.crossoverRate) {
|
if (parent2 && parent1 !== parent2 && Math.random() < config.crossoverRate) {
|
||||||
child = crossover(parent1, parent2, innovationTracker);
|
child = crossover(parent1, parent2);
|
||||||
} else {
|
} else {
|
||||||
child = cloneGenome(parent1);
|
child = cloneGenome(parent1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { createSimulation, stepSimulation } from './simulation';
|
|||||||
import { createNetwork } from './network';
|
import { createNetwork } from './network';
|
||||||
import { generateObservation, observationToInputs } from './sensors';
|
import { generateObservation, observationToInputs } from './sensors';
|
||||||
import { createFitnessTracker, updateFitness } from './fitness';
|
import { createFitnessTracker, updateFitness } from './fitness';
|
||||||
import { SeededRandom } from './utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Self-Play Scheduler
|
* Self-Play Scheduler
|
||||||
@@ -26,12 +25,7 @@ export const DEFAULT_MATCH_CONFIG: MatchConfig = {
|
|||||||
maxTicks: 1200, // Increased to 40s (was 10s) to allow complex strategies
|
maxTicks: 1200, // Increased to 40s (was 10s) to allow complex strategies
|
||||||
};
|
};
|
||||||
|
|
||||||
interface MatchPairing {
|
|
||||||
genome1Index: number;
|
|
||||||
genome2Index: number;
|
|
||||||
spawnPairId: number;
|
|
||||||
swapSides: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate entire population using self-play
|
* Evaluate entire population using self-play
|
||||||
@@ -43,7 +37,6 @@ export function evaluatePopulation(
|
|||||||
): Population {
|
): Population {
|
||||||
// Reset fitness
|
// Reset fitness
|
||||||
const genomes = population.genomes;
|
const genomes = population.genomes;
|
||||||
const K = config.matchesPerGenome; // Total matches (e.g., 6)
|
|
||||||
|
|
||||||
// Initialize fitness trackers
|
// Initialize fitness trackers
|
||||||
const fitnessTrackers = genomes.map(g => {
|
const fitnessTrackers = genomes.map(g => {
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ export function compatibilityDistance(
|
|||||||
|
|
||||||
const max1 = Math.max(...Array.from(innovations1), 0);
|
const max1 = Math.max(...Array.from(innovations1), 0);
|
||||||
const max2 = Math.max(...Array.from(innovations2), 0);
|
const max2 = Math.max(...Array.from(innovations2), 0);
|
||||||
const maxInnovation = Math.max(max1, max2);
|
|
||||||
|
|
||||||
let matching = 0;
|
let matching = 0;
|
||||||
let disjoint = 0;
|
let disjoint = 0;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export function step(state: GameState, action: Action): GameState {
|
|||||||
...state,
|
...state,
|
||||||
snake: newSnake,
|
snake: newSnake,
|
||||||
food: spawnFood(state.gridSize, newSnake),
|
food: spawnFood(state.gridSize, newSnake),
|
||||||
direction: newDirection,
|
direction: newDirection as Direction,
|
||||||
score: state.score + 1,
|
score: state.score + 1,
|
||||||
steps: state.steps + 1,
|
steps: state.steps + 1,
|
||||||
stepsSinceLastFood: 0,
|
stepsSinceLastFood: 0,
|
||||||
@@ -105,7 +105,7 @@ export function step(state: GameState, action: Action): GameState {
|
|||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
snake: newSnake,
|
snake: newSnake,
|
||||||
direction: newDirection,
|
direction: newDirection as Direction,
|
||||||
steps: state.steps + 1,
|
steps: state.steps + 1,
|
||||||
stepsSinceLastFood: state.stepsSinceLastFood + 1,
|
stepsSinceLastFood: state.stepsSinceLastFood + 1,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,11 +3,16 @@
|
|||||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
"lib": [
|
||||||
|
"ES2022",
|
||||||
|
"DOM",
|
||||||
|
"DOM.Iterable"
|
||||||
|
],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"types": ["vite/client"],
|
"types": [
|
||||||
|
"vite/client"
|
||||||
|
],
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|
||||||
/* Bundler mode */
|
/* Bundler mode */
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
@@ -15,7 +20,6 @@
|
|||||||
"moduleDetection": "force",
|
"moduleDetection": "force",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
/* Linting */
|
/* Linting */
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
@@ -24,5 +28,14 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUncheckedSideEffectImports": true
|
"noUncheckedSideEffectImports": true
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": [
|
||||||
}
|
"src"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/*.test.ts",
|
||||||
|
"**/*.test.tsx",
|
||||||
|
"**/debug_*.ts",
|
||||||
|
"**/run_test_manual.ts",
|
||||||
|
"**/check_map_los.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user