Skip to content

Instantly share code, notes, and snippets.

@polprog
Created April 18, 2024 19:12
Show Gist options
  • Save polprog/4a3b160a513932bb1c41b10456783c78 to your computer and use it in GitHub Desktop.
Save polprog/4a3b160a513932bb1c41b10456783c78 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
/* Plant like 2d cellular automaton by polprog <gorplop@sdf.org>
03.02.2022
Prototype program
Rules of the game:
- square grid
- Place cell if and only if it touches another cell with one corner
Extensions:
- Placement can be randomized
1) place iff above condition and with a x% chance (-DLEAF)
2) randomly place a cell in an empty spot (not corner or wall
adjacent to another cell) with some % chance (-DSTEM)
Released on 3 BSD
*/
#define WIDTH 60
#define HEIGHT 40
#define LEAF_PROB 30
#define STEM_PROB 1
#define CLEARSCREEN "\033[0;0H"
void print_field(char**);
void print_field_adv(char**);
void advance_step(char***, char***);
int neighbors(int x, int y, char***);
void stop();
static volatile int run = 1;
int main(){
//array inits
char **playfielda, **playfieldb;
playfielda = malloc(HEIGHT * (sizeof (char*)));
playfieldb = malloc(HEIGHT * (sizeof (char*)));
for(int i = 0; i < HEIGHT; i++){
playfielda[i] = malloc(WIDTH * (sizeof (char*)));
playfieldb[i] = malloc(WIDTH * (sizeof (char*)));
}
//register signal
signal(SIGINT, stop);
srand(time(NULL));
printf("\033[0;0H\033[0J");
playfielda[rand()%HEIGHT][rand()%WIDTH] = 1;
while(run){
puts(CLEARSCREEN);
print_field_adv(playfielda);
advance_step(&playfielda, &playfieldb);
usleep(250000);
}
//wrap up
for(int i = 0; i < HEIGHT; i++){
free(playfielda[i]);
free(playfieldb[i]);
}
free(playfielda);
free(playfieldb);
}
void print_field(char** field){
for(int i = 0; i < HEIGHT; i++){
for(int j = 0; j < WIDTH; j++){
if(field[i][j] == 0) putchar(' '); //draw space
if(field[i][j] == 1) putchar('X'); //draw branch
if(field[i][j] == 2) putchar('@'); //draw stem
}
putchar('\n');
}
}
void print_field_adv(char** field){
for(int i = 1; i < HEIGHT-1; i++){
for(int j = 1; j < WIDTH-1; j++){
if(field[i][j] == 0) putchar(' '); //draw space
//More advanced branch drawing code
//draws stems based on neighbor count
if(field[i][j] == 1){
if(neighbors(i, j, &field) <= 1) printf("\033[91m@");
else printf("\033[32mX");
}
if(field[i][j] == 2) printf("\033[32m@");
}
putchar('\n');
}
}
void advance_step(char*** fielda, char*** fieldb){
char **tmp;
int corners = 0;
int wall = 0;
for(int i = 0; i < HEIGHT; i++){
for(int j = 0; j < WIDTH; j++){
if((*fielda)[i][j] == 0) (*fieldb)[i][j] = 0;
else (*fieldb)[i][j] = 1;
#ifdef STEMS
if(rand()%10000 < STEM_PROB) (*fielda)[i][j] = 1;
#endif
}
}
for(int i = 1; i < HEIGHT-1; i++){
for(int j = 1; j < WIDTH-1; j++){
corners = 0;
wall = 0;
//Check Corners
corners = neighbors(i, j, fielda);
//Check walls
if((*fielda)[i-1][j]) wall = 1;
if((*fielda)[i][j-1]) wall = 1;
if((*fielda)[i+1][j]) wall = 1;
if((*fielda)[i][j+1]) wall = 1;
if(corners == 1 && wall != 1 && (*fielda)[i][j] == 0
#ifdef LEAF
&& rand()%1000 < LEAF_PROB
#endif
) (*fieldb)[i][j] = 2;
}
}
tmp = *fielda;
*fielda = *fieldb;
*fieldb = tmp;
}
int neighbors(int x, int y, char*** field){
int neigh = 0;
if((*field)[x-1][y-1]) neigh++;
if((*field)[x-1][y+1]) neigh++;
if((*field)[x+1][y-1]) neigh++;
if((*field)[x+1][y+1]) neigh++;
return neigh;
}
void stop(){
run = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment