Skip to content

Instantly share code, notes, and snippets.

@vgalin
Created July 16, 2021 12:56
Show Gist options
  • Save vgalin/81f4180dca48c701823ce5c808824f47 to your computer and use it in GitHub Desktop.
Save vgalin/81f4180dca48c701823ce5c808824f47 to your computer and use it in GitHub Desktop.
squarity-cellular-automata-poc
https://i.imgur.com/I6zEQh5.png
--------
{
"game_area": {
"nb_tile_width": 32,
"nb_tile_height": 32
},
"tile_size": 16,
"img_coords": {
"b": [0, 0],
"g": [16, 0],
"^": [32, 0]
}
}
--------
import random
# image = https://i.imgur.com/I6zEQh5.png
LEVEL = []
AVAILABLE_TILES = 'bg^'
CHANCE_TO_START_ALIVE = 0.4
BIRTH_LIMIT = 4
DEATH_LIMIT= 3
NO_OF_STEPS = 2
def count_alive_neighbours(map, x, y, alive):
count = 0
width = len(map[0])
height = len(map)
i=-1
while i < 2:
j=-1
while j < 2:
neighbour_x = x + i
neighbour_y = y + j
if i == 0 and j == 0:
pass
elif (neighbour_x < 0 or neighbour_y < 0 or
neighbour_x >= height or
neighbour_y >= width):
count += 1
elif (map[neighbour_x][neighbour_y] == alive):
count += 1
j += 1
i += 1
return count
def count_alive_neighbours_OLD(map, x, y, alive):
count = 0
for i in range(x-1, x+2):
for j in range(y-1, y+2):
if i == x and j == y:
continue
if i >= 0 and i < len(map) and j >= 0 and j < len(map[0]):
if map[i][j] == alive:
count += 1
return count
def do_simulation_step(old_map, dead, alive):
width = len(old_map[0])
height = len(old_map)
# init new map with empty cells
new_map = []
for _ in range(width):
line = []
for _ in range(height):
line.append(dead)
new_map.append(line)
for x in range(height):
for y in range(width):
nbs = count_alive_neighbours(old_map, x, y, alive)
# nbs = count_alive_neighbours_OLD(old_map, x, y, alive)
# The new value is based on our simulation rules
# First, if a cell is alive but has too few neighbours, kill it.
if old_map[x][y] == alive:
if nbs < DEATH_LIMIT:
new_map[x][y] = dead
else:
new_map[x][y] = alive
# Otherwise, if the cell is dead now, check if it has the right number of neighbours to be 'born'
else:
if nbs > BIRTH_LIMIT:
new_map[x][y] = alive
else:
new_map[x][y] = dead
return new_map
def init_with_noise(width, height, dead, alive):
map = []
for _ in range(width):
line = []
for _ in range(height):
if random.random() < CHANCE_TO_START_ALIVE:
line.append(alive)
else:
line.append(dead)
map.append(line)
return map
def generate_with_automata(width, height, dead, alive): # SEED ?
map = init_with_noise(width, height, dead, alive)
for _ in range(NO_OF_STEPS):
map = do_simulation_step(map, dead, alive)
return map
class GameModel():
def __init__(self):
self.w = 32
self.h = 32
self.tiles = [
[
[] for x in range(self.w)
]
for y in range(self.h)
]
LEVEL = generate_with_automata(self.w, self.h, dead='g', alive='b')
for y in range(self.h):
for x in range(self.w):
if LEVEL[y][x] != ' ':
self.tiles[y][x] = LEVEL[y][x]
def export_all_tiles(self):
return self.tiles
def __str__(self):
ret = ''
for y in range(self.h):
for x in range(self.w):
ret += str(self.tiles[y][x])
ret += '\n'
return ret
if __name__ == '__main__':
model = GameModel()
print(model)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment