diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/circuit.c | 312 |
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(¬_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> |
