aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar piotrruss <mail@pruss.it> 2022-01-30 20:22:22 +0000
committerGravatar piotrruss <mail@pruss.it> 2022-01-30 20:22:22 +0000
commitb5ab9fbb3afcda1fc3cdd4d05fd1a2d2bf65af71 (patch)
treee6ef358219a2011eae5ae4a12d695be1185e2f8a
downloadgame_of_life-b5ab9fbb3afcda1fc3cdd4d05fd1a2d2bf65af71.tar.gz
game_of_life-b5ab9fbb3afcda1fc3cdd4d05fd1a2d2bf65af71.tar.bz2
game_of_life-b5ab9fbb3afcda1fc3cdd4d05fd1a2d2bf65af71.zip
init commit
-rw-r--r--README.md6
-rw-r--r--game-of-life.js90
-rw-r--r--screenshot.jpgbin0 -> 272439 bytes
3 files changed, 96 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c1e17ac
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# Game of life
+Small script written in NodeJs displaying Conway's game of life in your console.
+
+To quit the script press Ctrl+C.
+
+![Game of life](screenshot.jpg)
diff --git a/game-of-life.js b/game-of-life.js
new file mode 100644
index 0000000..7cec741
--- /dev/null
+++ b/game-of-life.js
@@ -0,0 +1,90 @@
+const pr = t => process.stdout.write(t)
+
+class GameOfLife {
+ constructor(){
+ this.width = process.stdout.columns - 2
+ this.height = process.stdout.rows - 4
+ this.cells = Array.from({length: this.width * this.height}, () => Math.round(Math.random()))
+ }
+
+ printBoard() {
+ console.clear()
+ pr('╔' + '═'.repeat(this.width) + '╗')
+ pr('║' + ' '.repeat(Math.floor((this.width - 12) / 2)) + 'GAME OF LIFE' + ' '.repeat(Math.ceil((this.width - 12) / 2)) + '║')
+ pr('╠' + '═'.repeat(this.width) + '╣')
+ for (let l=0; l<this.height; l++) {
+ pr('║' + this.cells.slice(l*this.width, (l+1)*this.width).map((c, i) => (
+ c === 1
+ ? this.prevCells && this.prevCells[l*this.width+i] === 1
+ ? '#'
+ : '\x1b[32m#\x1b[0m'
+ : this.prevCells && this.prevCells[l*this.width+i] === 1
+ ? '\x1b[31m#\x1b[0m'
+ : ' '
+ )).join('') + '║')
+ }
+ pr('╚' + '═'.repeat(this.width) + '╝')
+ }
+
+ findCell(x, y) {
+ return this.cells[x + y * this.width]
+ }
+
+ computeCellNextState(x, y){
+ const st = (x, y) => {
+ if (x >= 0 && x < this.width && y >= 0 && y < this.height) {
+ return this.findCell(x, y)
+ } else {
+ return 0;
+ }
+ }
+
+ const total = st(x-1, y-1) + st(x, y-1) + st(x+1, y-1) + st(x-1, y) + st(x+1, y) + st(x-1, y+1) + st(x, y+1) + st(x+1, y+1)
+
+ if (st(x, y) === 1) {
+ if (total < 2) {
+ return 0
+ } else if (total >= 2 && total <= 3) {
+ return 1
+ } else {
+ return 0
+ }
+ } else if (total === 3) {
+ return 1
+ } else {
+ return 0
+ }
+ }
+
+ printNextGeneration(){
+ const nextState = []
+
+ for (let y = 0; y < this.height; y++) {
+ for (let x = 0; x < this.width; x++) {
+ nextState.push(this.computeCellNextState(x, y))
+ }
+ }
+
+ this.prevCells = this.cells
+ this.cells = nextState
+ this.printBoard()
+ }
+}
+
+let game = new GameOfLife()
+
+pr('\u001B[?25l')
+let animation = setInterval(() => game.printNextGeneration(), 250)
+
+process.on('SIGINT', function() {
+ clearInterval(animation)
+ pr('\u001B[?25h')
+ console.clear()
+ process.exit()
+});
+
+process.stdout.on('resize', () => {
+ clearInterval(animation)
+ game = new GameOfLife()
+ animation = setInterval(() => game.printNextGeneration(), 250)
+})
diff --git a/screenshot.jpg b/screenshot.jpg
new file mode 100644
index 0000000..49a59d9
--- /dev/null
+++ b/screenshot.jpg
Binary files differ