generated from michael/webpack-base
components -> site
This commit is contained in:
parent
834d4443dc
commit
7a986b3296
@ -1,4 +1,4 @@
|
||||
# AI in the Browser
|
||||
|
||||
## In this Repo:
|
||||
- [Snake Lab](src/components/snake) - [Live](https://beefslab.com/webapps/snake-lab)
|
||||
- [Snake Lab](src/site/snake) - [Live](https://beefslab.com/webapps/snake-lab)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import App from './components/app';
|
||||
import App from './site/app';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
|
@ -94,9 +94,7 @@ const SnakePage: FC = () => {
|
||||
<div>5,000 snakes per generation</div>
|
||||
<div>Press Spacebar for Slow Motion</div>
|
||||
<div>
|
||||
<a href="https://git.beefslab.com/michael/webai/src/branch/master/src/components/snake">
|
||||
View Repo
|
||||
</a>
|
||||
<a href="https://git.beefslab.com/michael/webai/src/branch/master/src/site/snake">View Repo</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
@ -1,93 +1,93 @@
|
||||
import { alignGenome, compatibilityDistance } from '../components/snake/brain-neat';
|
||||
import { alignGenome, compatibilityDistance } from '../site/snake/brain-neat';
|
||||
import { assert, addTest } from './tests';
|
||||
|
||||
function testAlignGenome() {
|
||||
// these genomes are taken from the NEAT paper's example
|
||||
const genomeA = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 4, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 0, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 3, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 5, enabled: true },
|
||||
// disjoint
|
||||
{ innovation: 8, src_id: 'A', dst_id: 'E', weight: 7, enabled: true },
|
||||
];
|
||||
const genomeB = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 8, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 1, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 2, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 3, enabled: false },
|
||||
// disjoint
|
||||
{ innovation: 6, src_id: 'E', dst_id: 'F', weight: 5, enabled: true },
|
||||
{ innovation: 7, src_id: 'F', dst_id: 'D', weight: 5, enabled: true },
|
||||
// excess
|
||||
{ innovation: 9, src_id: 'C', dst_id: 'E', weight: 5, enabled: true },
|
||||
{ innovation: 10, src_id: 'A', dst_id: 'F', weight: 5, enabled: true },
|
||||
];
|
||||
// these genomes are taken from the NEAT paper's example
|
||||
const genomeA = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 4, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 0, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 3, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 5, enabled: true },
|
||||
// disjoint
|
||||
{ innovation: 8, src_id: 'A', dst_id: 'E', weight: 7, enabled: true },
|
||||
];
|
||||
const genomeB = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 8, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 1, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 2, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 3, enabled: false },
|
||||
// disjoint
|
||||
{ innovation: 6, src_id: 'E', dst_id: 'F', weight: 5, enabled: true },
|
||||
{ innovation: 7, src_id: 'F', dst_id: 'D', weight: 5, enabled: true },
|
||||
// excess
|
||||
{ innovation: 9, src_id: 'C', dst_id: 'E', weight: 5, enabled: true },
|
||||
{ innovation: 10, src_id: 'A', dst_id: 'F', weight: 5, enabled: true },
|
||||
];
|
||||
|
||||
const alignment = alignGenome(genomeA, genomeB);
|
||||
const alignment = alignGenome(genomeA, genomeB);
|
||||
|
||||
assert(alignment.matching.length === 5);
|
||||
assert(alignment.disjoint.length === 3);
|
||||
assert(alignment.excess.length === 2);
|
||||
assert(alignment.matching.length === 5);
|
||||
assert(alignment.disjoint.length === 3);
|
||||
assert(alignment.excess.length === 2);
|
||||
|
||||
const matchingPair = alignment.matching[1]!;
|
||||
assert(matchingPair.a === genomeA[1]);
|
||||
assert(matchingPair.b === genomeB[1]);
|
||||
const matchingPair = alignment.matching[1]!;
|
||||
assert(matchingPair.a === genomeA[1]);
|
||||
assert(matchingPair.b === genomeB[1]);
|
||||
|
||||
const disjointPairA = alignment.disjoint[0]!;
|
||||
assert(disjointPairA.a === null);
|
||||
assert(disjointPairA.b === genomeB[5]);
|
||||
const disjointPairA = alignment.disjoint[0]!;
|
||||
assert(disjointPairA.a === null);
|
||||
assert(disjointPairA.b === genomeB[5]);
|
||||
|
||||
const disjointPairB = alignment.disjoint[2]!;
|
||||
assert(disjointPairB.a === genomeA[5]);
|
||||
assert(disjointPairB.b === null);
|
||||
const disjointPairB = alignment.disjoint[2]!;
|
||||
assert(disjointPairB.a === genomeA[5]);
|
||||
assert(disjointPairB.b === null);
|
||||
|
||||
const excessPair = alignment.excess[0]!;
|
||||
assert(excessPair.a === null);
|
||||
assert(excessPair.b === genomeB[7]);
|
||||
const excessPair = alignment.excess[0]!;
|
||||
assert(excessPair.a === null);
|
||||
assert(excessPair.b === genomeB[7]);
|
||||
}
|
||||
addTest(testAlignGenome);
|
||||
|
||||
function testCompatibilityDistance() {
|
||||
// these genomes are taken from the NEAT paper's example
|
||||
const genomeA = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 4, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 0, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 3, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 5, enabled: true },
|
||||
// disjoint
|
||||
{ innovation: 8, src_id: 'A', dst_id: 'E', weight: 7, enabled: true },
|
||||
];
|
||||
const genomeB = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 8, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 1, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 2, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 3, enabled: false },
|
||||
// disjoint
|
||||
{ innovation: 6, src_id: 'E', dst_id: 'F', weight: 5, enabled: true },
|
||||
{ innovation: 7, src_id: 'F', dst_id: 'D', weight: 5, enabled: true },
|
||||
// excess
|
||||
{ innovation: 9, src_id: 'C', dst_id: 'E', weight: 5, enabled: true },
|
||||
{ innovation: 10, src_id: 'A', dst_id: 'F', weight: 5, enabled: true },
|
||||
];
|
||||
// these genomes are taken from the NEAT paper's example
|
||||
const genomeA = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 4, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 0, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 3, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 5, enabled: true },
|
||||
// disjoint
|
||||
{ innovation: 8, src_id: 'A', dst_id: 'E', weight: 7, enabled: true },
|
||||
];
|
||||
const genomeB = [
|
||||
{ innovation: 1, src_id: 'A', dst_id: 'D', weight: 8, enabled: true },
|
||||
{ innovation: 2, src_id: 'B', dst_id: 'D', weight: 1, enabled: false },
|
||||
{ innovation: 3, src_id: 'C', dst_id: 'D', weight: 2, enabled: true },
|
||||
{ innovation: 4, src_id: 'B', dst_id: 'E', weight: 9, enabled: true },
|
||||
{ innovation: 5, src_id: 'E', dst_id: 'D', weight: 3, enabled: false },
|
||||
// disjoint
|
||||
{ innovation: 6, src_id: 'E', dst_id: 'F', weight: 5, enabled: true },
|
||||
{ innovation: 7, src_id: 'F', dst_id: 'D', weight: 5, enabled: true },
|
||||
// excess
|
||||
{ innovation: 9, src_id: 'C', dst_id: 'E', weight: 5, enabled: true },
|
||||
{ innovation: 10, src_id: 'A', dst_id: 'F', weight: 5, enabled: true },
|
||||
];
|
||||
|
||||
const alignment = alignGenome(genomeA, genomeB);
|
||||
const alignment = alignGenome(genomeA, genomeB);
|
||||
|
||||
const dist1 = compatibilityDistance(alignment, { c1: 1, c2: 0, c3: 0 });
|
||||
const dist2 = compatibilityDistance(alignment, { c1: 0, c2: 1, c3: 0 });
|
||||
const dist3 = compatibilityDistance(alignment, { c1: 0, c2: 0, c3: 1 });
|
||||
assert(dist1 === 2 / 10);
|
||||
assert(dist2 === 3 / 10);
|
||||
// |8 - 4| + |1 - 0| + |2 - 3| + |9 - 9| + |3 - 5|
|
||||
// 4 + 1 + 1 + 0 + 2
|
||||
// 8 / 5
|
||||
assert(dist3 === 8 / 5);
|
||||
const dist1 = compatibilityDistance(alignment, { c1: 1, c2: 0, c3: 0 });
|
||||
const dist2 = compatibilityDistance(alignment, { c1: 0, c2: 1, c3: 0 });
|
||||
const dist3 = compatibilityDistance(alignment, { c1: 0, c2: 0, c3: 1 });
|
||||
assert(dist1 === 2 / 10);
|
||||
assert(dist2 === 3 / 10);
|
||||
// |8 - 4| + |1 - 0| + |2 - 3| + |9 - 9| + |3 - 5|
|
||||
// 4 + 1 + 1 + 0 + 2
|
||||
// 8 / 5
|
||||
assert(dist3 === 8 / 5);
|
||||
|
||||
const distCombo = compatibilityDistance(alignment, { c1: 2, c2: 3, c3: 4 });
|
||||
assert(distCombo === 2 * (2 / 10) + 3 * (3 / 10) + 4 * (8 / 5));
|
||||
const distCombo = compatibilityDistance(alignment, { c1: 2, c2: 3, c3: 4 });
|
||||
assert(distCombo === 2 * (2 / 10) + 3 * (3 / 10) + 4 * (8 / 5));
|
||||
}
|
||||
addTest(testCompatibilityDistance);
|
||||
|
@ -1,31 +1,31 @@
|
||||
import IOSet from "../components/snake/ioset";
|
||||
import { addTest, assert, assertArrayEqual } from "./tests";
|
||||
import IOSet from '../site/snake/ioset';
|
||||
import { addTest, assert, assertArrayEqual } from './tests';
|
||||
|
||||
function testOrderMaintained() {
|
||||
const s = new IOSet();
|
||||
s.add('A');
|
||||
s.add('B');
|
||||
s.add('C');
|
||||
s.add('D');
|
||||
s.add('E');
|
||||
s.add('F');
|
||||
assert(s.size === 6);
|
||||
assertArrayEqual(Array.from(s), ['A', 'B', 'C', 'D', 'E', 'F']);
|
||||
const s = new IOSet();
|
||||
s.add('A');
|
||||
s.add('B');
|
||||
s.add('C');
|
||||
s.add('D');
|
||||
s.add('E');
|
||||
s.add('F');
|
||||
assert(s.size === 6);
|
||||
assertArrayEqual(Array.from(s), ['A', 'B', 'C', 'D', 'E', 'F']);
|
||||
}
|
||||
addTest(testOrderMaintained);
|
||||
|
||||
function testOrderMaintainedWithDelete() {
|
||||
const s = new IOSet();
|
||||
s.add('A');
|
||||
s.add('B');
|
||||
s.add('C');
|
||||
s.add('D');
|
||||
s.add('E');
|
||||
s.delete('D');
|
||||
s.add('F');
|
||||
s.delete('B');
|
||||
s.add('G');
|
||||
assert(s.size === 5);
|
||||
assertArrayEqual(Array.from(s), ['A', 'C', 'E', 'F', 'G']);
|
||||
const s = new IOSet();
|
||||
s.add('A');
|
||||
s.add('B');
|
||||
s.add('C');
|
||||
s.add('D');
|
||||
s.add('E');
|
||||
s.delete('D');
|
||||
s.add('F');
|
||||
s.delete('B');
|
||||
s.add('G');
|
||||
assert(s.size === 5);
|
||||
assertArrayEqual(Array.from(s), ['A', 'C', 'E', 'F', 'G']);
|
||||
}
|
||||
addTest(testOrderMaintainedWithDelete);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Network, Edge, Node, RawEdge } from '../components/snake/network';
|
||||
import { Network, Edge, Node, RawEdge } from '../site/snake/network';
|
||||
import { addTest, assert, assertArrayEqual } from './tests';
|
||||
|
||||
function testEdgesToNodesBasic() {
|
||||
@ -135,8 +135,8 @@ function testEdgesToNodesMaintainsData() {
|
||||
addTest(testEdgesToNodesMaintainsData);
|
||||
|
||||
function testCopyNodesPreventsModify() {
|
||||
type MyNode = Node<RawEdge & MyEdge>;
|
||||
type MyEdge = Edge<MyNode>;
|
||||
type MyNode = Node<RawEdge & MyEdge>;
|
||||
type MyEdge = Edge<MyNode>;
|
||||
const edges = [
|
||||
{ src_id: 'A', dst_id: 'B' },
|
||||
{ src_id: 'B', dst_id: 'C' },
|
||||
@ -145,15 +145,15 @@ function testCopyNodesPreventsModify() {
|
||||
|
||||
const nodesCopy = Network.copyNodes(nodes);
|
||||
|
||||
assert(nodes.size === nodesCopy.size);
|
||||
assert(nodes.size === nodesCopy.size);
|
||||
|
||||
// ensure that modifying a copied node does not modify the source node
|
||||
const nodeA = nodes.get('A')!;
|
||||
const nodeACopy = nodesCopy.get('A')!;
|
||||
// ensure that modifying a copied node does not modify the source node
|
||||
const nodeA = nodes.get('A')!;
|
||||
const nodeACopy = nodesCopy.get('A')!;
|
||||
|
||||
nodeACopy.dsts.pop()
|
||||
nodeACopy.dsts.pop();
|
||||
|
||||
assert(nodeA.dsts.size === 1);
|
||||
assert(nodeACopy.dsts.size === 0);
|
||||
assert(nodeA.dsts.size === 1);
|
||||
assert(nodeACopy.dsts.size === 0);
|
||||
}
|
||||
addTest(testCopyNodesPreventsModify);
|
||||
|
Loading…
Reference in New Issue
Block a user