Created
August 13, 2021 20:40
-
-
Save devill/4db1adeed909e1917998006ce8e3e03c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { GPU } from 'gpu.js'; | |
| import expect from 'expect.js'; | |
| const gpu = new GPU(); | |
| const gameOfLifeFor = (n,m) => { | |
| const evolve = gpu.createKernel(function(board, n, m) { | |
| function countOfNeighbours(board, x, y, n, m) { | |
| let count = 0; | |
| for(let dy = -1; dy <= 1; dy ++) { | |
| for (let dx = -1; dx <= 1; dx++) { | |
| if(x + dx >= 0 && x + dx < n && y + dy >= 0 && y + dy < m ) { | |
| count += board[y + dy][x + dx]; | |
| } | |
| } | |
| } | |
| return count - board[y][x]; | |
| } | |
| const x = this.thread.x; | |
| const y = this.thread.y; | |
| let count = countOfNeighbours(board, x, y, n, m); | |
| return ((count === 2 && board[y][x] === 1) || count === 3) ? 1 : 0; | |
| }).setOutput([n,m]) | |
| return board => { | |
| return evolve(board, n, m).map(l => Array.from(l)); | |
| }; | |
| } | |
| const ALIVE = 1; | |
| const DEAD = 0; | |
| const _ = DEAD; | |
| const X = ALIVE; | |
| describe("Game of life", () => { | |
| describe("3x3 world", () => { | |
| const evolve = gameOfLifeFor(3,3); | |
| specify("that empty board evolves to empty", () => { | |
| const board = [ | |
| [_, _, _], | |
| [_, _, _], | |
| [_, _, _], | |
| ] | |
| let result = evolve(board); | |
| expect(result).to.eql([ | |
| [_, _, _], | |
| [_, _, _], | |
| [_, _, _], | |
| ]); | |
| }); | |
| specify("that a board with 2 by 2 block is stable", () => { | |
| const board = [ | |
| [_, X, X], | |
| [_, X, X], | |
| [_, _, _], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][1]).to.be(ALIVE); | |
| }); | |
| specify("that single cell world evolves to empty board", () => { | |
| const board = [ | |
| [_, _, _], | |
| [_, X, _], | |
| [_, _, _], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][1]).to.be(DEAD); | |
| }); | |
| specify("that middle cell from a diagonal stays alive", () => { | |
| const board = [ | |
| [X, _, _], | |
| [_, X, _], | |
| [_, _, X], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][1]).to.be(ALIVE); | |
| }); | |
| specify("that cell with 3 neighbours spawns", () => { | |
| const board = [ | |
| [_, X, _], | |
| [X, _, _], | |
| [_, _, X], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][1]).to.be(ALIVE); | |
| }); | |
| specify("that cell with two neighbours does not spawn", () => { | |
| const board = [ | |
| [X, _, _], | |
| [_, _, _], | |
| [_, _, X], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][1]).to.be(DEAD); | |
| }); | |
| specify("that cell with four neighbours dies", () => { | |
| const board = [ | |
| [X, _, X], | |
| [_, X, _], | |
| [X, _, X], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][1]).to.be(DEAD); | |
| }); | |
| specify("that cell with four neighbours dies", () => { | |
| const board = [ | |
| [X, X, _], | |
| [X, X, _], | |
| [X, X, _], | |
| ] | |
| let result = evolve(board); | |
| expect(result[1][2]).to.be(ALIVE); | |
| }); | |
| }); | |
| specify("that glide works in large world", () => { | |
| const evolve = gameOfLifeFor(7,5); | |
| const board = [ | |
| [_,_,_,_,_,_,_], | |
| [_,_,X,_,_,_,_], | |
| [_,_,_,X,X,_,_], | |
| [_,_,X,X,_,_,_], | |
| [_,_,_,_,_,_,_], | |
| ]; | |
| let result = evolve(board); | |
| let expectedResult = [ | |
| [_,_,_,_,_,_,_], | |
| [_,_,_,X,_,_,_], | |
| [_,_,_,_,X,_,_], | |
| [_,_,X,X,X,_,_], | |
| [_,_,_,_,_,_,_], | |
| ]; | |
| expect(result).to.eql(expectedResult); | |
| }); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment