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