From 4c905e3aa2920bf528eaf51d55caea73957a9fa5 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sat, 13 Apr 2024 12:01:12 -0700 Subject: [PATCH] A little exploration of proc gen. --- space.gz | Bin 0 -> 6677 bytes terrain_automaton.py | 63 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 space.gz create mode 100644 terrain_automaton.py diff --git a/space.gz b/space.gz new file mode 100644 index 0000000000000000000000000000000000000000..ff21d930099940cd04407c649c832ca0a7ceb63f GIT binary patch literal 6677 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 Mu!#G9EF=*4AHHuuB>(^b literal 0 HcmV?d00001 diff --git a/terrain_automaton.py b/terrain_automaton.py new file mode 100644 index 0000000..62487cd --- /dev/null +++ b/terrain_automaton.py @@ -0,0 +1,63 @@ +''' +Cellular Automaton-based terrain generation adapted from: +https://codewithgolu.com/python/procedural-generation-of-game-content-with-python-a-comprehensive-guide/ +Produces goo like this: +################### ####### ###### ########### ########### ###### ### ####### > +####################### ####### # ###### ################### #### ####### ############# > +############################### ### ####### ################## ## ###### ############### > +################# ########### #### ######## ################ ## #### #### ########## > +##### #### ### ######## ####### ######### ############# ## ## ### ######### > +#### ####### ################### ########### #### #### ####### > +### ####### #################### ########## ###### ## ##### ###### > +## ######## ########### #### ##### ##### #### ###### ##### > + #################### ### #### #### ###### ######## #### > + ### #################### ### #### ### ######### ############ #### > + ##### ################### ### #### ## ########### ############# #### > + ###### #################### ### #### ### ############# ############## #########> + ############ #################### ### ###### #### ############################### ########> +################ ######### ####### #### ###### ##### ############################### #######> +################ ####### ###### #### #### ##### ############################### #######> +##### ###### ###### ##### #### #### ####################### #### ######> +## #### #### #### ##### #### ############ ######## ### #> + ### ## ###### #### ##### ##### #### ### > + ### ## ###### ## ## #### ### ## #### > + ## #### ## ##### #### ## ##### #### #### #### ###### #> + #### ###################### ### #### ###### ### ############# #########> + ################################## #### #### ##### ## ############## ########> +''' +import random + +# Set the size of the terrain +w, h = size = (256, 256) + +# Set the initial terrain state to random values +terrain = [[random.randint(0, 1) for _ in range(w)] for _ in range(h)] + +# Define the cellular automata rules +def cellular_automata_step(terrain): + new_terrain = [[0] * w for _ in range(h)] + + for x in range(1, w - 1): + for y in range(1, h - 1): + if sum(neighbors(terrain, x, y)) >= 5: + new_terrain[y][x] = 1 + + return new_terrain + + +def neighbors(terrain, x, y): + for i in range(y - 1, y + 2): + for j in range(x - 1, x + 2): + try: + n = terrain[i][j] + except IndexError: + continue + yield n + + +# Apply the cellular automata rules +for i in range(10): + terrain = cellular_automata_step(terrain) + +for row in terrain: + print(''.join(' #'[n] for n in row)