Behavior Driven Development Projects

Game of life

GitHub repo

GOF.gif

Rules of life

Based on Wikipedia: Conway's Game of Life: Rules

The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, alive or dead. Every cell interacts with its eight neighbors, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur:

1. Under-Population

2. Next Generation

3. Overcrowding

4. Reproduction

The first generation is created randomly or with a predefined pattern.

By applying the above rules simultaneously to every cell in the seed—births and deaths occur simultaneously, and the discrete moment at which this happens is sometimes called a tick. The rules continue to be applied repeatedly to create further generations.

How to run

You can run few commands to start/build this app :

Classes

The two main classes in this App is probably Board and Cell

Cell

Board class contain a 2D Cell array. Each Cell contains two properties :

The main method compute the neighbors coordinates from it own coordinates :

function getNeighborsCoordinates(arrayDimensions: ArrayDimensions): Coordinate[] {
    const coordinates: Coordinate[] = [];
    if (this.position.x > 0 && this.position.y > 0) {
        coordinates.push({
            x: this.position.x - 1,
            y: this.position.y - 1,
        });
    }
    if (
        this.position.y < arrayDimensions.height - 1 &&
        this.position.x < arrayDimensions.width - 1
    ) {
        coordinates.push({
            x: this.position.x + 1,
            y: this.position.y + 1,
        });
    }
    if (this.position.x > 0) {
        coordinates.push({
            x: this.position.x - 1,
            y: this.position.y,
        });
        if (this.position.y < arrayDimensions.height - 1) {
            coordinates.push({
                x: this.position.x - 1,
                y: this.position.y + 1,
            });
        }
    }
    if (this.position.y > 0) {
        coordinates.push({
            x: this.position.x,
            y: this.position.y - 1,
        });
        if (this.position.x < arrayDimensions.width - 1) {
            coordinates.push({
                x: this.position.x + 1,
                y: this.position.y - 1,
            });
        }
    }
    if (this.position.y < arrayDimensions.height - 1) {
        coordinates.push({
            x: this.position.x,
            y: this.position.y + 1,
        });
    }
    if (this.position.x < arrayDimensions.width - 1) {
        coordinates.push({
            x: this.position.x + 1,
            y: this.position.y,
        });
    }
    return coordinates;
}

Board

This class contains one of the most important function : nextStep() which compute the next state of our Board life :

function nextStep() {
    const nextBoard: CellArray = this.cells.map((line) => line.slice());

    for (let y = 0; y < this.dimensions.height; y++) {
        for (let x = 0; x < this.dimensions.width; x++) {
            let aliveNeighbours = 0;
            const neighbours = this.cells[y][x]
                .getNeighboursCoordinates(this.dimensions);

            neighbours.forEach((neighbour) => {
                if (this.isAlive(neighbour.x, neighbour.y)) {
                    aliveNeighbours++;
                }
            });
            if ((this.isAlive(x, y) && aliveNeighbours === 2)
                || aliveNeighbours === 3) {
                nextBoard[y][x] = new Cell({y, x}, true);
            } else {
                nextBoard[y][x] = new Cell({y, x}, false);
            }
        }
    }
    this.cells = nextBoard;
}

Tests & Coverage

When we run the cucumber tests, it generates two reports

Coverage Report

The first one is a code coverage on cucumber's tests. This file is viewable on coverage/index.html and look like this :

image-20220208192354230.png

image-20220208192400658.png

Cucumber report

The other report is the result of the ran cucumber's tests :

image-20220208192621443.png

image-20220208192633476.png