Initial commit

This commit is contained in:
Valentin Moguérou 2021-10-05 11:01:08 +00:00
parent c749c570f9
commit c606581ca1
4 changed files with 456 additions and 0 deletions

80
src/directions.c Normal file
View File

@ -0,0 +1,80 @@
/* CATWALK - Test your logic
Copyright (C) 2021 Valentin Moguerou
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/> */
#include <stdlib.h>
#include "../inc/directions.h"
#include "../inc/route.h"
#define RANDINT(MAX) (rand() % MAX)
directions *init_directions(route *rt)
{
directions *dirs = malloc(sizeof(*dirs));
if (dirs==NULL)
{
exit(EXIT_FAILURE);
}
dirs->rt = rt;
dirs->count = 0;
return dirs;
}
int evaluate_directions(directions *dirs)
{
int width = dirs->rt->width;
element *last = dirs->rt->last;
int count = 0;
if (last->x != 0 && is_free(dirs->rt, last->x-1, last->y))
{
dirs->cells[count][0] = last->x-1;
dirs->cells[count][1] = last->y;
count++;
}
if (last->x != (width-1) && is_free(dirs->rt, last->x+1, last->y))
{
dirs->cells[count][0] = last->x+1;
dirs->cells[count][1] = last->y;
count++;
}
if (last->y != 0 && is_free(dirs->rt, last->x, last->y-1))
{
dirs->cells[count][0] = last->x;
dirs->cells[count][1] = last->y-1;
count++;
}
if (last->y != (width-1) && is_free(dirs->rt, last->x, last->y+1))
{
dirs->cells[count][0] = last->x;
dirs->cells[count][1] = last->y+1;
count++;
}
dirs->count = count;
return count;
}
void push_choose(route *rt, directions *dirs)
{
int nb = RANDINT(dirs->count);
push_back(rt, dirs->cells[nb][0], dirs->cells[nb][1]);
}
void delete_directions(directions *dirs)
{
free(dirs);
}

108
src/grid.c Normal file
View File

@ -0,0 +1,108 @@
/* CATWALK - Test your logic
Copyright (C) 2021 Valentin Moguerou
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/> */
#include <stdlib.h>
#include "../inc/grid.h"
#include "../inc/indicators.h"
#include "../inc/route.h"
#define RANDINT(MAX) (rand() % MAX)
grid *init_grid(int width)
{
grid *gd = malloc(sizeof(grid));
if (gd == NULL)
{
exit(EXIT_FAILURE);
}
gd->width = width;
gd->hints = init_indicators(width);
gd->player_route = NULL;
return gd;
}
void random_grid(grid *gd, int seed)
{
srand(seed);
random_start(gd);
refresh_grid(gd);
}
void random_start(grid *gd)
{
gd->start[0] = RANDINT(gd->width);
gd->start[1] = RANDINT(gd->width);
}
void refresh_grid(grid *gd)
{
route *rt = init_route(gd->width, gd->start[0], gd->start[1]);
generate(rt);
setup_indicators(gd->hints, rt);
element *last = rt->last;
gd->end[0] = last->x;
gd->end[1] = last->y;
delete_route(rt);
}
void init_player_route(grid *gd)
{
route *player_rt = malloc(sizeof(*player_rt));
if (player_rt == NULL)
{
exit(EXIT_FAILURE);
}
player_rt = init_route(gd->width, gd->start[0], gd->start[1]);
gd->player_route = player_rt;
}
void reset_player_route(grid *gd)
{
delete_route(gd->player_route);
init_player_route(gd);
}
void delete_grid(grid *gd)
{
delete_indicators(gd->hints);
if (gd->player_route)
{
delete_route(gd->player_route);
}
free(gd);
}
int verify(grid *gd)
{
indicators *verif_in = init_indicators(gd->width);
setup_indicators(verif_in, gd->player_route);
for (int i=0; i<gd->width; i++)
{
if ((verif_in->x[i] != gd->hints->x[i]) || (verif_in->y[i] != gd->hints->y[i]))
{
return 0;
}
}
return 1;
}

58
src/indicators.c Normal file
View File

