-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
174 lines (148 loc) · 5.98 KB
/
main.py
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# Modules:
import pygame
from time import sleep
from random import choice
from math import ceil
from json import load
# Classes:
from cell import Cell
# Fetch the preferences in the json file:
with open("preferences.json", "r") as preferences_json:
preferences = load(preferences_json)["main"]
# Properties variables:
title = preferences["title"]
window_icon = pygame.image.load(preferences["icon_dir"])
window_size = width, height = tuple(
i for i in list(preferences["window_size"].values())
)
window_is_resizable = preferences["is_resizable"]
color4bg = tuple(
rgb for rgb in preferences["color4bg"].values()
)
initial_population = preferences["initial_population"]
overpopulation_point = preferences["overpopulation_point"]
# Aplication for properties variables:
if window_is_resizable:
window = pygame.display.set_mode(window_size, pygame.RESIZABLE)
else:
window = pygame.display.set_mode(window_size)
pygame.display.set_icon(window_icon)
pygame.display.set_caption(title)
if overpopulation_point:
def returnMaxPopulation(window_size:tuple, cell_radius):
'''
Given: the tuple of window size with two
values representing the width and height;
the cell object default radius.
Returns: the minimum n of cells to fill the
screen, then, the max n of cells to not be
overpopulated.
'''
width, height = window_size
cell_diameter = cell_radius*2
return(
(width*height) / (cell_radius**2)
)
max_population = returnMaxPopulation(
window_size, Cell().radius
)
deaths_percent_in_overpopulation_control = preferences[
"deaths_percent_in_overpopulation_control"
]
# cells variable is a list that contains all the Cell() objects
# it will be used to "plot" all the itens in the runtime bellow
cells = [Cell() for _ in range(initial_population)]
# Properties of runtime:
frame_rate = preferences["frame_rate"]
reproduce_in_n_frames = preferences["reproduce_in_n_frames"]
death_in_n_frames = preferences["death_in_n_frames"]
# the variables bellow is apercentage value
# and values must be like (0.27)
# the final value must be >= 1.00, otherwise
# the program breaks in the runtime
mortality_rate = preferences["mortality_rate"]
reproduction_rate = preferences["reproduction_rate"]
frame = 1
deaths = 0
reproductions = 0
mouse_was_pressed = False
print("\n || CLICK IN THE WINDOW TO START || \n")
# Runtime:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
window.fill(color4bg)
# once the mouse pressed, it will be true forever in runtime
# it is used to start the simulation when identif a click
if pygame.mouse.get_pressed()[0] == 1:
mouse_was_pressed = True
if mouse_was_pressed:
population = len(cells)
# Reprodution:
# create a new child cell for each Mother cells
# happen each `reproduce_in_n_frames` frames
if frame%reproduce_in_n_frames == 0:
# this loop runs for each existing cell if the reproduction rate == 1.00,
# otherwise, runs for `reproduction_rate` percent of cells
# the loop breaks case the ´reproduction_rate´ > 1.00
cells_to_be_mothers = ceil(population*reproduction_rate)
for c in range(cells_to_be_mothers):
# the existing cell is attributed to this variable
cellMother = cells[c]
# create a Cell() object, with default position
cellCopy = Cell()
# change that position to the mother position
cellCopy.pos = cellMother.pos
# put the new cell to the the population (cells list)
cells.append(cellCopy)
else: cells_to_be_mothers = 0
# Death:
# delete random cells of the population following
# the value assigmented in ´mortality_rate´ and
# happen each ´death_in_n_frames´ frames
if frame%death_in_n_frames == 0:
# the loop runs for ´mortalit_rate´ percet of
# population breaks case the ´mortality_rate´ > 1.00
cells_to_be_killed = ceil(population*mortality_rate)
for _ in range(cells_to_be_killed):
cell_to_be_killed = choice(cells)
cells.remove(cell_to_be_killed)
else: cells_to_be_killed = 0
# Overpopulation control:
# delete random cells of the population following
# the value of assigmented in `deaths_percent_in_
# overpopulation_control` and happen when the cells
# fill the scren as defined in returnMaxPopulation()
if overpopulation_point and population > max_population:
catastrofe_victims = ceil(
population * deaths_percent_in_overpopulation_control
)
for _ in range(catastrofe_victims):
victim = choice(cells)
cells.remove(victim)
else: catastrofe_victims = 0
# Plots
for cell in cells:
cell.draw(window)
# Logs:
sleep(frame_rate)
log_strings = [
f'FRAME: {frame}',
f'POPULATION: {population}',
f'REPRODUCTIONS: {reproductions}',
f'DEATHS: {deaths}',
f'FRAME_RATE = {frame_rate}',
f'REPRODUCE_EACH = {reproduce_in_n_frames} frames',
f'REPRODUTION_RATE = {reproduction_rate}',
f'MORTALITY_RATE = {mortality_rate}',
f'DEATH_EACH = {death_in_n_frames} frames'
]
for log_string in log_strings:
print(log_string)
print('\n=======================\n')
frame += 1
reproductions += cells_to_be_mothers
deaths += (cells_to_be_killed + catastrofe_victims)
pygame.display.update()