summaryrefslogtreecommitdiff
path: root/2d_automata.py
blob: 0ef55c2b18210db4defd153652f85399742a831f (plain)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/env python3

import pyray as pr
import random
import numpy as np
import time

screen_width = 1000
screen_height = 1000

sleep_time = .5

pr.init_window(screen_width, screen_height, "Game of Life")

cols = 20
rows = 20
grid = np.random.randint(2, size=(rows, cols))

# Single glider grid
# grid = np.zeros((100, 100))
# grid[0][1] = 1
# grid[1][2] = 1
# grid[2][0] = 1
# grid[2][1] = 1
# grid[2][2] = 1

# grid = np.array([[1, 0, 0, 1], [1, 0, 1, 1], [1, 0, 0, 1], [0, 0, 1, 1]])


col_space = int(screen_width / cols)
row_space = int(screen_height / rows)

def draw_game(grid):
    y = 0
    for i in grid:
        x = 0
        for j in i:
            if j == 1:
                pr.draw_rectangle(x, y, col_space, row_space, pr.DARKGRAY)
            else:
                pr.draw_rectangle(x, y, col_space, row_space, pr.LIGHTGRAY)
            x += col_space
        y += row_space

""" Rules of Conway's game of life:
1. Any live cell with fewer than two live neighbours dies, as if by
underpopulation.
2. Any live cell with two or three live neighbours lives on to the next
generation.
3. Any live cell with more than three live neighbours dies, as if by
overpopulation.
4. Any dead cell with exactly three live neighbours becomes a live cell,
as if by reproduction.
"""


def apply_conway(grid):
    new_grid = np.zeros((rows, cols))
    for j, row in enumerate(grid):
        for i, cell in enumerate(row):
            neighbours = 0
            # right neighbour
            # print(
            #     f"I'm {i+1} and {"alive" if cell == 1 else "dead"}, my right neighbour is {((i+1)%cols) +1} and {"alive" if grid[j][(i+1)%cols] == 1 else "dead"}"
            # )
            if grid[j][(i+1)%cols] == 1:
                neighbours += 1
            # left neighbour
            if grid[j][(i-1)%cols] == 1:
                neighbours += 1
            # bottom neighbour
            if grid[(j+1) % rows][i] == 1:
                neighbours += 1
            # top neighbour
            if grid[(j-1) % rows][i] == 1:
                neighbours += 1
            # print(f"Cell in row {j}, col {i} has {neighbours} neighbours")
            # top right neighbour
            if grid[(j-1) % rows][(i+1)%cols] == 1:
                neighbours += 1
            # top left neighbour
            if grid[(j-1) % rows][(i-1)%cols] == 1:
                neighbours += 1
            # bottom right neighbour
            if grid[(j+1) % rows][(i+1)%cols] == 1:
                neighbours += 1
            # bottom left neighbour
            if grid[(j+1) % rows][(i-1)%cols] == 1:
                neighbours += 1

            # Rule 1
            if cell == 1 and neighbours < 2:
                new_grid[j, i] = 0
            # Rule 2
            if cell == 1 and neighbours == 2:
                new_grid[j, i] = 1
            if cell == 1 and neighbours == 3:
                new_grid[j, i] = 1
            # Rule 3
            if cell == 1 and neighbours > 3:
                new_grid[j, i] = 0
            # Rule 4
            if cell == 0 and neighbours == 3:
                new_grid[j, i] = 1

            # TODO: consider alternative compute to avoid all the ifs: add all
            # nine fields, if 3 life, if 4 stay current state, else dead

    return new_grid

first_iter = True
while not pr.window_should_close():
    if not first_iter:
        grid = apply_conway(grid)

    pr.begin_drawing()
    pr.clear_background(pr.WHITE)
    # pr.draw_text("Hello World", 190, 200, 20, pr.VIOLET)

    draw_game(grid)
    pr.end_drawing()
    time.sleep(sleep_time)
    first_iter = False
pr.close_window()