diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 68ebe797..038fbe3e 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -32,6 +32,7 @@ * [Plot light level](/examples/plot-light-level) * [Plot analog pin](/examples/plot-analog-pin) * [Servo Calibrator](/examples/servo-calibrator) + * [Game of Life](/examples/gameofLife) ## Examples #examples diff --git a/docs/examples.md b/docs/examples.md index 69d7a319..eceb2beb 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -19,7 +19,13 @@ Here are some fun programs for your @boardname@! "name": "Rando", "description": "Randomly blinking LEDs", "url":"/examples/rando" -}] +}, +{ + "name": "Game of Life", + "description": "Simulation in LEDs. Use button A for next stage. Button B for reset.", + "url":"/examples/gameofLife" +} +] ``` ## Sensors diff --git a/docs/examples/gameofLife.md b/docs/examples/gameofLife.md new file mode 100644 index 00000000..70b1f63b --- /dev/null +++ b/docs/examples/gameofLife.md @@ -0,0 +1,124 @@ +# Game of Life simulation in LEDs + +```blocks +//https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life +let lifeChart: Image = null + +//Use button A for the next iteration of game of life +input.onButtonPressed(Button.A, () => { + gameOfLife(); + show(); +}) + +//Use button B for reseting to random initial seed state +input.onButtonPressed(Button.B, () => { + reset(); + show(); +}) + +lifeChart = images.createImage(` + . . . . . + . . . . . + . . . . . + . . . . . + . . . . . + `) + +//State holds the information about pixel is live or dead +//false means dead, true means live. +let state = [false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false, + false, false, false, false, false] + +//get & set on any array +function getState(arr: boolean[], x: number, y: number): boolean { + return arr[x * 5 + y]; +} +function setState(arr: boolean[], x: number, y: number, value: boolean): void { + arr[x * 5 + y] = value; +} + +//Generate random initial state. +function reset() { + for (let x = 0; x < 5; x++) { + for (let y = 0; y < 5; y++) { + setState(state, x, y, Math.randomBoolean()); + } + } +} + +//Show the lifeChart based on the state +function show() { + for (let x = 0; x < 5; x++) { + for (let y = 0; y < 5; y++) { + lifeChart.setPixel(x, y, getState(state, x, y)); + } + } + lifeChart.plotImage(0); +} + +//Core function +function gameOfLife() { + let result: boolean[] = []; + + for (let x = 0; x < 5; x++) { + for (let y = 0; y < 5; y++) { + let count = 0; + + //Count the live cells in the next row + if ((x + 1) < 5) { + if (getState(state, x + 1, y)) { + count++; + } + if ((y + 1 < 5) && getState(state, x + 1, y + 1)) { + count++; + } + if ((y - 1 >= 0) && getState(state, x + 1, y - 1)) { + count++; + } + } + + //Count the live cells in the previous row + if ((x - 1) >= 0) { + if (getState(state, x - 1, y)) { + count++; + } + if ((y + 1 < 5) && getState(state, x - 1, y + 1)) { + count++; + } + if ((y - 1 >= 0) && getState(state, x - 1, y - 1)) { + count++; + } + } + + //Count the live cells in the current row exlcuding the current position. + if ((y - 1 >= 0) && getState(state, x, y - 1)) { + count++; + } + if ((y + 1 < 5) && getState(state, x, y + 1)) { + count++; + } + + // Toggle live\dead cells based on the count. + // Any live cell with fewer than two live neighbours dies, as if caused by underpopulation. + // Any live cell with two or three live neighbours lives on to the next generation. + // Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction + // Any live cell with more than three live neighbours dies, as if by overpopulation. + switch (count) { + case 0: setState(result, x, y, false); break; + case 1: setState(result, x, y, false); break; + case 2: setState(result, x, y, getState(state, x, y)); break; + case 3: setState(result, x, y, true); break; + default: setState(result, x, y, false); break; + } + } + } + //Update the state + state = result; +} +//Initial reset & show +reset(); +show(); +``` \ No newline at end of file diff --git a/docs/projects/milk-carton-robot/code.md b/docs/projects/milk-carton-robot/code.md index 12786f97..839d9d54 100644 --- a/docs/projects/milk-carton-robot/code.md +++ b/docs/projects/milk-carton-robot/code.md @@ -68,6 +68,6 @@ closed = 175 ``` -### ~button /projects/milk-jar-robot/connect +### ~button /projects/milk-carton-robot/connect NEXT: Connect ### ~ \ No newline at end of file diff --git a/package.json b/package.json index e2ed657c..ac176a07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pxt-microbit", - "version": "0.9.65", + "version": "0.9.68", "description": "micro:bit target for PXT", "keywords": [ "JavaScript",