From b3ace3075f22c50c99e2f1c3004fac2bbfee2989 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Sun, 9 Nov 2014 22:19:57 +0100 Subject: Update C template IA for morpion_rec from Alexis. --- morpion_rec/NiAh/Makefile | 23 ++++++ morpion_rec/NiAh/ia.c | 50 +++++++++++++ morpion_rec/NiAh/ia.h | 15 ++++ morpion_rec/NiAh/main.c | 179 ++++++++++++++++++++++++++++------------------ morpion_rec/NiAh/main.h | 11 ++- 5 files changed, 205 insertions(+), 73 deletions(-) create mode 100644 morpion_rec/NiAh/Makefile create mode 100644 morpion_rec/NiAh/ia.c create mode 100644 morpion_rec/NiAh/ia.h diff --git a/morpion_rec/NiAh/Makefile b/morpion_rec/NiAh/Makefile new file mode 100644 index 0000000..4fb6bec --- /dev/null +++ b/morpion_rec/NiAh/Makefile @@ -0,0 +1,23 @@ +C=gcc +CFLAGS=-W -Wall -O3 +LDFLAGS=-lm +EXEC=IA-MR + +.PHONY: clean mrproper + +all: $(EXEC) + +IA-MR: ia.o main.o + $(C) main.o ia.o -o IA-MR $(LDFLAGS) + +ia.o: ia.c ia.h + $(C) -o ia.o -c ia.c $(CFLAGS) + +main.o: main.c main.h ia.o + $(C) -o main.o -c main.c $(CFLAGS) + +clean: + rm -rf *.o + +mkproper: clean + rm -rf $(EXEC) diff --git a/morpion_rec/NiAh/ia.c b/morpion_rec/NiAh/ia.c new file mode 100644 index 0000000..70533a9 --- /dev/null +++ b/morpion_rec/NiAh/ia.c @@ -0,0 +1,50 @@ +/* IA pour morpion récursif - Alexis + * ia.c + * Fonctions nécéssaires à l'intelligence artificielle */ + +#include +#include +#include "ia.h" + +Dots chooseFirstSubgrid() +{ + return V; +} + +Dots chooseFirstMove() +{ + return V; +} + +int pickUpMove(Dots grid[9][9], Boxes subgrid, Dots player, Boxes *move, Boxes firstSubgrid) +{ + int i,j; + + if(subgrid == Z) + return 1; + + // Cas général + for(i=0;i<9;i++) + { + if(grid[subgrid][i] == FREE) + { + *move = i; + return 0; + } + } + + //Cas particulier où il n'y a pas de place dans la sous-grille (car c'est la première à avoir été jouée) + for(i=0;i<9;i++) + { + for(j=0;j<9;j++) + { + if(grid[j][i] == FREE) + { + *move = i; + return 0; + } + } + } + return 1; +} + diff --git a/morpion_rec/NiAh/ia.h b/morpion_rec/NiAh/ia.h new file mode 100644 index 0000000..1174049 --- /dev/null +++ b/morpion_rec/NiAh/ia.h @@ -0,0 +1,15 @@ +/* IA pour morpion récursif - Alexis + * ia.h + * Définitions des fonctions nécéssaires à l'intelligence artificielle */ + +#ifndef IA_H +#define IA_H + +#include "main.h" + +Dots chooseFirstSubgrid(); +Dots chooseFirstMove(); +int pickUpMove(Dots grid[9][9], Boxes subgrid, Dots player, Boxes *move, Boxes firstSubgrid); + +#endif + diff --git a/morpion_rec/NiAh/main.c b/morpion_rec/NiAh/main.c index 74248c3..1cee771 100644 --- a/morpion_rec/NiAh/main.c +++ b/morpion_rec/NiAh/main.c @@ -5,7 +5,9 @@ #include #include #include +#include #include "main.h" +#include "ia.h" #define INPUT_LENGTH 50 @@ -16,16 +18,27 @@ int main() char input[INPUT_LENGTH]; float timeout; - Dots grid[9][9]; + Dots grid[9][9]; //La grille Boxes subgrid, move, firstsubgrid; int firstMove=1; + Dots won; //Si quelqu'un a gagné + Dots swon[9]; //Qui a gagné les sous-grilles ? + for(i=0;i<9;i++) for(j=0;j<9;j++) grid[i][j] = FREE; subgrid = Z; - firstsubgrid=V; + firstsubgrid=Z; + + won = FREE; // Personne n'a gagné ... + for(i=0;i<9;i++) + swon[i]=FREE; + + srand(time(NULL)); + + /* Fin des initialisation */ // Dis bonjour à Alex ... fgets(input, sizeof(input), stdin); @@ -40,9 +53,9 @@ int main() return EXIT_FAILURE; } - printGrid(grid); + printGrid(grid, swon); - // Est-ce à moi de jouer ? + // Boucle de jeu while(1) { while(1) @@ -53,6 +66,7 @@ int main() if(strstr(input,"Your turn")==input) { sscanf(input+10,"%f",&timeout); + fprintf(stderr, "Timeout: %f\n", timeout); break; } @@ -69,89 +83,84 @@ int main() firstsubgrid=subgrid; firstMove=0; } - play(grid, subgrid, CIRCLE, move); - printGrid(grid); + play(grid, subgrid, move, CIRCLE); + updateWon(grid, &won, swon, subgrid, move); + printGrid(grid, swon); subgrid=move; + if(won == CIRCLE) + fprintf(stderr, "You won :|"); } // Attendre le résultat de la partie - if(strstr(input,"You win")==input) + if(strstr(input,"You win")==input || strstr(input,"You lose")==input || strstr(input,"Tie")==input || strstr(input,"Cheater")==input) { - printf("Yeah!"); + printf("Fair enough\n"); return EXIT_SUCCESS; } - if(strstr(input,"You lose")==input) - { - printf("I am so sad..."); - return EXIT_SUCCESS; - } - if(strstr(input,"Tie")==input) - { - printf("It is a good result anyways."); - return EXIT_SUCCESS; - } - if(strstr(input,"Cheater")==input) - { - printf("You are so nasty :("); - return EXIT_FAILURE; - } - } // On joue toujours les croix if(firstMove) { - firstsubgrid=V; + firstsubgrid=chooseFirstSubgrid(); subgrid=firstsubgrid; + move=chooseFirstMove(); firstMove=0; } - if(chooseMoveAndPlay(grid, subgrid, CROSS, &move, firstsubgrid) != 0){return EXIT_FAILURE;} + else if(pickUpMove(grid, subgrid, CROSS, &move, firstsubgrid) != 0) + { + return EXIT_FAILURE; + } + + play(grid, subgrid, move, CROSS); + updateWon(grid, &won, swon, subgrid, move); printf("Play %d %d %d %d\n", subgrid%3+1, subgrid/3+1, move%3+1, move/3+1); subgrid=move; - printGrid(grid); + printGrid(grid, swon); + if(won==CROSS) + fprintf(stderr, "I won !!"); } - return EXIT_SUCCESS; } -int play(Dots grid[9][9], Boxes subgrid, Dots player, Boxes move) +// Joue un coup sur la grille +int play(Dots grid[9][9], Boxes subgrid, Boxes move, Dots player) { if(subgrid == Z || move == Z || player == FREE || grid[subgrid][move] != FREE) return 1; grid[subgrid][move] = player; + return 0; } -int chooseMoveAndPlay(Dots grid[9][9], Boxes subgrid, Dots player, Boxes *move, Boxes firstSubgrid) + +// Les affichages se font dans stderr +void printGrid(Dots grid[9][9], Dots swon[9]) { - int i,j; - Boxes sg = (subgrid!=Z) ? subgrid : V; // Inutile maintenant - for(i=0;i<9;i++) + int x,y, i,j; + + fprintf(stderr,"\n*********\n"); + for(x=0;x<9;x++) { - if(grid[sg][i] == FREE) + for(y=0;y<9;y++) { - *move = i; - grid[sg][i] = player; - return 0; + i=(y/3)*3+(x/3); + j=(y-(y/3)*3)*3+(x-(x/3)*3); + fprintf(stderr,"%d", grid[i][j]); } + fprintf(stderr,"\n"); } - if(firstSubgrid=subgrid) + fprintf(stderr,"*********\n"); + for(x=0;x<3;x++) { - for(i=0;i<9;i++) + for(y=0;y<3;y++) { - for(j=0;j<9;j++) - { - if(grid[j][i] == FREE) - { - *move = i; - grid[j][i] = player; - return 0; - } - } + fprintf(stderr, "%d", swon[x+3*y]); } + fprintf(stderr, "\n"); } - return 1; + fprintf(stderr,"*********\n"); } void checkSolutions(Boxes a, Solutions sols) @@ -161,7 +170,7 @@ void checkSolutions(Boxes a, Solutions sols) case I: sols[0][0] = II; sols[0][1] = III; sols[1][0] = IV; sols[1][1] = VII; - sols[2][0] = Z; sols[2][1] = Z; + sols[2][0] = V; sols[2][1] = IX; sols[3][0] = Z; sols[3][1] = Z; break; case II: @@ -173,7 +182,7 @@ void checkSolutions(Boxes a, Solutions sols) case III: sols[0][0] = I; sols[0][1] = II; sols[1][0] = VI; sols[1][1] = IX; - sols[2][0] = Z; sols[2][1] = Z; + sols[2][0] = V; sols[2][1] = VII; sols[3][0] = Z; sols[3][1] = Z; break; case IV: @@ -196,20 +205,20 @@ void checkSolutions(Boxes a, Solutions sols) break; case VII: sols[0][0] = I; sols[0][1] = IV; - sols[1][0] = VII; sols[1][1] = IX; - sols[2][0] = Z; sols[2][1] = Z; + sols[1][0] = VIII; sols[1][1] = IX; + sols[2][0] = V; sols[2][1] = III; sols[3][0] = Z; sols[3][1] = Z; break; case VIII: sols[0][0] = II; sols[0][1] = V; - sols[1][0] = VI; sols[1][1] = IX; + sols[1][0] = VII; sols[1][1] = IX; sols[2][0] = Z; sols[2][1] = Z; sols[3][0] = Z; sols[3][1] = Z; break; case IX: sols[0][0] = III; sols[0][1] = VI; - sols[1][0] = VII; sols[2][1] = IX; - sols[2][0] = Z; sols[2][1] = Z; + sols[1][0] = VII; sols[1][1] = VIII; + sols[2][0] = I; sols[2][1] = V; sols[3][0] = Z; sols[3][1] = Z; break; default: @@ -221,23 +230,53 @@ void checkSolutions(Boxes a, Solutions sols) } } -// Les affichages se font dans stderr -void printGrid(Dots grid[9][9]) +void updateWon(Dots grid[9][9], Dots *won, Dots swon[9], Boxes subgrid, Boxes move) { - int x,y, i,j; + int i; + Dots player = grid[subgrid][move]; + Solutions sols; - fprintf(stderr,"\n*********\n"); - for(x=0;x<9;x++) + fprintf(stderr, "Start update\n"); + + //Si la sous-grille n'est pas déja attribuée ... + if(swon[subgrid] != FREE) + return; + + // On vérifie d'abord la petite grille + checkSolutions(move, sols); + fprintf(stderr, "For %d %d: ", subgrid, move); + for(i=0;i<4;i++) { - for(y=0;y<9;y++) + if(sols[i][0]==Z) + break; + + if(grid[subgrid][ sols[i][0] ] == player && grid[subgrid][ sols[i][1] ] == player) { - i=(y/3)*3+(x/3); - j=(y-(y/3)*3)*3+(x-(x/3)*3); - fprintf(stderr,"%d", grid[i][j]); + fprintf(stderr, "check %d %d -> OK ; ", sols[i][0], sols[i][1]); + swon[subgrid] = player; + break; } - fprintf(stderr,"\n"); - } - fprintf(stderr,"\n*********\n"); + else + fprintf(stderr, "check %d %d -> Fail ; ", sols[i][0], sols[i][1]); + } + // On vérifie ensuite la grande grille si besoin + if(swon[subgrid] == player) + { + fprintf(stderr, "\nFor %d: ", subgrid); + checkSolutions(subgrid, sols); + for(i=0;i<4;i++) + { + if(sols[i][0] == Z) + break; + if(swon[ sols[i][0] ] == player && swon[ sols[i][1] ] == player) + { + fprintf(stderr, "check %d %d -> OK ; ", sols[i][0], sols[i][1]); + *won = player; + break; + } + else + fprintf(stderr, "check %d %d -> Fail ; ", sols[i][0], sols[i][1]); + } + } + fprintf(stderr, "\nEnd update\n"); } - - diff --git a/morpion_rec/NiAh/main.h b/morpion_rec/NiAh/main.h index 5cf06d2..5942256 100644 --- a/morpion_rec/NiAh/main.h +++ b/morpion_rec/NiAh/main.h @@ -2,12 +2,17 @@ * main.h * Définition des énumérations, typedef et autres */ +#ifndef MAIN_H +#define MAIN_H + typedef enum {FREE, CROSS, CIRCLE} Dots; typedef enum {I=0, II=1, III=2, IV = 3, V=4, VI=5, VII=6, VIII=7, IX=8, Z=-1} Boxes; typedef Boxes Solutions[4][2]; -int play(Dots grid[9][9], Boxes subgrid, Dots player, Boxes move); -int chooseMoveAndPlay(Dots grid[9][9], Boxes subgrid, Dots player, Boxes *move, Boxes firstSubgrid); +int play(Dots grid[9][9], Boxes subgrid, Boxes move, Dots player); +void printGrid(Dots grid[9][9], Dots swon[9]); void checkSolutions(Boxes a, Solutions sols); -void printGrid(Dots grid[9][9]); +void updateWon(Dots grid[9][9], Dots *won, Dots swon[9], Boxes subgrid, Boxes move); + +#endif -- cgit v1.2.3