From 53664714b9a693391054d1c0c601b285f2b1a577 Mon Sep 17 00:00:00 2001 From: iceyrazor Date: Thu, 28 May 2026 18:49:05 -0500 Subject: init --- .gitignore | 3 + LICENSE | 21 +++++ README.md | 11 +++ build.sh | 29 +++++++ lib/algolib.c | 108 ++++++++++++++++++++++++ lib/gobjects.c | 51 ++++++++++++ lib/init.c | 88 ++++++++++++++++++++ lib/init.h | 19 +++++ lib/vectorlib.c | 72 ++++++++++++++++ src/1-1-binary-search-tree.c | 33 ++++++++ src/1-2-binary-search-tree-visual.c | 162 ++++++++++++++++++++++++++++++++++++ 11 files changed, 597 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100755 build.sh create mode 100644 lib/algolib.c create mode 100644 lib/gobjects.c create mode 100644 lib/init.c create mode 100644 lib/init.h create mode 100644 lib/vectorlib.c create mode 100644 src/1-1-binary-search-tree.c create mode 100644 src/1-2-binary-search-tree-visual.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6685dd8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin/** +**/.clangd +.clangd diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e4e5954 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 iceyrazor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..689873b --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Session 1 - Algorithms and Graphs - Intelligence and Learning + +Me following [Session 1 - Algorithms and Graphs - Intelligence and Learning](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6bePNiZLnglXUp2LXIjlCdb) with SDL2 + +## requirements + +- clang +- shell +- SDL2 +- SDL2_gfx +- SDL2_ttf \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e005808 --- /dev/null +++ b/build.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +DEBUG="" +LIB="-Ilib/ -lSDL2_gfx -lSDL2_ttf" + +while getopts "d" opt; do + case "$opt" in + d) DEBUG="-Wall -fsanitize=address -g" + ;; + esac +done + +shift $((OPTIND-1)) +[ "${1:-}" = "--" ] && shift + +if [ "$1" ]; then + printf -- "\n\nmaking src %s\n" "$1" + file="src/$1" + clang -o bin/$(basename $file | sed 's/.c$//') $file $LIB `sdl2-config --cflags --libs` -lm $DEBUG +else + for file in src/*; do + if [ -f "$file" ]; then + if [ "$file" != ".clangd" ]; then + printf -- "\n\nmaking %s\n" "$file" + clang -o bin/$(basename $file | sed 's/.c$//') $file $LIB `sdl2-config --cflags --libs` -lm $DEBUG + fi + fi + done +fi diff --git a/lib/algolib.c b/lib/algolib.c new file mode 100644 index 0000000..43a1f2e --- /dev/null +++ b/lib/algolib.c @@ -0,0 +1,108 @@ +#ifndef algolib +#define algolib + +#include +#include +#include +#include +#include +#include +#include + +#define flaot float + +//Binary Search Tree + +typedef struct BS_Node { + int value; + struct BS_Node *left; + struct BS_Node *right; + Point pos; + TEXT *text; +} BS_Node; + +void BSAddNode(BS_Node **self, BS_Node **node){ + if ((*node)->value < (*self)->value){ + if((*self)->left == NULL){ + (*self)->left = (*node); + } else { + BSAddNode(&(*self)->left,node); + } + } else if ((*node)->value > (*self)->value){ + if((*self)->right == NULL){ + (*self)->right = (*node); + } else { + BSAddNode(&(*self)->right,node); + } + } else { + free(*node); + } +} + +void BSAddValue(BS_Node **root, int value){ + BS_Node *node = (BS_Node*)malloc(sizeof(BS_Node)); + node->value=value; + node->left = NULL; + node->right = NULL; + + if ((*root) == NULL){ + (*root) = node; + } else { + BSAddNode(root, &node); + } +} + +void BSPrintTree(BS_Node **node){ + if((*node)->left != NULL){ + BSPrintTree(&(*node)->left); + } + printf("%d\n",(*node)->value); + if((*node)->right!= NULL){ + BSPrintTree(&(*node)->right); + } +} + +BS_Node *BSSearchTree(BS_Node **node, int val){ + if((*node)->value == val) { + return *node; + } else if (val < (*node)->value && (*node)->left != NULL){ + return BSSearchTree(&(*node)->left,val); + } else if (val > (*node)->value && (*node)->right!= NULL){ + return BSSearchTree(&(*node)->right,val); + } + return NULL; +} + +void BSFreeTree(BS_Node **node){ + if((*node)->left != NULL){ + BSFreeTree(&(*node)->left); + } + if((*node)->right != NULL){ + BSFreeTree(&(*node)->right); + } + free(*node); +} + + +//Breadth-First Search + +typedef struct BFS_Node{ + char *value; + struct BFS_Node **edges; + bool searched; + struct BFS_Node *parent; +} BFS_Node; + +typedef struct BFS_Graph{ + BFS_Node **nodes; + BFS_Node **graph; //make hashmap +} BFS_Graph; + +BFS_Node *BFS_Constructor(char *value){ + BFS_Node *node=(BFS_Node*)malloc(sizeof(BFS_Node)); + node->value=value; + node->edges=(BFS_Node**)malloc(sizeof(BFS_Node*)*2048); + return node; +} + +#endif diff --git a/lib/gobjects.c b/lib/gobjects.c new file mode 100644 index 0000000..0817181 --- /dev/null +++ b/lib/gobjects.c @@ -0,0 +1,51 @@ +#ifndef gobjects +#define gobjects + +#include +#include +#include + +#define flaot float + +typedef struct TEXT { + SDL_Rect textRect; + SDL_Texture *texture; +} TEXT; + +typedef struct GS{ + int width; + int height; + SDL_Renderer *renderer; + TTF_Font *font; +} GS; + +TEXT *text_constructor(GS *stuff, char *text_buf){ + TEXT *text=(TEXT*)malloc(sizeof(TEXT)); + SDL_Color color={ + 244,222,205 + }; + int w, h; + TTF_SizeUTF8(stuff->font,text_buf,&w,&h); + SDL_Rect textRect={ + 0,0,w,h + }; + textRect.x=(stuff->width/2)-(textRect.w/2); + textRect.y=(stuff->height/2)-(textRect.h/2); + SDL_Surface *textSurface = TTF_RenderUTF8_Solid_Wrapped(stuff->font, text_buf, color, textRect.w); + if(!textSurface){ + fprintf(stderr,"ERROR WITH TEXT SURFACE\n"); + exit(EXIT_FAILURE); + } + SDL_Texture *texture = SDL_CreateTextureFromSurface(stuff->renderer, textSurface); + SDL_FreeSurface(textSurface); + if(!texture){ + fprintf(stderr,"ERROR WITH TEXTURE\n"); + exit(EXIT_FAILURE); + } + + text->texture=texture; + text->textRect=textRect; + return text; +} + +#endif diff --git a/lib/init.c b/lib/init.c new file mode 100644 index 0000000..9321038 --- /dev/null +++ b/lib/init.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + SDL_Log("SDL fails to initialize! %s\n", SDL_GetError()); + + if (TTF_Init() < 0) + SDL_Log("SDL fails to initialize ttf! %s\n", SDL_GetError()); + + int startw=600; + int starth=600; + + SDL_Window *window = SDL_CreateWindow(PROJECT_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, startw, starth, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); + if (!window) { + printf("Failed to create window: %s\n", SDL_GetError()); + } + SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_SOFTWARE); + if (!renderer) { + printf("Failed to create renderer: %s\n", SDL_GetError()); + } + + srand(time(NULL)); + OBJECT_INER obj_storage[obj_n]; + + STUFFS stuff = { + startw, + starth, + false, + 0, + 0, + NULL, + NULL, + (OBJECT){}, + }; + + stuff.renderer = renderer; + + stuff.font = TTF_OpenFont("/usr/share/fonts/TTF/JetBrainsMono-Regular.ttf" , 10); + + init_stuffs(startw,starth,obj_storage,&stuff); + + + + for (int i = 0; i < obj_n; i++) + stuff.obj.objs[i] = &obj_storage[i]; + + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + + bool quit = false; + SDL_Event e; + while (!quit) { + while (SDL_PollEvent(&e)) { + if (e.type == SDL_QUIT) { + quit = true; + } + else if(e.type == SDL_MOUSEBUTTONDOWN){ + if(e.button.button==SDL_BUTTON_LEFT){ + stuff.mousedown=true; + } else if(e.button.button==SDL_BUTTON_RIGHT){ + } + } else if(e.type==SDL_MOUSEBUTTONUP){ + stuff.mousedown=false; + } + stuff.mx=e.button.x; + stuff.my=e.button.y; + } + draw(window,&stuff); + SDL_Delay(10); + } + + on_end(&stuff); + TTF_CloseFont(stuff.font); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_QuitSubSystem(SDL_INIT_VIDEO); + + SDL_Quit(); + + return 0; +} diff --git a/lib/init.h b/lib/init.h new file mode 100644 index 0000000..5337013 --- /dev/null +++ b/lib/init.h @@ -0,0 +1,19 @@ +#ifndef inithell +#define inithell + +#include +#include +#include +#include + +typedef struct{ + int width; + int height; + bool mousedown; + int mx; + int my; + TTF_Font *font; + SDL_Renderer *renderer; + OBJECT obj; +} STUFFS; +#endif diff --git a/lib/vectorlib.c b/lib/vectorlib.c new file mode 100644 index 0000000..c059742 --- /dev/null +++ b/lib/vectorlib.c @@ -0,0 +1,72 @@ +#ifndef vector_lib +#define vector_lib + +#include +#include + +#define flaot float + +typedef struct { + float x; + float y; +} Point; + +void point_add(Point *A, Point *B){ + A->x = A->x + B->x; + A->y = A->y + B->y; +} + +void point_sub(Point *A, Point *B){ + A->x = A->x - B->x; + A->y = A->y - B->y; +} + +void point_mul(Point *A, Point *B){ + A->x = A->x * B->x; + A->y = A->y * B->y; +} + +void point_div(Point *A, Point *B){ + A->x = A->x / B->x; + A->y = A->y / B->y; +} + +float magnitude(flaot x, flaot y) { + return sqrt((pow(x,2) + pow(y,2))); +} + +void point_set_mag(Point *point, float mag){ + flaot getmag = magnitude(point->x, point->y); + flaot rx = (point->x / getmag) * mag; + flaot ry = (point->y / getmag) * mag; + + point->x = rx; + point->y = ry; +} + +void point_limit(Point *point, float mag){ + flaot getmag = magnitude(point->x, point->y); + flaot rx, ry; + if (getmag > mag){ + rx = (point->x / getmag) * mag; + ry = (point->y / getmag) * mag; + } else { + rx = point->x; + ry = point->y; + } + + point->x = rx; + point->y = ry; +} + +float RandomFloat(float min, float max){ + return ((max - min) * ((float)rand() / (double)RAND_MAX)) + min; +} + +float constrain(float val, float min, float max){ + if(val > max) val=max; + else if(val < min) val=min; + return val; +} + +#endif \ No newline at end of file diff --git a/src/1-1-binary-search-tree.c b/src/1-1-binary-search-tree.c new file mode 100644 index 0000000..cb5efc1 --- /dev/null +++ b/src/1-1-binary-search-tree.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +typedef struct TREE{ + BS_Node *root; +} TREE; + +int main(int argc, char **argv){ + srand(time(NULL)); + TREE tree = {NULL}; + + for(int i=0; i <40; i++){ + BSAddValue(&tree.root,(int)RandomFloat(0,100)); + } + + BSPrintTree(&tree.root); + BS_Node *found_node = BSSearchTree(&tree.root,53); + if(found_node != NULL) { + printf("53 found %d\n",found_node->value); + } else { + printf("53 not found\n"); + } + BSFreeTree(&tree.root); + return 0; +} + +/* Challanges + * + * balance the tree + */ \ No newline at end of file diff --git a/src/1-2-binary-search-tree-visual.c b/src/1-2-binary-search-tree-visual.c new file mode 100644 index 0000000..633dc7b --- /dev/null +++ b/src/1-2-binary-search-tree-visual.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define PROJECT_NAME "algorithms-binary search tree visual" +#define obj_n 1 + +typedef struct OBJECT_INER { + BS_Node *root; + BS_Node *found_node; +} OBJECT_INER; + +typedef struct OBJECT { + OBJECT_INER *objs[obj_n]; +} OBJECT; + +#include +#include + +int node_rows[200]; + +void count_rows(BS_Node **node){ + static int depth=1; + depth++; + if((*node)->left != NULL){ + node_rows[depth]++; + count_rows(&(*node)->left); + } + if((*node)->right != NULL){ + node_rows[depth]++; + count_rows(&(*node)->right); + } + depth--; +} + +int node_row_index[200]; + +void set_pos(BS_Node **node, STUFFS *stuff){ + static int depth=1; + depth++; + if((*node)->left != NULL){ + node_row_index[depth]++; + (*node)->left->pos.x = (((float)stuff->width / 2) + ((float)node_row_index[depth] * 30)) - (15 + (float)node_rows[depth] * 15); + (*node)->left->pos.y = (*node)->pos.y + 30; + set_pos(&(*node)->left, stuff); + } + if((*node)->right != NULL){ + node_row_index[depth]++; + (*node)->right->pos.x = (((float)stuff->width / 2) + ((float)node_row_index[depth] * 30)) - (15 + (float)node_rows[depth] * 15); + (*node)->right->pos.y = (*node)->pos.y + 30; + set_pos(&(*node)->right, stuff); + } + (*node)->text = NULL; + depth--; +} + +void add_text(BS_Node **node, STUFFS *stuff){ + GS stuff2={stuff->width,stuff->height,stuff->renderer,stuff->font}; + char *text=(char*)malloc(sizeof(char)*20); + sprintf(text,"%d",(*node)->value); + (*node)->text=text_constructor(&stuff2,text); + free(text); + (*node)->text->textRect.x=(*node)->pos.x-5; + (*node)->text->textRect.y=(*node)->pos.y-5; + if((*node)->left != NULL){ + add_text(&(*node)->left, stuff); + } + if((*node)->right != NULL){ + add_text(&(*node)->right, stuff); + } +} + +void init_stuffs(int w, int h, OBJECT_INER *objs,STUFFS *stuff){ + OBJECT_INER *tree = &objs[0]; + for(int i=0; i <100; i++){ + BSAddValue(&tree->root,(int)RandomFloat(0,100)); + } + tree->root->pos.x = (float)stuff->width / 2; + tree->root->pos.y = 16; + tree->root->text = NULL; + + BSPrintTree(&tree->root); + BS_Node *found_node = BSSearchTree(&tree->root,53); + tree->found_node=found_node; + if(found_node != NULL) { + printf("53 found %d\n",found_node->value); + } else { + printf("53 not found\n"); + } + + count_rows(&tree->root); + set_pos(&tree->root, stuff); + add_text(&tree->root,stuff); +} + + +void draw_node(BS_Node **node, STUFFS *stuff){ + if((*node)->left != NULL){ + draw_node(&(*node)->left, stuff); + SDL_RenderDrawLine(stuff->renderer,(*node)->pos.x,(*node)->pos.y,(*node)->left->pos.x,(*node)->left->pos.y); + } + SDL_RenderCopy(stuff->renderer,(*node)->text->texture,NULL, &(*node)->text->textRect); + circleRGBA(stuff->renderer,(*node)->pos.x,(*node)->pos.y,10,255,0,255,255); + if(stuff->obj.objs[0]->found_node != NULL && stuff->obj.objs[0]->found_node == *node){ + circleRGBA(stuff->renderer,(*node)->pos.x,(*node)->pos.y,10,0,255,255,255); + SDL_SetRenderDrawColor(stuff->renderer,255,0,255,255); + } + if((*node)->right != NULL){ + draw_node(&(*node)->right, stuff); + SDL_RenderDrawLine(stuff->renderer,(*node)->pos.x,(*node)->pos.y,(*node)->right->pos.x,(*node)->right->pos.y); + } +} + + +void draw(SDL_Window* window, STUFFS *stuff){ + SDL_SetRenderDrawColor(stuff->renderer,51,51,51,255); + //SDL_RenderClear(renderer); + SDL_RenderFillRect(stuff->renderer, &(SDL_Rect){0,0,stuff->width,stuff->height}); + //for (int i=0; iobj.objs[i]); + //} + + SDL_SetRenderDrawColor(stuff->renderer,255,0,255,255); + draw_node(&stuff->obj.objs[0]->root,stuff); + SDL_RenderPresent(stuff->renderer); +} + +void BSFreeText(BS_Node **node){ + if((*node)->left != NULL){ + BSFreeText(&(*node)->left); + } + if((*node)->right != NULL){ + BSFreeText(&(*node)->right); + } + + SDL_DestroyTexture((*node)->text->texture); + free((*node)->text); +} + +void on_end(STUFFS *stuff){ + OBJECT_INER *tree = stuff->obj.objs[0]; + BSFreeText(&tree->root); + BSFreeTree(&tree->root); +} + +#include + +/* Challanges + * + * make a prettier visualization + * + * - animation of a search + * + * - set node position closer to its parent node + */ -- cgit v1.3