@ -0,0 +1,58 @@
/* CATWALK - Test your logic
Copyright (C) 2021 Valentin Moguerou
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/> */
#include <stdlib.h>
#include "../inc/indicators.h"
#include "../inc/route.h"
indicators *init_indicators(int width)
{
indicators *in = malloc(sizeof(*in));
if (in == NULL)
{
exit(EXIT_FAILURE);
}
in->x = calloc(width, sizeof(int));
in->y = calloc(width, sizeof(int));
if (in->x==NULL || in->y==NULL)
{
exit(EXIT_FAILURE);
}
return in;
}
void setup_indicators(indicators *in, route *rt)
{
for (int i=0; i<rt->width; i++)
{
in->x[i] = 0;
in->y[i] = 0;
}
for (element *el=rt->first; el; el=el->next)
{
in->x[el->x]++;
in->y[el->y]++;
}
}
void delete_indicators(indicators *hints)
{
free(hints->x);
free(hints->y);
free(hints);
}

210
src/route.c Normal file
View File

@ -0,0 +1,210 @@
/* CATWALK - Test your logic
Copyright (C) 2021 Valentin Moguerou
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/> */
#include <stdlib.h>
#include "../inc/directions.h"
#include "../inc/route.h"
#define RANDINT(MIN, MAX) ((rand()%(MAX-MIN)) + MIN)
int is_left(element *first, element *second)
{
return first->x-1 == second->x;
}
int is_right(element *first, element *second)
{
return first->x+1 == second->x;
}
int is_up(element *first, element *second)
{
return first->y-1 == second->y;
}
int is_down(element *first, element *second)
{
return first->y+1 == second->y;
}
int move_left(route *rt)
{
element *last = rt->last;
if (last->x == 0)
{
return 1;
}
else if (!is_free(rt, last->x-1, last->y))
{
return 2;
}
else
{
push_back(rt, last->x-1, last->y);
return 0;
}
}
int move_right(route *rt)
{
element *last = rt->last;
if (last->x == rt->width-1)
{
return 1;
}
else if (!is_free(rt, last->x+1, last->y))
{
return 2;
}
else
{
push_back(rt, last->x+1, last->y);
return 0;
}
}
int move_up(route *rt)
{
element *last = rt->last;
if (last->y == 0)
{
return 1;
}
else if (!is_free(rt, last->x, last->y-1))
{
return 2;
}
else
{
push_back(rt, last->x, last->y-1);
return 0;
}
}
int move_down(route *rt)
{
element *last = rt->last;
if (last->y == (rt->width-1))
{
return 1;
}
else if (!is_free(rt, last->x, last->y+1))
{
return 2;
}
else
{
push_back(rt, last->x, last->y+1);
return 0;
}
}
route *init_route(int width, int startx, int starty)
{
route *rt = malloc(sizeof(*rt));
element *el = malloc(sizeof(*el));
if (rt == NULL || el == NULL)
{
exit(EXIT_FAILURE); // memory allocation failed
}
el->previous = NULL;
el->next = NULL;
el->x = startx;
el->y = starty;
rt->width = width;
rt->first = el;
rt->last = el;
return rt;
}
void delete_element(element *el)
{
if (el->next)
{
delete_element(el->next);
}
free(el);
}
void delete_route(route *rt)
{
delete_element(rt->first);
free(rt);
}
void push_back(route *rt, int x, int y)
{
element *new_el = malloc(sizeof(*new_el));
if (new_el == NULL)
{
exit(EXIT_FAILURE);
}
new_el->x = x;
new_el->y = y;
new_el->previous = rt->last;
new_el->next = NULL;
rt->last->next = new_el;
rt->last = new_el;
}
void pop_back(route *rt)
{
element *last = rt->last;
rt->last = rt->last->previous;
rt->last->next = NULL;
free(last);
}
element *find_coordinates(route *rt, int x, int y)
{
for (element *el=rt->first; el; el=el->next)
{
if (el->x == x && el->y == y)
{
return el;
}
}
return NULL;
}
int is_free(route *rt, int x, int y)
{
for (element *el=rt->first; el; el=el->next)
{
if (x==el->x && y==el->y)
{
return 0;
}
}
return 1;
}
void generate(route *rt)
{
directions *dirs = init_directions(rt);
for (int i=0; i < RANDINT(1, rt->width*rt->width) && evaluate_directions(dirs); i++)
{
push_choose(rt, dirs);
}
}