stub out stream for Cell
This commit is contained in:
parent
f46b72f6db
commit
530acc0aeb
6 changed files with 96 additions and 13 deletions
|
@ -11,17 +11,57 @@ class Cell {
|
|||
}
|
||||
setLiving() {
|
||||
if (this.living && this.liveNeighbors !== 2 && this.liveNeighbors !== 3) {
|
||||
this.liveNeighbors = 0;
|
||||
return (this.living = false);
|
||||
}
|
||||
if (this.liveNeighbors === 3) {
|
||||
this.liveNeighbors = 0;
|
||||
return (this.living = true);
|
||||
}
|
||||
this.liveNeighbors = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Stream {
|
||||
constructor(head, next) {
|
||||
this.head = head;
|
||||
this.tail = next;
|
||||
this.memo = false;
|
||||
}
|
||||
get next() {
|
||||
if (!this.memo) {
|
||||
this.tail = this.tail();
|
||||
this.memo = true;
|
||||
}
|
||||
return this.tail;
|
||||
}
|
||||
}
|
||||
|
||||
class CellStream extends Stream {
|
||||
constructor(head, next) {
|
||||
super(head, next);
|
||||
}
|
||||
get living() {
|
||||
return this.head.living;
|
||||
}
|
||||
set liveNeighbors(liveNeighbors) {
|
||||
this.head.liveNeighbors = liveNeighbors;
|
||||
}
|
||||
}
|
||||
|
||||
const cellStream = (living = false, liveNeighbors = 0) => {
|
||||
return new CellStream(new Cell(living, liveNeighbors), function () {
|
||||
this.head.setLiving();
|
||||
return this;
|
||||
});
|
||||
};
|
||||
|
||||
// as a stream -> cellStream = Stream(Cell, () => Cell(cellStream.isLiving()))
|
||||
// in this case GameField = { [x-y]: cellStream }
|
||||
// communicating with neighbors = filter for (Boolean(Cell.living)) -> Cell neighbors.addLivingNeighbor
|
||||
// controlling whether to call or not: filter for (Boolean(Cell.living) || Boolean(cell.liveNeighbors)) -> cellStream.next
|
||||
|
||||
module.exports = Cell;
|
||||
module.exports = {
|
||||
Cell,
|
||||
cellStream,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Cell from "./Cell";
|
||||
import { cellStream } from "./Cell";
|
||||
|
||||
export default class GameField {
|
||||
constructor({ fieldArray = [], fieldMap = {} }) {
|
||||
|
@ -7,12 +7,12 @@ export default class GameField {
|
|||
fieldArray.forEach((subArray, majorIndex) =>
|
||||
subArray.forEach((value, minorIndex) => {
|
||||
if (value > 0) {
|
||||
this.map[`${majorIndex}-${minorIndex}`] = new Cell(true);
|
||||
this.map[`${majorIndex}-${minorIndex}`] = cellStream(true, 0);
|
||||
}
|
||||
})
|
||||
);
|
||||
for (let key in fieldMap) {
|
||||
this.map[key] = new Cell(true);
|
||||
this.map[key] = cellStream(true, 0);
|
||||
}
|
||||
// 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)
|
||||
|
@ -20,3 +20,7 @@ export default class GameField {
|
|||
}
|
||||
|
||||
// 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({}));
|
||||
// const container = document.getElementById("game-field");
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import css from "./styles/reset.css";
|
||||
require("./components/Cell")(() => console.log("hello world!"))();
|
||||
import reset from "./styles/reset.css";
|
||||
import css from "./styles/style.css";
|
||||
// import Controls from './components/Controls';
|
||||
import GameField from "./components/GameField";
|
||||
(() => console.log("hello world!"))();
|
||||
|
||||
// controls
|
||||
// -- state=idle ?
|
||||
|
|
19
src/styles/style.css
Normal file
19
src/styles/style.css
Normal file
|
@ -0,0 +1,19 @@
|
|||
* {
|
||||
background: #333;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
main, aside {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import Cell from "../components/Cell";
|
||||
import { Cell, cellStream } from "../components/Cell";
|
||||
|
||||
describe("Cell functionality", () => {
|
||||
test("dispatch toggleLiving state should mark living cell dead", () => {
|
||||
|
@ -42,4 +42,27 @@ describe("Cell functionality", () => {
|
|||
expect(cell.living).toEqual(state);
|
||||
});
|
||||
});
|
||||
|
||||
const cellStreamNextCalls = [
|
||||
[2, false],
|
||||
[3, true],
|
||||
[0, false],
|
||||
[5, false],
|
||||
];
|
||||
|
||||
cellStreamNextCalls.forEach(([liveNeighbors, livingResult]) => {
|
||||
test(`cellStream advances cell state for ${liveNeighbors} live Neighbors (from dead cell)`, () => {
|
||||
const cell = cellStream(false, liveNeighbors).next;
|
||||
expect(cell.living).toEqual(livingResult);
|
||||
});
|
||||
});
|
||||
|
||||
[[2, true], ...cellStreamNextCalls.slice(1)].forEach(
|
||||
([liveNeighbors, livingResult]) => {
|
||||
test(`cellStream advances cell state for ${liveNeighbors} live Neighbors (from living cell)`, () => {
|
||||
const cell = cellStream(true, liveNeighbors).next;
|
||||
expect(cell.living).toEqual(livingResult);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
import GameField from "../components/GameField";
|
||||
|
||||
describe("Game Field", () => {
|
||||
test("smoke test", () => {
|
||||
expect(new GameField([])).toEqual({ map: {} });
|
||||
});
|
||||
});
|
||||
|
||||
describe("Game Field seeds living Cells with array", () => {
|
||||
const gameArraySeed = new GameField({
|
||||
fieldArray: [
|
||||
|
|
Loading…
Reference in a new issue