Mercurial > public > algo-animator
comparison main.c @ 17:fba66d02f1cf
add randomize func and refactor UI
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Sun, 25 Jun 2023 18:46:29 +0100 |
parents | 2ded5f1f544a |
children | 6a5c5b137348 |
comparison
equal
deleted
inserted
replaced
16:2ded5f1f544a | 17:fba66d02f1cf |
---|---|
26 "Insertion sort", | 26 "Insertion sort", |
27 "Quick sort" | 27 "Quick sort" |
28 }; | 28 }; |
29 | 29 |
30 int selected_algo = 0; | 30 int selected_algo = 0; |
31 int speed = 5; | |
31 int refresh_counter = 0; | 32 int refresh_counter = 0; |
32 int iter_counter = 0; | 33 int iter_counter = 0; |
33 int arr_size; | 34 int arr_size; |
34 | 35 |
35 int* arr; | 36 float* arr; |
36 | 37 |
37 bool run; | 38 bool run; |
38 | 39 |
39 | 40 |
40 /* Algorithms */ | 41 /* Algorithms */ |
47 | 48 |
48 struct BubbleSortInfo bs = {1, 0}; | 49 struct BubbleSortInfo bs = {1, 0}; |
49 | 50 |
50 void bubble_sort() { | 51 void bubble_sort() { |
51 if (bs.i < arr_size - bs.step - 1) { | 52 if (bs.i < arr_size - bs.step - 1) { |
52 int current = arr[bs.i]; | 53 float current = arr[bs.i]; |
53 int next = arr[bs.i + 1]; | 54 float next = arr[bs.i + 1]; |
54 | 55 |
55 if (current > next) { | 56 if (current > next) { |
56 arr[bs.i + 1] = current; | 57 arr[bs.i + 1] = current; |
57 arr[bs.i] = next; | 58 arr[bs.i] = next; |
58 } | 59 } |
66 | 67 |
67 | 68 |
68 /* Helper functions */ | 69 /* Helper functions */ |
69 | 70 |
70 void create_array() { | 71 void create_array() { |
71 arr_size = floor((WINDOW_WIDTH - RECT_WIDTH) / (RECT_WIDTH + SPACE)) + 1; | 72 arr_size = WINDOW_WIDTH / (RECT_WIDTH + SPACE); |
72 arr = (int*)malloc(arr_size * sizeof(int)); | 73 arr = (float*)malloc(arr_size * sizeof(float)); |
73 | 74 |
75 float rect_increase = (WINDOW_HEIGHT - VPADDING * 2) / (float)(arr_size - 1); | |
76 | |
77 for (int i = 1; i <= arr_size; i++) { | |
78 arr[i - 1] = i * rect_increase; | |
79 } | |
80 } | |
81 | |
82 | |
83 void randomize_array() { | |
74 srand(time(NULL)); | 84 srand(time(NULL)); |
75 | 85 |
76 int min = VPADDING; | 86 // Fisher-Yates shuffle |
77 int max = WINDOW_HEIGHT - VPADDING; | 87 for (int i = arr_size - 1; i > 0; i--) { |
78 | 88 int j = rand() % (i + 1); |
79 for (int i = 0; i < arr_size; i++) { | 89 |
80 arr[i] = rand() % ((max - min) + 1) + min; | 90 // Swap |
91 float temp = arr[i]; | |
92 arr[i] = arr[j]; | |
93 arr[j] = temp; | |
81 } | 94 } |
82 } | 95 } |
83 | 96 |
84 | 97 |
85 bool array_sorted() { | 98 bool array_sorted() { |
103 } | 116 } |
104 } | 117 } |
105 | 118 |
106 | 119 |
107 /* Render functions */ | 120 /* Render functions */ |
108 | |
109 unsigned char* flipBitmapVertically(unsigned char* bitmap, int width, int height) { | |
110 unsigned char* flippedBitmap = (unsigned char*)malloc(width * height); | |
111 | |
112 for (int row = 0; row < height; row++) { | |
113 unsigned char* srcRow = bitmap + (row * width); | |
114 unsigned char* destRow = flippedBitmap + ((height - row - 1) * width); | |
115 memcpy(destRow, srcRow, width); | |
116 } | |
117 | |
118 return flippedBitmap; | |
119 } | |
120 | |
121 | 121 |
122 void render_text(int x, int y, char* text) { | 122 void render_text(int x, int y, char* text) { |
123 for (const char *c = text; *c; c++) { | 123 for (const char *c = text; *c; c++) { |
124 | 124 |
125 // Get glyph index from character code | 125 // Get glyph index from character code |
177 | 177 |
178 // Bottom left | 178 // Bottom left |
179 glVertex2f(x, VPADDING); | 179 glVertex2f(x, VPADDING); |
180 | 180 |
181 // Top left | 181 // Top left |
182 glVertex2f(x, arr[i]); | 182 glVertex2f(x, VPADDING + arr[i]); |
183 | 183 |
184 // Top right | 184 // Top right |
185 glVertex2f(x + RECT_WIDTH, arr[i]); | 185 glVertex2f(x + RECT_WIDTH, VPADDING + arr[i]); |
186 | 186 |
187 // Bottom right | 187 // Bottom right |
188 glVertex2f(x + RECT_WIDTH, VPADDING); | 188 glVertex2f(x + RECT_WIDTH, VPADDING); |
189 | 189 |
190 x += RECT_WIDTH + SPACE; | 190 x += RECT_WIDTH + SPACE; |
193 glEnd(); | 193 glEnd(); |
194 | 194 |
195 // Render text | 195 // Render text |
196 char text[256]; | 196 char text[256]; |
197 | 197 |
198 | |
199 // Top: Column 1 | |
198 sprintf(text, "Algorithm: %s", algos[selected_algo]); | 200 sprintf(text, "Algorithm: %s", algos[selected_algo]); |
199 render_text(20, WINDOW_HEIGHT - 50, text); | 201 render_text(20, WINDOW_HEIGHT - 50, text); |
200 | 202 |
203 sprintf(text, "Speed: %i", speed); | |
204 render_text(20, WINDOW_HEIGHT - 80, text); | |
205 | |
206 // Top: Column 2 | |
201 sprintf(text, "Number of elements: %i", arr_size); | 207 sprintf(text, "Number of elements: %i", arr_size); |
202 render_text(20, WINDOW_HEIGHT - 80, text); | 208 render_text(500, WINDOW_HEIGHT - 50, text); |
203 | 209 |
204 sprintf(text, "Iterations: %i", iter_counter); | 210 sprintf(text, "Iterations: %i", iter_counter); |
205 render_text(20, WINDOW_HEIGHT - 110, text); | 211 render_text(500, WINDOW_HEIGHT - 80, text); |
206 | 212 |
207 render_text(20, VPADDING - 50, "Press a or s to select an algorithm"); | 213 |
208 render_text(20, VPADDING - 80, "Press enter to run the algorithm"); | 214 // Bottom: Column 1 |
209 render_text(20, VPADDING - 110, "Press r to reset array"); | 215 render_text(20, VPADDING - 50, "Press a or s to select an algorithm."); |
216 render_text(20, VPADDING - 80, "Press u or d to modify speed."); | |
217 render_text(20, VPADDING - 110, "Press r to randomize the array."); | |
218 | |
219 // Bottom: Column 2 | |
220 render_text(800, VPADDING - 50, "Press enter to run the algorithm."); | |
210 | 221 |
211 glutSwapBuffers(); | 222 glutSwapBuffers(); |
212 } | 223 } |
213 | 224 |
214 | 225 |
218 if (run) { | 229 if (run) { |
219 bubble_sort(); | 230 bubble_sort(); |
220 refresh_counter++; | 231 refresh_counter++; |
221 iter_counter++; | 232 iter_counter++; |
222 | 233 |
223 if (refresh_counter == 90) { | 234 if (refresh_counter == speed) { |
224 glutPostRedisplay(); | 235 glutPostRedisplay(); |
225 refresh_counter = 0; | 236 refresh_counter = 0; |
226 } | 237 } |
227 | 238 |
228 } else { | 239 } else { |
237 | 248 |
238 /* User input handler */ | 249 /* User input handler */ |
239 | 250 |
240 void keyboard(unsigned char key, int x, int y) { | 251 void keyboard(unsigned char key, int x, int y) { |
241 | 252 |
242 // s | 253 // s: Next algorithm |
243 if (key == 115) { | 254 if (key == 115) { |
244 algo_selector(1); | 255 algo_selector(1); |
245 } | 256 } |
246 | 257 |
247 // a | 258 // a: Previous algorithm |
248 if (key == 97) { | 259 if (key == 97) { |
249 algo_selector(-1); | 260 algo_selector(-1); |
250 } | 261 } |
251 | 262 |
252 // r | 263 // r: Reset state |
253 if (key == 114) { | 264 if (key == 114) { |
254 | 265 randomize_array(); |
255 // Reset array | |
256 create_array(); | |
257 | 266 |
258 // Reset state | 267 // Reset state |
259 iter_counter = 0; | 268 iter_counter = 0; |
260 refresh_counter = 0; | 269 refresh_counter = 0; |
261 run = false; | 270 run = false; |
262 | 271 |
263 // Reset algo steps | 272 // Reset algo steps |
264 bs = (struct BubbleSortInfo){0, 0}; | 273 bs = (struct BubbleSortInfo){0, 0}; |
265 } | 274 } |
266 | 275 |
267 // enter | 276 // enter: Run program |
268 if (key == 13) { | 277 if (key == 13) { |
269 run = true; | 278 run = true; |
279 } | |
280 | |
281 // u: Increase speed | |
282 if (key == 117) { | |
283 speed++; | |
284 } | |
285 | |
286 // d: reduce speed | |
287 if (key == 100) { | |
288 speed--; | |
270 } | 289 } |
271 } | 290 } |
272 | 291 |
273 | 292 |
274 /* Set up functions */ | 293 /* Set up functions */ |