Initial commit
This commit is contained in:
parent
c749c570f9
commit
c606581ca1
80
src/directions.c
Normal file
80
src/directions.c
Normal 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
108
src/grid.c
Normal 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
58
src/indicators.c
Normal 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
210
src/route.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user