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 */