summaryrefslogtreecommitdiffstats
path: root/lab1/src/life.cpp
blob: cf5c6c9414adbf5fc9d4eac787feb47ddfb768de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Gustav Sörnäs - gusso230

#include "grid.h"
#include "lifeutil.h"

#include <iostream>
#include <fstream>
#include <string>

/*
 * Print a representation of the grid.
 * Alive cells show as 'X', dead show as '-'.
 */
void printGrid(Grid<bool> &grid) {
    for (int y = 0; y < grid.numRows(); y++) {
        for (int x = 0; x < grid.numCols(); x++) {
            if (grid.get(y, x)) {
                std::cout << 'X';
            } else {
                std::cout << '-';
            }
        }
        std::cout << std::endl;
    }
}

/*
 * Return 1 if (x, y) is in bounds and alive, otherwise 0.
 */
int checkPoint(Grid<bool> &grid, int y, int x) {
    return grid.inBounds(y, x) && grid.get(y, x) ? 1 : 0;
}

/*
 * Simulate the grid one time step and update it in-place.
 */
void simulate(Grid<bool> &grid) {
    Grid<bool> prevGrid(grid);
    for (int y = 0; y < grid.numRows(); y++) {
        for (int x = 0; x < grid.numCols(); x++) {
            int numNeighbours = checkPoint(prevGrid, y-1, x-1) +
                    checkPoint(prevGrid, y-1, x  ) +
                    checkPoint(prevGrid, y-1, x+1) +
                    checkPoint(prevGrid, y  , x-1) +
                    checkPoint(prevGrid, y  , x+1) +
                    checkPoint(prevGrid, y+1, x-1) +
                    checkPoint(prevGrid, y+1, x  ) +
                    checkPoint(prevGrid, y+1, x+1);
            if (numNeighbours < 2) {
                grid.set(y, x, false);
            } else if (numNeighbours == 2) {
                // Do nothing.
            } else if (numNeighbours == 3) {
                grid.set(y, x, true);
            } else {
                grid.set(y, x, false);
            }
        }
    }
}

int main() {
    Grid<bool> grid;

    std::string filepath;
    std::cout << "file: ";
    std::cin >> filepath;
    std::ifstream input;
    input.open(filepath);
    int h, w;
    input >> h >> w;
    grid.resize(h, w);

    for (int y = 0; y < grid.numRows(); y++) {
        std::string line;
        std::getline(input, line);
        for (int x = 0; x < grid.numCols(); x++) {
            grid.set(y, x, line[x] == 'X');
        }
    }
    input.close();

    char prompt;
    bool running = true;
    while (running && (std::cout << "[a]nimate, [t]ick, [q]uit: ") && std::cin >> prompt) {
        switch (prompt) {
        case 'a':
            while (true) {
                clearConsole();
                std::cout << std::endl;
                printGrid(grid);
                pause(100);
                simulate(grid);
            }
        case 't':
            simulate(grid);
            printGrid(grid);
            break;
        case 'q':
            running = false;
            break;
        }
    }
}