aboutsummaryrefslogtreecommitdiff
path: root/src/circuit.c
diff options
context:
space:
mode:
authoriceyrazor <iceyrazor@mailfence.com>2026-07-31 16:07:49 -0500
committericeyrazor <iceyrazor@mailfence.com>2026-07-31 16:07:49 -0500
commit433c49ac031ab9febe0602936dce551af8c40a25 (patch)
tree8968c0f7cdf771d7e988b8d2ca5be8b93d23ecce /src/circuit.c
parent90d9c0edf7a92b270aadc384e9e366c9a4e6aa79 (diff)
circuit generatorHEADmain
Diffstat (limited to 'src/circuit.c')
-rw-r--r--src/circuit.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/src/circuit.c b/src/circuit.c
new file mode 100644
index 0000000..b5dfe1a
--- /dev/null
+++ b/src/circuit.c
@@ -0,0 +1,312 @@
+#include <algolib.c>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <vectorlib.c>
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL2_gfxPrimitives.h>
+#include <SDL2/SDL_render.h>
+#include <SDL2/SDL_ttf.h>
+#include <SDL2/SDL_video.h>
+
+#define PROJECT_NAME "circuit"
+
+#define grid_cols 50
+#define grid_rows grid_cols
+
+#define obj_n grid_cols * grid_rows
+
+#define frame_delay 0
+
+// CONFIG
+#define random_chance 0 //chance of picking a new random spot
+#define random_direction 30 //chance of turning a line
+//not finished
+#define DIRS 4 //set to 8 for 8 directions. set to 4 for 4 directions
+
+// END CONFIG
+
+typedef struct CELL{
+ int i;
+ int j;
+ struct CELL* next;
+ struct CELL* prev;
+ bool circle;
+ bool visited;
+} CELL;
+
+typedef struct OBJECT {
+ CELL items[obj_n];
+ CELL* current;
+ int cells[obj_n];
+ int cells_len;
+ int w;
+ int h;
+} OBJECT;
+
+#include <init.h>
+
+//TODO: make it wrap?
+int get_index(int i, int j){
+ if (i < 0 || j < 0 || i > grid_cols-1 || j > grid_rows-1)
+ return -1;
+ return (j * grid_cols + i);
+}
+
+void cell_constructor(CELL* cell,int i,int j){
+ cell->i = i;
+ cell->j = j;
+ cell->visited=false;
+ cell->next = NULL;
+ cell->prev = NULL;
+ cell->circle = false;
+}
+
+void push_cell(CELL* arr[], CELL* cell, int count){
+ for (int i=0; i<count; i++){
+ if(!arr[i]){
+ arr[i]=cell;
+ return;
+ }
+ }
+}
+
+CELL* pop_cell(CELL* arr[], int count){
+ CELL* ret_cell;
+ for (int i=0; i<count; i++){
+ if(!arr[i]){
+ ret_cell = arr[i-1];
+ arr[i-1]=NULL;
+ return ret_cell;
+ } else if (i == count){
+ ret_cell = arr[i];
+ arr[i]=NULL;
+ return ret_cell;
+ }
+ }
+ return NULL;
+}
+
+void slice_match(int(* cells)[],int num,int count){
+ bool found=false;
+ for (int i=0; i<count; i++){
+ if((*cells)[i] == num)
+ found = true;
+ if(found==true){
+ if(i+1>=count){
+ (*cells)[i] = -1;
+ return;
+ }
+ if((*cells)[i+1] == -1){
+ (*cells)[i] = -1;
+ return;
+ }
+ (*cells)[i] = (*cells)[i+1];
+ }
+ }
+ (*cells)[count] = -1;
+ return;
+}
+
+void push_int(int(*cells)[],int ins, int count){
+ for (int i=0; i<count; i++){
+ if((*cells)[i] == -1){
+ (*cells)[i]=ins;
+ return;
+ }
+ }
+}
+
+void init_stuffs(int w, int h, STUFFS* stuff)
+{
+ if (DIRS != 8 && DIRS != 4){
+ //TODO: you still need to free sdl
+ //required editing init.c and updating ever other file.
+ fprintf(stderr,"DIRS must be 4 or 8");
+ exit(-1);
+ }
+ stuff->obj.w = stuff->width / grid_cols;
+ stuff->obj.h = stuff->height / grid_rows;
+
+ for (int j = 0; j < grid_rows; j++) {
+ for (int i = 0; i < grid_cols; i++) {
+ int index = j * grid_cols + i;
+ cell_constructor(&stuff->obj.items[index],i,j);
+ }
+ }
+
+ stuff->obj.cells_len=obj_n;
+
+ //TODO: optomize this. tiz slow at big grids
+ int ints_len=obj_n;
+ int ints[obj_n];
+ for(int i=0; i<obj_n; i++){
+ ints[i]=i;
+ stuff->obj.cells[i]=-1;
+ }
+
+ for (int i=0; i<obj_n; i++){
+ int selected = (int)RandomFloat(0,ints_len);
+ push_int(&(stuff->obj.cells),ints[selected],obj_n);
+ slice_match(&ints,ints[selected],obj_n);
+ ints_len--;
+ }
+
+ stuff->obj.current = &stuff->obj.items[(int)RandomFloat(0,obj_n)];
+ stuff->obj.current->circle=true;
+}
+
+void pick_random(STUFFS* stuff){
+ stuff->obj.current->circle=true;
+ int selected=(int)RandomFloat(0,stuff->obj.cells_len);
+ stuff->obj.current=&stuff->obj.items[stuff->obj.cells[selected]];
+ stuff->obj.current->circle=true;
+ slice_match(&stuff->obj.cells,stuff->obj.cells[selected],obj_n);
+ stuff->obj.cells_len--;
+}
+
+void random_dir(STUFFS* stuff, int* index){
+
+ int not_checked[DIRS]={0,1,2,3,4,5,6,7};
+ int randdir=-1;
+ for (int k=0; k<DIRS; k++){
+ randdir = (int)RandomFloat(0,DIRS-1-k);
+ slice_match(&not_checked,not_checked[randdir],DIRS);
+
+ switch(randdir){
+ case 0:
+ *index = get_index(stuff->obj.current->i,stuff->obj.current->j-1);
+ break;
+ case 1:
+ *index = get_index(stuff->obj.current->i+1,stuff->obj.current->j);
+ break;
+ case 2:
+ *index = get_index(stuff->obj.current->i,stuff->obj.current->j+1);
+ break;
+ case 3:
+ *index = get_index(stuff->obj.current->i-1,stuff->obj.current->j);
+ break;
+ case 4:
+ *index = get_index(stuff->obj.current->i-1,stuff->obj.current->j+1);
+ break;
+ case 5:
+ *index = get_index(stuff->obj.current->i+1,stuff->obj.current->j+1);
+ break;
+ case 6:
+ *index = get_index(stuff->obj.current->i+1,stuff->obj.current->j-1);
+ break;
+ case 7:
+ *index = get_index(stuff->obj.current->i-1,stuff->obj.current->j-1);
+ break;
+ }
+
+ if(*index==-1) continue;
+
+ if (stuff->obj.items[*index].visited==false){ break; }
+ }
+}
+
+void step_next(STUFFS* stuff){
+ int index = -1;
+
+ int doranddir=(int)RandomFloat(0,100);
+
+ if(doranddir > random_direction && stuff->obj.current->prev){
+ int tmp_index=0;
+ int x = stuff->obj.current->i - stuff->obj.current->prev->i + stuff->obj.current->i;
+ int y = stuff->obj.current->j - stuff->obj.current->prev->j + stuff->obj.current->j;
+ tmp_index = get_index(x,y);
+ if(tmp_index == -1 || stuff->obj.items[tmp_index].visited==true){
+ random_dir(stuff,&index);
+ } else {
+ index=tmp_index;
+ }
+ } else {
+ random_dir(stuff,&index);
+ }
+
+
+ if(index != -1 && stuff->obj.items[index].visited==false){
+ stuff->obj.items[index].prev=stuff->obj.current;
+ stuff->obj.current->next=(struct CELL*)&stuff->obj.items[index];
+ stuff->obj.current=&stuff->obj.items[index];
+ slice_match(&stuff->obj.cells,index,obj_n);
+ stuff->obj.cells_len--;
+ } else {
+ pick_random(stuff);
+ }
+}
+
+
+void draw_cell(CELL* cell, STUFFS* stuff)
+{
+ int w = stuff->obj.w;
+ int x = cell->i * w;
+ int y = cell->j * w;
+ SDL_SetRenderDrawColor(stuff->renderer, 255, 255, 255, 255);
+
+
+ if (cell->next){
+ int x2 = cell->next->i * w;
+ int y2 = cell->next->j * w;
+ thickLineRGBA(stuff->renderer,x + w/2,y + w/2,x2 + w/2,y2 + w/2, w/3,255,255,255,255);
+ if(cell->next->circle==true){
+ filledCircleRGBA(stuff->renderer,x2 + w/2, y2 + w/2, w/2.5, 255, 255, 255, 255);
+ filledCircleRGBA(stuff->renderer,x2 + w/2, y2 + w/2, w/3.5, 20, 20, 20, 255);
+ }
+ }
+
+ if(cell->circle==true){
+ filledCircleRGBA(stuff->renderer,x + w/2, y + w/2, w/2.5, 255, 255, 255, 255);
+ filledCircleRGBA(stuff->renderer,x + w/2, y + w/2, w/3.5, 20, 20, 20, 255);
+ }
+}
+
+void draw_highlight(CELL* cell, STUFFS* stuff){
+ int w = stuff->obj.w;
+ int x = cell->i * w;
+ int y = cell->j * w;
+ SDL_SetRenderDrawColor(stuff->renderer, 255, 0, 0, 200);
+ SDL_RenderFillRect(stuff->renderer, &(SDL_Rect) { x, y, w, w });
+}
+
+void draw(SDL_Window* window, STUFFS* stuff)
+{
+ static bool done = false;
+ if (done == false) {
+ SDL_SetRenderDrawColor(stuff->renderer, 20, 20, 20, 255);
+ // SDL_RenderClear(renderer);
+ SDL_RenderFillRect(stuff->renderer, &(SDL_Rect) { 0, 0, stuff->width, stuff->height });
+
+ for (int i=0; i<obj_n; i++){
+ draw_cell(&stuff->obj.items[i],stuff);
+ }
+
+ stuff->obj.current->visited=true;
+
+ if(stuff->obj.cells_len > 0){
+ float step = RandomFloat(0,100);
+ if (step > random_chance){
+ step_next(stuff);
+ } else {
+ pick_random(stuff);
+ }
+ } else {
+ done=true;
+ }
+
+
+ if(done==false)
+ draw_highlight(stuff->obj.current,stuff);
+
+
+ SDL_RenderPresent(stuff->renderer);
+ }
+}
+
+void on_end(STUFFS* stuff)
+{
+}
+
+#include <init.c>