Skip to content

Instantly share code, notes, and snippets.

@webpapaya
Created September 21, 2019 11:36
Show Gist options
  • Save webpapaya/410e481ff3f050c6f062f1c1b1808867 to your computer and use it in GitHub Desktop.
Save webpapaya/410e481ff3f050c6f062f1c1b1808867 to your computer and use it in GitHub Desktop.
// @ts-ignore
import {assertThat, equalTo} from 'hamjest';
type CellState = 'alive' | 'dead'
type EventType = CellState | 'nextGeneration'
type Event<Type> = {
state: Type
}
type CellReceivingEvent = Event<EventType>
type CellDispatchEvent = Event<CellState>
class Cell {
callbackFunction?: (event: CellDispatchEvent) => void
receivedEvents: CellState[] = []
cellState: CellState
constructor(cellState: CellState = 'alive') {
this.cellState = cellState
}
dispatch(event: CellReceivingEvent) {
if (event.state === 'alive' || event.state === 'dead') {
this.receivedEvents.push(event.state)
} else if (event.state === 'nextGeneration' && this.callbackFunction) {
const aliveCellCount = this.receivedEvents.filter((cellState) => cellState === 'alive').length
if (this.cellState === 'dead' && aliveCellCount === 3) {
this.cellState = 'alive'
} else if (aliveCellCount === 2) {
this.cellState = 'alive'
} else {
this.cellState = 'dead'
}
this.callbackFunction({
state: this.cellState,
})
this.receivedEvents = []
}
}
register(fn: (event: CellDispatchEvent) => void) {
this.callbackFunction = fn
}
}
describe.only('Game of life', () => {
it("a living cell receiving 2 alive events from all neighbors, triggers alive event", (done) => {
const cell = new Cell()
cell.register((event) => {
assertThat(event.state, equalTo('alive'))
done()
})
Array.from({ length: 2 }).forEach(() => cell.dispatch({ state: 'alive' }))
Array.from({ length: 6 }).forEach(() => cell.dispatch({ state: 'dead' }))
cell.dispatch({ state: 'nextGeneration' })
})
it("a living cell receiving dead events from all neighbors only, triggers a dead event", (done) => {
const cell = new Cell()
cell.register((event) => {
assertThat(event.state, equalTo('dead'))
done()
})
Array.from({ length: 0 }).forEach(() => cell.dispatch({ state: 'alive' }))
Array.from({ length: 8 }).forEach(() => cell.dispatch({ state: 'dead' }))
cell.dispatch({ state: 'nextGeneration' })
})
it("a dead cell receiving 3 alive events from all neighbors, triggers a alive event", (done) => {
const cell = new Cell('dead')
cell.register((event) => {
assertThat(event.state, equalTo('alive'))
done()
})
Array.from({ length: 3 }).forEach(() => cell.dispatch({ state: 'alive' }))
Array.from({ length: 5 }).forEach(() => cell.dispatch({ state: 'dead' }))
cell.dispatch({ state: 'nextGeneration' })
})
it("a dead cell receiving 3 alive events from all neighbors, triggers a alive event", (done) => {
const cell = new Cell('dead')
let generation = 0
cell.register((event) => {
if (generation === 0) {
assertThat(event.state, equalTo('alive'))
} else {
assertThat(event.state, equalTo('dead'))
done()
}
generation++
})
Array.from({ length: 3 }).forEach(() => cell.dispatch({ state: 'alive' }))
Array.from({ length: 5 }).forEach(() => cell.dispatch({ state: 'dead' }))
cell.dispatch({ state: 'nextGeneration' })
Array.from({ length: 0 }).forEach(() => cell.dispatch({ state: 'alive' }))
Array.from({ length: 8 }).forEach(() => cell.dispatch({ state: 'dead' }))
cell.dispatch({ state: 'nextGeneration' })
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment