diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cd531cf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,54 @@
+# ---> C
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..66d1277
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,28 @@
+CC	= gcc
+FLAGS	= -Wall -g
+LFLAGS	= -lcatwalk
+
+all: bin/catwalk
+
+bin/catwalk: obj/main.o obj/interact.o obj/print.o obj/simplegen.o
+	@mkdir -p $(@D)
+	$(CC) $(FLAGS) -o $@ $(LFLAGS) $^
+
+obj/%.o: src/%.c
+	@mkdir -p $(@D)
+	$(CC) $(FLAGS) -o $@ -c $<
+
+obj/main.o: src/main.c
+obj/interact.o: src/interact.c
+obj/print.o: src/print.c
+obj/simplegen.o: src/simplegen.c
+
+.PHONY: clean mrproper install
+clean:
+	rm -rf obj
+mrproper: clean
+	rm -rf bin
+
+install: bin/catwalk
+	@mkdir -p /usr/local/bin/
+	cp bin/catwalk /usr/local/bin/
diff --git a/bin/catwalk b/bin/catwalk
new file mode 100755
index 0000000..6ccf49e
Binary files /dev/null and b/bin/catwalk differ
diff --git a/src/interact.c b/src/interact.c
new file mode 100644
index 0000000..1271278
--- /dev/null
+++ b/src/interact.c
@@ -0,0 +1,307 @@
+/* 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   */
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include "print.h"
+#include "interact.h"
+
+#define COMMAND_MAX_SIZE 100
+#define STR_STARTS_WITH(s1, s2) (strncmp(s1, s2, strlen(s2)) == 0)
+
+void print_help()
+{
+    printf(" | [l]eft, [r]ight     - move towards the specified direction\n");
+    printf(" | [u]p, [d]own        - move towards the specified direction\n");
+    printf(" | undo, z             - undo the last move\n");
+    printf(" | [r]eset             - reset the grid\n");
+    printf(" | help, ?             - show this help\n");
+    printf(" | [s]how              - show the current grid\n");
+    printf(" | exit, [q]uit        - exit the program\n");
+}
+
+void clear_buffer()
+{
+    int c = 0;
+    while (c != '\n' && c != EOF)
+    {
+        c = getchar();
+    }
+}
+
+int is_whitespace(char *str)
+{
+    if (*str == '\0')
+    {
+        return 1;
+    }
+    for (char *chr=str; *chr; chr++)
+    {
+        if (*chr != ' ' && *chr != '\t')
+        {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+void ltrim(char *dest, char *src)
+{
+    char *ch = src;
+    while (*ch)
+    {
+        if (*ch != ' ' && *ch != '\t')
+        {
+            break;
+        }
+        ch++;
+    }
+    strcpy(dest, ch);
+}
+
+int read_from_stdin(char *str, int length)
+{
+    char *entry_position = NULL;
+
+    if (fgets(str, length, stdin) != NULL)
+    {
+        entry_position = strchr(str, '\n');
+        if (entry_position != NULL)
+        {
+            *entry_position = '\0';
+        }
+        else
+        {
+            clear_buffer();
+        }
+        return 1;
+    }
+    else
+    {
+        clear_buffer();
+        return 0;
+    }
+}
+
+void interact(int width)
+{
+    grid *gd = init_grid(width);
+
+    printf("Welcome to Catwalk CLI. Type 'help' or '?' to see all available commands.\n");
+    char prompt[COMMAND_MAX_SIZE] = "";
+    char buffer[COMMAND_MAX_SIZE] = "";
+
+    refresh_grid(gd);
+    init_player_route(gd);
+
+    for(;;)
+    {
+        if (is_whitespace(prompt))
+        {
+            printf("catwalk> ");
+            read_from_stdin(prompt, COMMAND_MAX_SIZE);
+            ltrim(buffer, prompt);
+            strcpy(prompt, buffer);
+        }
+        else
+        {
+            if STR_STARTS_WITH(prompt, "help")
+            {
+                print_help();
+                strcpy(buffer, prompt+strlen("help"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "?")
+            {
+                print_help();
+                strcpy(buffer, prompt+strlen("?"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "show")
+            {
+                print_interactive_grid(gd);
+                strcpy(buffer, prompt+strlen("show"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "reset")
+            {
+                if (gd->player_route->first->next == NULL)
+                {
+                    printf("Play first!\n");
+                }
+                else
+                {
+                    delete_element(gd->player_route->first->next);
+                    gd->player_route->first->next = NULL;
+                    gd->player_route->last = gd->player_route->first;
+                }
+                strcpy(buffer, prompt+strlen("reset"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "route")
+            {
+                print_route(gd->player_route);
+                strcpy(buffer, prompt+strlen("route"));
+                ltrim(prompt, buffer);
+            }
+            else if (STR_STARTS_WITH(prompt, "exit") || STR_STARTS_WITH(prompt, "quit") || STR_STARTS_WITH(prompt, "q"))
+            {
+                break;
+            }
+            else if STR_STARTS_WITH(prompt, "undo")
+            {
+                if (gd->player_route->first->next == NULL)
+                {
+                    printf("Can't undo! (single element)\n");
+                }
+                else
+                {
+                    pop_back(gd->player_route);
+                }
+                strcpy(buffer, prompt+strlen("z"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "left")
+            {
+                switch (move_left(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("left"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "right")
+            {
+                switch (move_right(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("right"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "up")
+            {
+                switch (move_up(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("up"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "down")
+            {
+                switch (move_down(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("down"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "s")
+            {
+                print_interactive_grid(gd);
+                strcpy(buffer, prompt+strlen("s"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "l")
+            {
+                switch (move_left(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("l"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "r")
+            {
+                switch (move_right(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("r"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "u")
+            {
+                switch (move_up(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("u"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "d")
+            {
+                if (gd->player_route->first->next == NULL)
+                {
+                    printf("Can't undo! (single element)\n");
+                }
+                else
+                {
+                    pop_back(gd->player_route);
+                }
+                strcpy(buffer, prompt+strlen("undo"));
+                ltrim(prompt, buffer);
+            }
+            else if STR_STARTS_WITH(prompt, "z")
+            {
+                switch (move_down(gd->player_route))
+                {
+                    case 1: puts("Cannot move: border of the grid"); break;
+                    case 2: puts("Cannot move: already went there"); break;
+                }
+                strcpy(buffer, prompt+strlen("d"));
+                ltrim(prompt, buffer);
+            }
+            else
+            {
+                printf("Unrecognized command : '%s'!\n", prompt);
+                prompt[0] = '\0';
+            }
+        }
+
+
+        if (gd->player_route->last->x == gd->end[0] && gd->player_route->last->y == gd->end[1])
+        {
+            print_interactive_grid(gd);
+            if (verify(gd))
+            {
+                printf("You won!\n");
+            }
+            else
+            {
+                printf("You lost!\n");
+            }
+
+            random_start(gd);
+            refresh_grid(gd);
+            reset_player_route(gd);
+        }
+    }
+
+    delete_grid(gd);
+}
diff --git a/src/interact.h b/src/interact.h
new file mode 100644
index 0000000..d6da3dc
--- /dev/null
+++ b/src/interact.h
@@ -0,0 +1,32 @@
+/* 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   */
+
+#ifndef INTERACT_H_INCLUDED
+#define INTERACT_H_INCLUDED
+
+#include 
+
+void print_help();
+
+void clear_buffer();
+
+int is_whitespace(char *str);
+
+int read_from_stdin(char *str, int length);
+
+void interact(int width);
+
+#endif /* INTERACT_H_INCLUDED */
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..0ca0ac7
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,100 @@
+/* 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   */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "interact.h"
+#include "simplegen.h"
+
+#define PROGRAM_VERSION "1.0"
+
+void help(char *program_name)
+{
+    printf("\
+Usage : %s [parameters]\n",
+    program_name);
+    puts("\n\
+  -h, --help              Print this help.\n\
+  -v, --version           Print version info.\n\
+  -i, --interactive       Launch catwalk-cli in interactive mode (default\n\
+  -s, --simple            Create a grid, without permitting to play.\n\
+  -w, --width      Create a grid with the given width.\n\
+--interactive, --simple, --help and --version are mutually exclusive: the last argument is kept.\n\n\
+This program was made with love by Valentin Moguerou .");
+}
+
+void version()
+{
+    printf("Catwalk CLI version 1.0\n");
+}
+
+int main(int argc, char **argv)
+{
+    int width = 4;
+    char mode = 'i';
+    for (int i=1; i  */
+
+#include 
+
+#include 
+#include 
+
+#include "print.h"
+
+//#define  COLORED_PATH
+#ifdef   COLORED_PATH
+# define KNRM "\e[0m"
+# define KRED "\e[31m"
+#endif
+
+const char ASCII_START[GRID_CELL_H][GRID_CELL_W]
+= {
+    {' ', ' ', '/',  '\\', ' ',  ' ', ' '},
+    {' ', '/', '\\', ' ',  '\\', '/', ' '},
+    {' ', ' ', ' ',  '\\', '/',  ' ', ' '}
+};
+
+const char ASCII_CAT[GRID_CELL_H][GRID_CELL_W]
+= {
+    {' ', '/', '\\', '_', '/', '\\', ' '},
+    {'(', ' ', 'o',  '.', 'o', ' ',  ')'},
+    {' ', '>', ' ',  '^', ' ', '<',  ' '}
+};
+
+const char ASCII_MILK[GRID_CELL_H][GRID_CELL_W]
+= {
+    {' ', ' ',  '=', '=', ' ',  ' ', ' '},
+    {' ', '/',  'm', 'i', '\\', ' ', ' '},
+    {' ', '\\', 'l', 'k', '/',  ' ', ' '}
+};
+
+void print_interactive_grid(grid *gd)
+{
+    element *pos = gd->player_route->last; // define pointer to last element of player route
+    element *el;
+    for (int y=0; y<(gd->width+1)*(GRID_CELL_H+1); y++) // for each line
+    {
+        for (int x=0; x<(gd->width+1)*(GRID_CELL_W+1); x++) // for each column
+        {
+            if (xhints->x[x/(GRID_CELL_W+1)-1]);
+                }
+                else if (x == GRID_CELL_W/2 && y%(GRID_CELL_H+1) == GRID_CELL_H/2) // left indicators
+                {
+                    printf("%d", gd->hints->y[y/(GRID_CELL_H+1)-1]);
+                }
+                else
+                {
+                    putchar(CELL_FILL_CHAR); // blank space around numbers
+                }
+            }
+            else // else if body (cells)
+            {
+                if ((x+1)%(GRID_CELL_W+1) == 0 && (y+1)%(GRID_CELL_H+1) == 0)
+                {
+                    putchar(CELL_NODE_CHAR); // cell border intersections
+                }
+                else if ((y+1)%(GRID_CELL_H+1) == 0)
+                {
+                    putchar(HO_BORDER_CHAR); // cell horizontal borders
+                }
+                else if ((x+1)%(GRID_CELL_W+1) == 0)
+                {
+                    putchar(VE_BORDER_CHAR); // cell vertical borders
+                }
+                else // if inside cells
+                {
+                    if (x/(GRID_CELL_W+1)-1 == pos->x && y/(GRID_CELL_H+1)-1 == pos->y) // if cursor position corresponds to the player position
+                    {
+                        putchar(ASCII_CAT[y%(GRID_CELL_H+1)][x%(GRID_CELL_W+1)]);
+                    }
+                    else if (x/(GRID_CELL_W+1)-1 == gd->start[0] && y/(GRID_CELL_H+1)-1 == gd->start[1]) // if the player has moved, if cursor position corresponds to the cat position
+                    {
+                        putchar(ASCII_START[y%(GRID_CELL_H+1)][x%(GRID_CELL_W+1)]);
+                    }
+                    else if (x/(GRID_CELL_W+1)-1 == gd->end[0] && y/(GRID_CELL_H+1)-1 == gd->end[1]) // if corresponds to the milk position
+                    {
+                        putchar(ASCII_MILK[y%(GRID_CELL_H+1)][x%(GRID_CELL_W+1)]);
+                    }
+                    else if (!is_free(gd->player_route, x/(GRID_CELL_W+1)-1, y/(GRID_CELL_H+1)-1))
+                    {
+                        if (!el)
+                        {
+                            el = find_coordinates(gd->player_route, x/(GRID_CELL_W+1)-1, y/(GRID_CELL_H+1)-1);
+                        }
+                        else if (el->x!=x/(GRID_CELL_W+1)-1 || el->y!=y/(GRID_CELL_H+1)-1)
+                        {
+                            el = find_coordinates(gd->player_route, x/(GRID_CELL_W+1)-1, y/(GRID_CELL_H+1)-1);
+                        }
+                        if (x%(GRID_CELL_W+1) == GRID_CELL_W/2 && y%(GRID_CELL_H+1) == GRID_CELL_H/2)
+                        {
+                            #ifdef COLORED_PATH
+                            printf("%s%c%s", KRED, CELL_NODE_CHAR, KNRM);
+                            #else
+                            putchar(CELL_NODE_CHAR);
+                            #endif
+                        }
+                        else if (x%(GRID_CELL_W+1) == GRID_CELL_W/2 || y%(GRID_CELL_H+1) == GRID_CELL_H/2)
+                        {
+                            if (x%(GRID_CELL_W+1) < GRID_CELL_W/2 && is_left(el, el->previous))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, HO_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(HO_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (x%(GRID_CELL_W+1) > GRID_CELL_W/2 && is_right(el, el->previous))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, HO_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(HO_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (y%(GRID_CELL_H+1) < GRID_CELL_H/2 && is_up(el, el->previous))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, VE_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(VE_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (y%(GRID_CELL_H+1) > GRID_CELL_H/2 && is_down(el, el->previous))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, VE_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(VE_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (x%(GRID_CELL_W+1) < GRID_CELL_W/2 && is_left(el, el->next))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, HO_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(HO_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (x%(GRID_CELL_W+1) > GRID_CELL_W/2 && is_right(el, el->next))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, HO_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(HO_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (y%(GRID_CELL_H+1) < GRID_CELL_H/2 && is_up(el, el->next))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, VE_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(VE_BORDER_CHAR);
+                                #endif
+                            }
+                            else if (y%(GRID_CELL_H+1) > GRID_CELL_H/2 && is_down(el, el->next))
+                            {
+                                #ifdef COLORED_PATH
+                                printf("%s%c%s", KRED, VE_BORDER_CHAR, KNRM);
+                                #else
+                                putchar(VE_BORDER_CHAR);
+                                #endif
+                            }
+                            else
+                            {
+                                putchar(CELL_FILL_CHAR);
+                            }
+                        }
+                        else
+                        {
+                            putchar(CELL_FILL_CHAR);
+                        }
+                    }
+                    else // if cursor position corresponds to nothing
+                    {
+                        putchar(CELL_FILL_CHAR);
+                    }
+                }
+            }
+        }
+        putchar('\n'); // newline
+    }
+}
+
+
+void print_simple_grid(grid *gd)
+{
+    for (int y=0; y<(gd->width+1)*(GRID_CELL_H+1); y++) // for each line
+    {
+        for (int x=0; x<(gd->width+1)*(GRID_CELL_W+1); x++) // for each column
+        {
+            if (xhints->x[x/(GRID_CELL_W+1)-1]);
+                }
+                else if (x == GRID_CELL_W/2 && y%(GRID_CELL_H+1) == GRID_CELL_H/2) // left indicators
+                {
+                    printf("%d", gd->hints->y[y/(GRID_CELL_H+1)-1]);
+                }
+                else
+                {
+                    putchar(CELL_FILL_CHAR); // blank space around numbers
+                }
+            }
+            else // else if body (cells)
+            {
+                if ((x+1)%(GRID_CELL_W+1) == 0 && (y+1)%(GRID_CELL_H+1) == 0)
+                {
+                    putchar(CELL_NODE_CHAR); // cell border intersections
+                }
+                else if ((y+1)%(GRID_CELL_H+1) == 0)
+                {
+                    putchar(HO_BORDER_CHAR); // cell horizontal borders
+                }
+                else if ((x+1)%(GRID_CELL_W+1) == 0)
+                {
+                    putchar(VE_BORDER_CHAR); // cell vertical borders
+                }
+                else // if inside cells
+                {
+                    if (x/(GRID_CELL_W+1)-1 == gd->start[0] && y/(GRID_CELL_H+1)-1 == gd->start[1])
+                    {
+                        putchar(ASCII_CAT[y%(GRID_CELL_H+1)][x%(GRID_CELL_W+1)]);
+                    }
+                    else if (x/(GRID_CELL_W+1)-1 == gd->end[0] && y/(GRID_CELL_H+1)-1 == gd->end[1])
+                    {
+                        putchar(ASCII_MILK[y%(GRID_CELL_H+1)][x%(GRID_CELL_W+1)]);
+                    }
+                    else
+                    {
+                        putchar(CELL_FILL_CHAR);
+                    }
+                }
+            }
+        }
+        putchar('\n'); // newline
+    }
+}
+
+void print_indicators(grid *gd)
+{
+    printf("Indicators :\nX: ");
+    int i;
+    for (i=0; iwidth; i++)
+    {
+        printf("%d ", gd->hints->x[i]);
+    }
+    printf("\nY: ");
+    for (i=0; iwidth; i++)
+    {
+        printf("%d ", gd->hints->y[i]);
+    }
+    printf("\n");
+}
+
+void print_route(route *rt)
+{
+    element *el = rt->first;
+    printf("[(%d, %d)", el->x, el->y);
+    el = el->next;
+    while (el)
+    {
+        printf(", (%d, %d)", el->x, el->y);
+        el = el->next;
+    }
+    printf("]\n");
+}
diff --git a/src/print.h b/src/print.h
new file mode 100644
index 0000000..dc5f892
--- /dev/null
+++ b/src/print.h
@@ -0,0 +1,36 @@
+/* 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   */
+
+#ifndef PRINT_H_INCLUDED
+#define PRINT_H_INCLUDED
+
+#include 
+#include 
+
+void print_interactive_grid(grid *gd);
+void print_simple_grid(grid *gd);
+void print_indicators(grid *gd);
+void print_route(route *rt);
+
+#define GRID_CELL_H 3
+#define GRID_CELL_W 7
+
+#define CELL_FILL_CHAR ' '
+#define CELL_NODE_CHAR '+'
+#define HO_BORDER_CHAR '-'
+#define VE_BORDER_CHAR '|'
+
+#endif /* PRINT_H_INCLUDED */
diff --git a/src/simplegen.c b/src/simplegen.c
new file mode 100644
index 0000000..5cc6748
--- /dev/null
+++ b/src/simplegen.c
@@ -0,0 +1,31 @@
+/* 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   */
+
+#include 
+
+#include 
+
+#include "print.h"
+
+void simple_generation(int width)
+{
+    grid *gd = init_grid(width);
+    refresh_grid(gd);
+
+    print_simple_grid(gd);
+
+    delete_grid(gd);
+}
diff --git a/src/simplegen.h b/src/simplegen.h
new file mode 100644
index 0000000..f3d8cdb
--- /dev/null
+++ b/src/simplegen.h
@@ -0,0 +1,22 @@
+/* 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   */
+
+#ifndef SIMPLEGEN_H_INCLUDED
+#define SIMPLEGEN_H_INCLUDED
+
+void simple_generation(int width);
+
+#endif /* SIMPLEGEN_H_INCLUDED */