diff --git a/src/apps/LunarLander/GeneticAlgo.ts b/src/apps/LunarLander/GeneticAlgo.ts index 7aff359..3db750e 100644 --- a/src/apps/LunarLander/GeneticAlgo.ts +++ b/src/apps/LunarLander/GeneticAlgo.ts @@ -8,7 +8,6 @@ export interface Genome { export class GeneticAlgo { private population: Genome[] = []; - private layerSizes: number[]; private popSize: number; private mutationRate: number; private mutationScale: number; @@ -25,7 +24,6 @@ export class GeneticAlgo { mutationScale = 0.5 // Gaussian/random perturbation amount (increased) ) { this.popSize = popSize; - this.layerSizes = layerSizes; this.mutationRate = mutationRate; this.mutationScale = mutationScale; diff --git a/src/apps/LunarLander/LanderScene.ts b/src/apps/LunarLander/LanderScene.ts index dd29be4..7fb17ff 100644 --- a/src/apps/LunarLander/LanderScene.ts +++ b/src/apps/LunarLander/LanderScene.ts @@ -17,7 +17,7 @@ export class LanderScene extends Phaser.Scene { preload() { // 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.fillCircle(4, 4, 4); // 8x8 circle gfx.generateTexture('flame', 8, 8); diff --git a/src/apps/LunarLander/LanderSimulation.ts b/src/apps/LunarLander/LanderSimulation.ts index c97c021..2a6ef19 100644 --- a/src/apps/LunarLander/LanderSimulation.ts +++ b/src/apps/LunarLander/LanderSimulation.ts @@ -101,7 +101,7 @@ export class LanderSimulation { } } - private crash(reason: string) { + private crash(_reason: string) { this.result = 'CRASHED'; this.isGameOver = true; } diff --git a/src/apps/RogueGen/RogueGenApp.tsx b/src/apps/RogueGen/RogueGenApp.tsx index a840936..767a270 100644 --- a/src/apps/RogueGen/RogueGenApp.tsx +++ b/src/apps/RogueGen/RogueGenApp.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState, useCallback } from 'react'; -import type { Genotype, MapData } from './types'; +import type { Genotype } from './types'; import { generateMap } from './generator'; import { createRandomGenome, evaluatePopulation, evolve, type Individual, POPULATION_SIZE } from './evolution'; diff --git a/src/apps/RogueGen/generator.ts b/src/apps/RogueGen/generator.ts index ba53e20..0e9ddfc 100644 --- a/src/apps/RogueGen/generator.ts +++ b/src/apps/RogueGen/generator.ts @@ -277,10 +277,8 @@ function bfsFlood(grid: Uint8Array, width: number, height: number, startX: numbe const d = dists[packed]; // Inline neighbors - const nOffsets = [-width, width, -1, 1]; // N, S, W, E - + 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), // 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. diff --git a/src/apps/SelfDrivingCar/CarScene.ts b/src/apps/SelfDrivingCar/CarScene.ts index 3e525a9..1e652df 100644 --- a/src/apps/SelfDrivingCar/CarScene.ts +++ b/src/apps/SelfDrivingCar/CarScene.ts @@ -2,7 +2,7 @@ import Phaser from 'phaser'; import { CarSimulation } from './CarSimulation'; import { Car } from './Car'; 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'; // NEAT Imports REMOVED diff --git a/src/apps/SelfDrivingCar/ConfigPanel.tsx b/src/apps/SelfDrivingCar/ConfigPanel.tsx index 59572c8..8e391a8 100644 --- a/src/apps/SelfDrivingCar/ConfigPanel.tsx +++ b/src/apps/SelfDrivingCar/ConfigPanel.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; import type { CarConfig, SimulationConfig } from './types'; import type { GAConfig } from './SimpleGA'; diff --git a/src/apps/SelfDrivingCar/SimpleGA.ts b/src/apps/SelfDrivingCar/SimpleGA.ts index 7bc42b5..ed00434 100644 --- a/src/apps/SelfDrivingCar/SimpleGA.ts +++ b/src/apps/SelfDrivingCar/SimpleGA.ts @@ -31,8 +31,6 @@ export class SimpleGA { // Duplicating logic is safer to avoid instantiation overhead if large. // Logic from DenseNetwork: sum((full_in + 1) * out) // 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++) { const dn = new DenseNetwork(this.layerSizes); @@ -88,8 +86,6 @@ export class SimpleGA { let bestFitness = -Infinity; 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 realIdx = indices[r]; if (fitnesses[realIdx] > bestFitness) { diff --git a/src/apps/SnakeAI/SnakeAI.tsx b/src/apps/SnakeAI/SnakeAI.tsx index 8e5dba7..f9b35e4 100644 --- a/src/apps/SnakeAI/SnakeAI.tsx +++ b/src/apps/SnakeAI/SnakeAI.tsx @@ -38,7 +38,7 @@ export default function SnakeAI() { populationRef.current = population; }, [population]); - const animationFrameRef = useRef(); + const animationFrameRef = useRef(0); const lastUpdateRef = useRef(0); // Compute derived values for display diff --git a/src/apps/SnakeAI/SnakeCanvas.tsx b/src/apps/SnakeAI/SnakeCanvas.tsx index f572ca7..e93ec7b 100644 --- a/src/apps/SnakeAI/SnakeCanvas.tsx +++ b/src/apps/SnakeAI/SnakeCanvas.tsx @@ -23,7 +23,7 @@ const CANVAS_PADDING = 10; export default function SnakeCanvas({ network, gridSize, showGrid = true, size = 'normal', showStats = false, playbackSpeed = 15 }: SnakeCanvasProps) { const canvasRef = useRef(null); const [currentGame, setCurrentGame] = useState(null); - const animationFrameRef = useRef(); + const animationFrameRef = useRef(0); const lastUpdateRef = useRef(0); const networkRef = useRef(network); diff --git a/src/lib/neatArena/crossover.ts b/src/lib/neatArena/crossover.ts index 0906bba..0ca8059 100644 --- a/src/lib/neatArena/crossover.ts +++ b/src/lib/neatArena/crossover.ts @@ -1,4 +1,4 @@ -import type { Genome, InnovationTracker } from './genome'; +import type { Genome } from './genome'; import { cloneGenome } from './genome'; /** @@ -22,8 +22,7 @@ const DISABLED_GENE_INHERITANCE_RATE = 0.75; */ export function crossover( parent1: Genome, - parent2: Genome, - innovationTracker?: InnovationTracker + parent2: Genome ): Genome { // Ensure parent1 is fitter (or equal) if (parent2.fitness > parent1.fitness) { diff --git a/src/lib/neatArena/exportImport.ts b/src/lib/neatArena/exportImport.ts index a1d6d26..dc85fad 100644 --- a/src/lib/neatArena/exportImport.ts +++ b/src/lib/neatArena/exportImport.ts @@ -41,6 +41,7 @@ export function exportGenome( outputCount: config.outputCount, }, genome: { + id: genome.id, nodes: genome.nodes, connections: genome.connections, fitness: genome.fitness, diff --git a/src/lib/neatArena/mutations.ts b/src/lib/neatArena/mutations.ts index 525a184..b42269f 100644 --- a/src/lib/neatArena/mutations.ts +++ b/src/lib/neatArena/mutations.ts @@ -1,6 +1,5 @@ import type { Genome, InnovationTracker } from './genome'; import { - cloneGenome, getNextNodeId, connectionExists, wouldCreateCycle, diff --git a/src/lib/neatArena/network.ts b/src/lib/neatArena/network.ts index b7a9f9d..cc60f1d 100644 --- a/src/lib/neatArena/network.ts +++ b/src/lib/neatArena/network.ts @@ -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. diff --git a/src/lib/neatArena/reproduction.ts b/src/lib/neatArena/reproduction.ts index 1b96459..72f48e2 100644 --- a/src/lib/neatArena/reproduction.ts +++ b/src/lib/neatArena/reproduction.ts @@ -124,7 +124,7 @@ function reproduceSpecies( // Crossover if we have two different parents, otherwise clone if (parent2 && parent1 !== parent2 && Math.random() < config.crossoverRate) { - child = crossover(parent1, parent2, innovationTracker); + child = crossover(parent1, parent2); } else { child = cloneGenome(parent1); } diff --git a/src/lib/neatArena/selfPlay.ts b/src/lib/neatArena/selfPlay.ts index 0858e72..9ba19b4 100644 --- a/src/lib/neatArena/selfPlay.ts +++ b/src/lib/neatArena/selfPlay.ts @@ -5,7 +5,6 @@ import { createSimulation, stepSimulation } from './simulation'; import { createNetwork } from './network'; import { generateObservation, observationToInputs } from './sensors'; import { createFitnessTracker, updateFitness } from './fitness'; -import { SeededRandom } from './utils'; /** * Self-Play Scheduler @@ -26,12 +25,7 @@ export const DEFAULT_MATCH_CONFIG: MatchConfig = { 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 @@ -43,7 +37,6 @@ export function evaluatePopulation( ): Population { // Reset fitness const genomes = population.genomes; - const K = config.matchesPerGenome; // Total matches (e.g., 6) // Initialize fitness trackers const fitnessTrackers = genomes.map(g => { diff --git a/src/lib/neatArena/speciation.ts b/src/lib/neatArena/speciation.ts index 5b42be5..1977db7 100644 --- a/src/lib/neatArena/speciation.ts +++ b/src/lib/neatArena/speciation.ts @@ -44,7 +44,6 @@ export function compatibilityDistance( const max1 = Math.max(...Array.from(innovations1), 0); const max2 = Math.max(...Array.from(innovations2), 0); - const maxInnovation = Math.max(max1, max2); let matching = 0; let disjoint = 0; diff --git a/src/lib/snakeAI/game.ts b/src/lib/snakeAI/game.ts index a706ab1..bc50b9f 100644 --- a/src/lib/snakeAI/game.ts +++ b/src/lib/snakeAI/game.ts @@ -94,7 +94,7 @@ export function step(state: GameState, action: Action): GameState { ...state, snake: newSnake, food: spawnFood(state.gridSize, newSnake), - direction: newDirection, + direction: newDirection as Direction, score: state.score + 1, steps: state.steps + 1, stepsSinceLastFood: 0, @@ -105,7 +105,7 @@ export function step(state: GameState, action: Action): GameState { return { ...state, snake: newSnake, - direction: newDirection, + direction: newDirection as Direction, steps: state.steps + 1, stepsSinceLastFood: state.stepsSinceLastFood + 1, }; diff --git a/tsconfig.app.json b/tsconfig.app.json index a9b5a59..eae74fb 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,11 +3,16 @@ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2022", "useDefineForClassFields": true, - "lib": ["ES2022", "DOM", "DOM.Iterable"], + "lib": [ + "ES2022", + "DOM", + "DOM.Iterable" + ], "module": "ESNext", - "types": ["vite/client"], + "types": [ + "vite/client" + ], "skipLibCheck": true, - /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, @@ -15,7 +20,6 @@ "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", - /* Linting */ "strict": true, "noUnusedLocals": true, @@ -24,5 +28,14 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["src"] -} + "include": [ + "src" + ], + "exclude": [ + "**/*.test.ts", + "**/*.test.tsx", + "**/debug_*.ts", + "**/run_test_manual.ts", + "**/check_map_los.ts" + ] +} \ No newline at end of file