diff --git a/Makefile b/Makefile index 18cd429..f21d0e9 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,8 @@ SRC = main.c \ get_next_line.c \ fill_array.c \ check_input.c \ - print_board.c + print_board.c \ + ai.c SRCS = $(addprefix $(P_SRC), $(SRC)) OBJS = $(patsubst $(P_SRC)%.c,$(P_OBJ)%.o,$(SRCS)) diff --git a/alcu.map b/alcu.map index 1ec63ec..0b470c6 100644 --- a/alcu.map +++ b/alcu.map @@ -2,4 +2,4 @@ 5 3 2 -1 +2 diff --git a/alum1 b/alum1 index 2db180e..31f2243 100755 Binary files a/alum1 and b/alum1 differ diff --git a/inc/alcu.h b/inc/alcu.h index 51bfcb3..a8ebfdc 100644 --- a/inc/alcu.h +++ b/inc/alcu.h @@ -18,6 +18,7 @@ char *read_file(int fd); int check_input(int fd); void print_board(int *game_state, size_t nb_line); -int *fill_array(int fd, int size); +int *fill_array(int fd, int size); +int ai(int *gamestate, int nb_line); #endif diff --git a/src/ai.c b/src/ai.c new file mode 100644 index 0000000..e5fc61d --- /dev/null +++ b/src/ai.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ai.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: dgaillet +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2026/03/28 17:22:33 by dgaillet #+# #+# */ +/* Updated: 2026/03/28 17:22:35 by dgaillet ### ########lyon.fr */ +/* */ +/* ************************************************************************** */ + +#include "alcu.h" + +static int best_to_take(int prev_should_start, int line) { + int best; + + if (prev_should_start) { + best = 2; + while (best <= line - 2) + best += 2; + } else { + best = 1; + while (best <= line - 4) { + best += 4; + } + } + return (best); +} + +static int to_play(int prev_should_start, int line) { + int goal; + goal = best_to_take(prev_should_start, line); + if (line - goal < 3) { + return (line - goal) + 1; + } else { + return (1); + } +} + +static int should_start(int prev_should_start, int line) { + if (prev_should_start && line == 1) + return (!prev_should_start); + if (prev_should_start) + return (line % 4 != 1); + else + return (line % 4 != 0); +} + +int ai(int *gamestate, int nb_line) { + int prev_should_start; + int i; + + prev_should_start = 0; + i = -1; + while (++i < nb_line && gamestate[i] != 0) { + if (i == nb_line - 1 || gamestate[i + 1] == 0) { + if (gamestate[i] == 1) + return (1); + return (to_play(prev_should_start, gamestate[i])); + } + prev_should_start = should_start(prev_should_start, gamestate[i]); + } + return (1); +} diff --git a/src/main.c b/src/main.c index f53f90d..c5840a7 100644 --- a/src/main.c +++ b/src/main.c @@ -17,31 +17,86 @@ #include "../libft/libft.h" #include "alcu.h" -int main(int argc, char *argv[]) -{ - if (argc != 2) - { +void game(int *lines, int size) { + int ai_turn = 1; + int nb_read; + int choice; + + for (int i = size - 1; i >= 0; i--) { + while (lines[i] != 0) { + char buffer[100] = ""; + // ft_putstr_fd("Player : ", 1); + // char* choice = ft_itoa(i % 2 == 0 ? 1 : 2); + // ft_putstr_fd(choice, 1); + // ft_putstr_fd("\n", 1); + if (!ai_turn) { + print_board(lines, size); + ft_putstr_fd("\nPlease choose between 1 and 3 items\n", 1); + nb_read = read(0, buffer, sizeof(buffer)); + // char *temp = NULL; + if (nb_read > 0) { + choice = ft_atoi(buffer); + // temp = ft_itoa(choice); + // ft_putstr_fd(temp, 1); + if (choice > 0 && choice < 4) { + if (choice > lines[i]) { + ft_putstr_fd("-", 1); + ft_putstr_fd("\n", 1); + ft_putstr_fd("Invalid choice\n", 1); + i++; + // free(temp); + continue; + } + lines[i] -= choice; + } else { + ft_putstr_fd("-", 1); + ft_putstr_fd("\n", 1); + ft_putstr_fd("Invalid choice\n", 1); + i++; + // free(temp); + continue; + } + } + } else { + print_board(lines, size); + ft_putstr_fd("\n", 1); + choice = ai(lines, size); + ft_putstr_fd("AI play ", 1); + ft_putnbr_fd(choice, 1); + ft_putstr_fd("\n\n", 1); + lines[i] -= choice; + } + ai_turn = ai_turn == 0; + } + } + if (!ai_turn) + ft_putstr_fd("AI win ! It will replace you\n", 1); + else + ft_putstr_fd("You win ! Well done\n", 1); +} + +int main(int argc, char *argv[]) { + if (argc != 2) { ft_putstr_fd("ERROR", 2); return (1); } int fd = open(argv[1], O_RDONLY); - if (fd == -1) - { + if (fd == -1) { ft_putstr_fd("ERROR", 2); return (1); } int size = check_input(fd); - if (size < 0) - { + if (size < 0) { ft_putstr_fd("ERROR", 2); return (1); } + close(fd); fd = open(argv[1], O_RDONLY); - int* lines = fill_array(fd, size); + int *lines = fill_array(fd, size); if (!lines) return (1); @@ -51,49 +106,7 @@ int main(int argc, char *argv[]) // } // int player = 1; - for (int i = size - 1; i >= 0; i--) - { - while (lines[i] != 0) - { - char buffer[100] = ""; - // ft_putstr_fd("Player : ", 1); - // char* choice = ft_itoa(i % 2 == 0 ? 1 : 2); - // ft_putstr_fd(choice, 1); - // ft_putstr_fd("\n", 1); - ft_putstr_fd("Please choose between 1 and 3 items\n", 1); - print_board(lines, size); - int nb_read = read(0, buffer, sizeof(buffer)); - char* temp = NULL; - if (nb_read > 0) - { - int choice = ft_atoi(buffer); - // temp = ft_itoa(choice); - // ft_putstr_fd(temp, 1); - if (choice > 0 && choice < 4) - { - if (choice > lines[i]) - { - ft_putstr_fd("-", 1); - ft_putstr_fd("\n", 1); - ft_putstr_fd("Invalid choice\n", 1); - i++; - free(temp); - continue ; - } - lines[i] -= choice; - } - else - { - ft_putstr_fd("-", 1); - ft_putstr_fd("\n", 1); - ft_putstr_fd("Invalid choice\n", 1); - i++; - free(temp); - continue ; - } - } - } - } + game(lines, size); close(fd); free(lines); return (0);