139 lines
4.1 KiB
C
139 lines
4.1 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_image.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
|
|
typedef enum topic {NOTHING, MATH, PHYSICS, ENGLISH, FRENCH, INFO} topic;
|
|
// colles subjects
|
|
|
|
typedef struct date {int hour; int day; int month; int year;} date; /* format is {hour, day, month, year} */
|
|
// nothing to say here
|
|
|
|
typedef struct creneau {date date; int group; char* name; int namelen; topic mat;} creneau;
|
|
// one créneau de colle
|
|
// /!\ creneau has to be sorted by ascending dates
|
|
// with edt being a creneau*, it is required to have edt[0] be a Monday and edt[len(edt)-1] has to be a Friday
|
|
|
|
typedef struct colleur {char* name; int namelen; topic mat; date* disp; int n_disp;} colleur;
|
|
// available creneaux for the colleurs
|
|
|
|
typedef struct array {int* a; int len; int memlen;} array;
|
|
// yes
|
|
|
|
static int width = 1200;
|
|
static int height = 900;
|
|
|
|
int date_dist(date d1, date d2) { /* returns distance between d1 and d2 in days
|
|
if d2 is sooner than d1, it will return -1 */
|
|
if(d2.month == d1.month && d2.year == d1.year) {
|
|
if(d2.day < d1.day) {
|
|
return -1;
|
|
}
|
|
return d2.day - d1.day;
|
|
} else {
|
|
int is_31 = 0;
|
|
if(d1.month == 1 || d1.month == 3 || d1.month == 5 || d1.month == 7 || d1.month == 8 || d1.month == 10 || d1.month == 12) {
|
|
is_31 = 1;
|
|
} else {
|
|
is_31 = (d1.month == 2)*(-2) + (d1.month == 2 && d1.year%4 == 0 && d1.year%100 != 0);
|
|
}
|
|
if(d2.month - d1.month < 0 && d2.year <= d1.year) {
|
|
return -1;
|
|
} else if(d2.month - d1.month == 1 && d2.year == d1.year) {
|
|
return d2.day + (30 + is_31 - d1.day);
|
|
} else {
|
|
date copy;
|
|
copy.day = d1.day;
|
|
copy.month = d1.month;
|
|
copy.year = d1.year;
|
|
copy.month = (copy.month + 1);
|
|
if(copy.month == 13) {
|
|
copy.month = 1;
|
|
copy.year += 1;
|
|
}
|
|
return (30 + is_31 + date_dist(copy, d2));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool is_sorted(creneau* edt, int len) {
|
|
for(int i = 1; i < len; i++) {
|
|
if(date_dist(edt[i-1].date, edt[i].date) == -1) {
|
|
printf("Anomaly detected at lane %d (dates are not sorted in ascending order)\n", i);
|
|
return false;
|
|
}
|
|
}
|
|
printf("No problem detected\n");
|
|
return true;
|
|
}
|
|
|
|
creneau* import_creneaux(char* filename, int size) {
|
|
// import creneau data from a file
|
|
// see file.txt for an example
|
|
FILE* ptr = fopen(filename, "r");
|
|
char c = fgetc(ptr);
|
|
|
|
creneau* edt = malloc(sizeof(creneau)*size);
|
|
int i = 0;
|
|
int to_fill = 0;
|
|
|
|
int buffer = 0;
|
|
|
|
while(c != EOF && c != '$') {
|
|
if((int)(c) >= 48 && (int)(c) <= 57) {
|
|
buffer *= 10;
|
|
buffer += (int)(c) - 48;
|
|
} else {
|
|
if(to_fill == 0) {
|
|
edt[i].date.hour = buffer;
|
|
edt[i].group = 0;
|
|
edt[i].name = malloc(sizeof(char)*35);
|
|
edt[i].name[0] = '\0';
|
|
edt[i].namelen = 0;
|
|
edt[i].mat = NOTHING;
|
|
} else if(to_fill == 1) {
|
|
edt[i].date.day = buffer;
|
|
} else if(to_fill == 2) {
|
|
edt[i].date.month = buffer;
|
|
} else {
|
|
edt[i].date.year = buffer;
|
|
}
|
|
to_fill++;
|
|
buffer = 0;
|
|
if(c == '\n') {
|
|
i++;
|
|
to_fill = 0;
|
|
}
|
|
}
|
|
c = fgetc(ptr);
|
|
}
|
|
|
|
fclose(ptr);
|
|
|
|
if(!is_sorted(edt, size)) {
|
|
assert(0);
|
|
}
|
|
return edt;
|
|
}
|
|
|
|
bool str_equal(char* s1, char* s2) {
|
|
// note : s1 and s2 must be valid strings (aka have \0 at the end)
|
|
if((int)(s1[0]) == 0 || (int)(s2[0]) == 0) {
|
|
return ((int)(s1[0]) == 0 && (int)(s2[0]) == 0);
|
|
} else if(s1[0] != s2[0]) {
|
|
return false;
|
|
}
|
|
return str_equal(&s1[1], &s2[1]);
|
|
}
|
|
|
|
void str_copy(char* src, int l1, char* dest) {
|
|
/* put the word length as l1, \0 NOT included */
|
|
for(int i = 0; i < l1; i++) {
|
|
dest[i] = src[i];
|
|
}
|
|
dest[l1] = '\0';
|
|
} |