diff --git a/src/interact.c b/src/interact.c index 44f7cca..510334e 100644 --- a/src/interact.c +++ b/src/interact.c @@ -102,71 +102,128 @@ int read_from_stdin(char *str, int length) void interact(int width) { + /* Avant de permettre à l'utilisateur d'intéragir + * avec la grille, encore faut-il la générer ! */ grid *gd = init_grid(width); + refresh_grid(gd); + init_player_route(gd); + // Afficher un message de bienvenue et d'aide courte printf("Welcome to Catwalk CLI. Type 'help' or '?' to see all available commands.\n"); + + /* Création des deux tableaux de caractères contenant les + * entrées de l'utilisateur. Le premier sert à stocker + * directement les entrées de l'utilisateur. Le second est + * utilisé pour permettre la copie et la modification + * du premier. */ char prompt[COMMAND_MAX_SIZE] = ""; char buffer[COMMAND_MAX_SIZE] = ""; - refresh_grid(gd); - init_player_route(gd); - + // Boucle principale for(;;) { + // vérification de la non-vacuité de prompt if (is_whitespace(prompt)) { - printf("catwalk> "); + printf("catwalk> "); // affichage + + // on met dans "prompt" l'entrée de l'utilisateur read_from_stdin(prompt, COMMAND_MAX_SIZE); + + /* on met une copie de "prompt" dans + * "buffer" sans les espaces */ ltrim(buffer, prompt); + + // on remet tout dans "prompt" strcpy(prompt, buffer); } else { + /* Succession d'expressions conditionnelles. + * Fonctionnement de l'entrée : l'utilisateur + * entre une suite de commandes; elles sont + * éxécutées successivement : par exemple, + * "llurus" est éxécuté comme cela : + * - "l" comme "left" (X2) + * - "u" comme "up" + * - "r" comme "right" + * - "u" comme "up" + * - "s" comme "show" + * Pour éviter les problèmes du type : + * prompt = "undo" : j'éxécute "u" pour "up" + * -> prompt = "ndo": commande inconnue, + * Les commandes en toutes lettres sont testées + * avant les commandes abrégées. */ if STR_STARTS_WITH(prompt, "help") { - print_help(); + print_help(); // action correspondante + + /* on enlève "help" de prompt et décale + * les caractères en conséquence */ strcpy(buffer, prompt+strlen("help")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "?") { - print_help(); + print_help(); // action correspondante + + /* on enlève "?" de prompt et décale + * les caractères en conséquence */ strcpy(buffer, prompt+strlen("?")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "show") { + /* on affiche la grille, en précisant qu'elle + * est interactive (afficher le chemin) */ print_interactive_grid(gd); + + /* on enlève "show" de prompt et décale + * les caractères en conséquence */ strcpy(buffer, prompt+strlen("show")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "reset") { + // Réinitialisation de la grille + + /* si le chemin du joueur ne + * contient qu'un élément */ if (gd->player_route->first->next == NULL) { + // demander à jouer d'abord printf("Play first!\n"); } else { + /* supprimer récursivement tous les éléments + * du chemin du joueur, sauf le premier */ delete_element(gd->player_route->first->next); gd->player_route->first->next = NULL; gd->player_route->last = gd->player_route->first; } + + // supprimer "reset" de prompt strcpy(buffer, prompt+strlen("reset")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "route") { + // afficher le chemin print_route(gd->player_route); - strcpy(buffer, prompt+strlen("route")); + + // supprimer "route" de prompt + 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")) { + // arrêter l'interaction break; } else if STR_STARTS_WITH(prompt, "undo") { + // annulation imposible s'il n'y a qu'un unique élément if (gd->player_route->first->next == NULL) { printf("Can't undo! (single element)\n"); @@ -175,87 +232,129 @@ void interact(int width) { pop_back(gd->player_route); } + + // supprimer "undo" de prompt strcpy(buffer, prompt+strlen("undo")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "left") { + /* tenter de se déplacer, et si erreur, + * afficher le message correspondant */ 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; } + + // supprimer "left" de prompt strcpy(buffer, prompt+strlen("left")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "right") { + /* tenter de se déplacer, et si erreur, + * afficher le message correspondant */ 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; } + + // supprimer "right" de prompt strcpy(buffer, prompt+strlen("right")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "up") { + /* tenter de se déplacer, et si erreur, + * afficher le message correspondant */ 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; } + + // supprimer "up" de prompt strcpy(buffer, prompt+strlen("up")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "down") { + /* tenter de se déplacer, et si erreur, + * afficher le message correspondant */ 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; } + + // supprimer "down" de prompt strcpy(buffer, prompt+strlen("down")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "s") { + // afficher la grille print_interactive_grid(gd); + + // supprimer "s" de prompt strcpy(buffer, prompt+strlen("s")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "l") { + // se déplacer 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; } + + // MàJ de prompt strcpy(buffer, prompt+strlen("l")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "r") { + // se déplacer 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; } + + // MàJ de prompt strcpy(buffer, prompt+strlen("r")); ltrim(prompt, buffer); } else if STR_STARTS_WITH(prompt, "u") { + // se déplacer 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; } + + // MàJ de prompt strcpy(buffer, prompt+strlen("u")); ltrim(prompt, buffer); } - else if STR_STARTS_WITH(prompt, "d") + else if STR_STARTS_WITH(prompt, "d") + { + 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")); + + } + else if STR_STARTS_WITH(prompt, "z") { + // annuler, mais seulement si possible if (gd->player_route->first->next == NULL) { printf("Can't undo! (single element)\n"); @@ -264,30 +363,25 @@ void interact(int width) { pop_back(gd->player_route); } - strcpy(buffer, prompt+strlen("d")); - 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; - } + + // MàJ de prompt strcpy(buffer, prompt+strlen("z")); ltrim(prompt, buffer); } else { + // afficher un message d'erreur printf("Unrecognized command : '%s'!\n", prompt); - prompt[0] = '\0'; + prompt[0] = '\0'; // effacer prompt } } if (gd->player_route->last->x == gd->end[0] && gd->player_route->last->y == gd->end[1]) { - print_interactive_grid(gd); + print_interactive_grid(gd); // afficher à nouveau la grille + + // afficher un message de fin if (verify(gd)) { printf("You won!\n"); @@ -297,11 +391,13 @@ void interact(int width) printf("You lost!\n"); } + // régénérer la grille random_start(gd); refresh_grid(gd); reset_player_route(gd); } } + // Pour finir, détruire la grille delete_grid(gd); }