aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriceyrazor <iceyrazor@mailfence.com>2026-05-28 18:49:05 -0500
committericeyrazor <iceyrazor@mailfence.com>2026-05-28 18:49:05 -0500
commit53664714b9a693391054d1c0c601b285f2b1a577 (patch)
tree0a9f9e6d6dcf61f9f8d13f1e8c45e8ab6b361a9c
init
-rw-r--r--.gitignore3
-rw-r--r--LICENSE21
-rw-r--r--README.md11
-rwxr-xr-xbuild.sh29
-rw-r--r--lib/algolib.c108
-rw-r--r--lib/gobjects.c51
-rw-r--r--lib/init.c88
-rw-r--r--lib/init.h19
-rw-r--r--lib/vectorlib.c72
-rw-r--r--src/1-1-binary-search-tree.c33
-rw-r--r--src/1-2-binary-search-tree-visual.c162
11 files changed, 597 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <vectorlib.c>
+#include <gobjects.c>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
+#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 <stdlib.h>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
+#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 <stdio.h>
+#include <stdbool.h>
+#include <time.h>
+#include <init.h>
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_video.h>
+#include <SDL2/SDL_ttf.h>
+
+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 <stdio.h>
+#include <stdbool.h>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_ttf.h>
+
+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 <math.h>
+#include <stdlib.h>
+
+#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 <stdbool.h>
+#include <stdio.h>
+#include <algolib.c>
+#include <vectorlib.c>
+#include <time.h>
+
+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 <stdbool.h>
+#include <stdio.h>
+#include <vectorlib.c>
+#include <algolib.c>
+
+#include <SDL2/SDL_render.h>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_video.h>
+#include <SDL2/SDL2_gfxPrimitives.h>
+#include <SDL2/SDL_ttf.h>
+
+#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 <init.h>
+#include <gobjects.c>
+
+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; i<obj_n; i++){
+ // show(renderer,stuff,stuff->obj.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 <init.c>
+
+/* Challanges
+ *
+ * make a prettier visualization
+ *
+ * - animation of a search
+ *
+ * - set node position closer to its parent node
+ */