refactor fieldStream, handles oscillators
This commit is contained in:
parent
9c52a320eb
commit
32762e6ca8
3 changed files with 180 additions and 30 deletions
|
@ -40,6 +40,9 @@ class CellStream extends Stream {
|
|||
addLiveNeighbor() {
|
||||
this.head.addLiveNeighbor();
|
||||
}
|
||||
setLiving() {
|
||||
this.head.setLiving();
|
||||
}
|
||||
}
|
||||
|
||||
const cellStream = (living = false, liveNeighbors = 0) => {
|
||||
|
|
|
@ -12,9 +12,10 @@ class GameField {
|
|||
}
|
||||
})
|
||||
);
|
||||
for (let key in fieldMap) {
|
||||
this.map[key] = cellStream(true, 0);
|
||||
}
|
||||
Object.entries(fieldMap).forEach(
|
||||
([key, [live, neighbors]]) =>
|
||||
(this.map[key] = cellStream(live, neighbors))
|
||||
);
|
||||
// instead of implementing multiple GameFields, clear irrelevant keys and expand Game Field as needed
|
||||
// discrete Field expansion should only happen in View (to keep view fields centered)
|
||||
}
|
||||
|
@ -35,19 +36,43 @@ class FieldStream extends Stream {
|
|||
}
|
||||
}
|
||||
|
||||
const seedMap = (map, [key, seed]) => {
|
||||
map[key] = seed;
|
||||
return map;
|
||||
};
|
||||
const isLiving = ([key, cell]) => cell.living === true;
|
||||
const incrementLiveNeighbors = (field) => ([key]) =>
|
||||
getNeighbors(key).forEach((neighbor) => field.addLiveNeighbor(neighbor));
|
||||
const makeSeed = ([key, cell]) => [key, [cell.living, cell.liveNeighbors]];
|
||||
const makeSeedNextGen = ([key, cell]) => {
|
||||
cell.setLiving();
|
||||
return [key, [cell.living, 0]];
|
||||
};
|
||||
|
||||
const fieldStream = ({ fieldArray, fieldMap }) => {
|
||||
return new FieldStream(new GameField({ fieldArray, fieldMap }), function () {
|
||||
// calculate liveNeighbors for all cells on first next call
|
||||
for (const key in this.map) {
|
||||
getNeighbors(key).forEach((neighbor) => this.addLiveNeighbor(neighbor));
|
||||
Object.entries(this.map)
|
||||
.filter(isLiving)
|
||||
.forEach(incrementLiveNeighbors(this));
|
||||
// generate seed for next Stream with liveNeighbors
|
||||
const mapWithLiveNeighbors = Object.entries(this.map)
|
||||
.map(makeSeed)
|
||||
.reduce(seedMap, {});
|
||||
// return next stream
|
||||
return new FieldStream(
|
||||
new GameField({ fieldMap: mapWithLiveNeighbors }),
|
||||
function () {
|
||||
// determine living cells for next generation
|
||||
const nextGeneration = Object.entries(this.map)
|
||||
.map(makeSeedNextGen)
|
||||
.reduce(seedMap, {});
|
||||
// seed next Stream
|
||||
return fieldStream({ fieldMap: nextGeneration });
|
||||
}
|
||||
this.tail = function () {
|
||||
// call .next on all Cells on second next call
|
||||
};
|
||||
return this;
|
||||
);
|
||||
});
|
||||
};
|
||||
// as a stream -> fieldStream => Stream(GameField, () => Stream(fieldStream.computeNeighbors(), () => Stream(fieldStream.setLiving()))
|
||||
|
||||
// instantiate table (orientation of major and minor axis dependent on viewport)
|
||||
// const gameFields = new Array(1).fill(new GameField({}));
|
||||
|
|
|
@ -7,9 +7,9 @@ describe("Game Field seeds living Cells with array", () => {
|
|||
];
|
||||
|
||||
const fieldMap = {
|
||||
"0,0": true,
|
||||
"0,2": true,
|
||||
"1,1": true,
|
||||
"0,0": [true, 0],
|
||||
"0,2": [true, 0],
|
||||
"1,1": [true, 0],
|
||||
};
|
||||
const gameArraySeed = new GameField({ fieldArray });
|
||||
const gameMapSeed = new GameField({ fieldMap });
|
||||
|
@ -85,13 +85,13 @@ describe("fieldStream.next calculates liveNeighbors", () => {
|
|||
});
|
||||
|
||||
const fieldMap = {
|
||||
"0,1": true,
|
||||
"0,2": true,
|
||||
"1,0": true,
|
||||
"1,1": true,
|
||||
"1,3": true,
|
||||
"2,1": true,
|
||||
"2,2": true,
|
||||
"0,1": [true, 0],
|
||||
"0,2": [true, 0],
|
||||
"1,0": [true, 0],
|
||||
"1,1": [true, 0],
|
||||
"1,3": [true, 0],
|
||||
"2,1": [true, 0],
|
||||
"2,2": [true, 0],
|
||||
};
|
||||
const testStream2 = fieldStream({ fieldMap });
|
||||
[
|
||||
|
@ -128,27 +128,149 @@ describe("fieldStream.next calculates liveNeighbors", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe.skip("fieldStream.next tests still lifes", () => {
|
||||
describe("fieldStream.next tests still lifes", () => {
|
||||
const blockArray = [
|
||||
[1, 1],
|
||||
[1, 1],
|
||||
];
|
||||
|
||||
streamBlock = fieldStream({ fieldArray: blockArray });
|
||||
["0,0", "0,1", "1,0", "1,1"].forEach((key) => {});
|
||||
const streamBlock = fieldStream({ fieldArray: blockArray });
|
||||
[
|
||||
["-1,-1", false],
|
||||
["-1,0", false],
|
||||
["-1,1", false],
|
||||
["-1,2", false],
|
||||
["0,-1", false],
|
||||
["0,0", true],
|
||||
["0,1", true],
|
||||
["0,2", false],
|
||||
["1,-1", false],
|
||||
["1,0", true],
|
||||
["1,1", true],
|
||||
["1,2", false],
|
||||
["2,-1", false],
|
||||
["2,0", false],
|
||||
["2,1", false],
|
||||
["2,2", false],
|
||||
].forEach(([key, live]) => {
|
||||
test(`after one generation of Block, ${key} alive: ${live}`, () => {
|
||||
expect(streamBlock.next.next.map[key].living).toEqual(live);
|
||||
});
|
||||
});
|
||||
|
||||
const beehiveMap = {
|
||||
"0,1": true,
|
||||
"0,2": true,
|
||||
"1,0": true,
|
||||
"1,3": true,
|
||||
"2,1": true,
|
||||
"2,2": true,
|
||||
"0,1": [true, 0],
|
||||
"0,2": [true, 0],
|
||||
"1,0": [true, 0],
|
||||
"1,3": [true, 0],
|
||||
"2,1": [true, 0],
|
||||
"2,2": [true, 0],
|
||||
};
|
||||
const streamBeehive = fieldStream({ fieldMap: beehiveMap });
|
||||
[
|
||||
["-1,0", false],
|
||||
["-1,1", false],
|
||||
["-1,2", false],
|
||||
["-1,3", false],
|
||||
["0,-1", false],
|
||||
["0,0", false],
|
||||
["0,1", true],
|
||||
["0,2", true],
|
||||
["0,3", false],
|
||||
["0,4", false],
|
||||
["1,-1", false],
|
||||
["1,0", true],
|
||||
["1,1", false],
|
||||
["1,2", false],
|
||||
["1,3", true],
|
||||
["1,4", false],
|
||||
["2,-1", false],
|
||||
["2,0", false],
|
||||
["2,1", true],
|
||||
["2,2", true],
|
||||
["2,3", false],
|
||||
["2,4", false],
|
||||
["3,0", false],
|
||||
["3,1", false],
|
||||
["3,2", false],
|
||||
["3,3", false],
|
||||
].forEach(([key, live]) => {
|
||||
test(`after one generation of Beehive, ${key} alive: ${live}`, () => {
|
||||
expect(streamBeehive.next.next.map[key].living).toEqual(live);
|
||||
});
|
||||
});
|
||||
|
||||
const boatArray = [
|
||||
[1, 1, 0],
|
||||
[1, 0, 1],
|
||||
[0, 1, 0],
|
||||
];
|
||||
const streamBoat = fieldStream({ fieldArray: boatArray });
|
||||
[
|
||||
["-1,-1", false],
|
||||
["-1,0", false],
|
||||
["-1,1", false],
|
||||
["-1,2", false],
|
||||
["0,-1", false],
|
||||
["0,0", true],
|
||||
["0,1", true],
|
||||
["0,2", false],
|
||||
["1,-1", false],
|
||||
["1,0", true],
|
||||
["1,1", false],
|
||||
["1,2", true],
|
||||
["1,3", false],
|
||||
["2,-1", false],
|
||||
["2,0", false],
|
||||
["2,1", true],
|
||||
["2,2", false],
|
||||
["2,3", false],
|
||||
["3,0", false],
|
||||
["3,1", false],
|
||||
["3,2", false],
|
||||
].forEach(([key, live]) => {
|
||||
test(`after one generation of Beehive, ${key} alive: ${live}`, () => {
|
||||
expect(streamBoat.next.next.map[key].living).toEqual(live);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("fieldStream.next tests oscillators", () => {
|
||||
const blinkerArray = [
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
[0, 1, 0],
|
||||
];
|
||||
const streamBlinker = fieldStream({ fieldArray: blinkerArray });
|
||||
[
|
||||
["0,0", false],
|
||||
["0,1", false],
|
||||
["0,2", false],
|
||||
["1,0", true],
|
||||
["1,1", true],
|
||||
["1,2", true],
|
||||
["2,0", false],
|
||||
["2,1", false],
|
||||
["2,2", false],
|
||||
].forEach(([key, live]) => {
|
||||
test(`after one generation of blinker, ${key} alive: ${live}`, () => {
|
||||
expect(streamBlinker.next.next.map[key].living).toEqual(live);
|
||||
});
|
||||
});
|
||||
[
|
||||
["0,0", false],
|
||||
["0,1", true],
|
||||
["0,2", false],
|
||||
["1,0", false],
|
||||
["1,1", true],
|
||||
["1,2", false],
|
||||
["2,0", false],
|
||||
["2,1", true],
|
||||
["2,2", false],
|
||||
].forEach(([key, live]) => {
|
||||
test(`after two generations of blinker, ${key} alive: ${live}`, () => {
|
||||
console.log(streamBlinker.next.next.map);
|
||||
expect(streamBlinker.next.next.next.next.map[key].living).toEqual(live);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue