/* * IAEngine.c * * Created on: 17 juin 2018 * Author: isen * * Fonction qui va définir le comportement joueur(s) "ordinateur" */ #include "playerInterface.h" #include "arenaEngine.h" #include "IAEngine.h" #include "SDL2/SDL.h" #include #include #include enum {HAUT, DROITE, BAS, GAUCHE}; #define NB_BLOCS_LARGEUR 20 #define NB_BLOCS_HAUTEUR 20 struct point { int x,y; }POINT; int IAEngine(ARENA_H_TILE* arena,PLAYER * player1, PLAYER * player2) { //Fonction avec seulement 2 joueurs, voir la gestion quand il y a 2 IA supplémentaire //Player 1 est le joueur, player 2 le bot if((player1 != NULL) & (player2 !=NULL)) { //On récupère les positions des 2 joueurs . L'IA sait où est le joueur int action; //action = FindShortestPath(player1->PositionX,player1->PositionY,player2->PositionX,player2->PositionY); action = FindPath(arena,player1,player2); printf("Tour de l'IA\n"); if(action == 5) { AttackPlayer(player1,player2); } else if ((action >= 1) && (action <= 4)) { ActionPlayer(arena,player2,action); } //On vérifie si les 2 joueurs sont à côté pour attaquer printf("Vérification position\n"); /*action = FindShortestPath(player1->PositionX,player1->PositionY,player2->PositionX,player2->PositionY); if(action == 5) { AttackPlayer(player2,player1); }*/ } return 0; } int FindPath(ARENA_H_TILE* arena,PLAYER * player1, PLAYER * player2) { int action; int compteur = 0; int minH=1000,minB=1000,minG=1000,minD=1000; int posX=0; int posY=0; //1 vers la gauche NOEUD * n1 =NULL; n1=(NOEUD*)malloc(sizeof(NOEUD)); posX = player2->PositionX -1; posY = player2->PositionY ; n1->min=3000; n1->compteur=0; n1->ParentX = player2->PositionX; n1->ParentY = player2->PositionY; if(((posX >= 0) && (posX < NB_BLOCS_LARGEUR ))&& ((posY >= 0) && (posY < NB_BLOCS_HAUTEUR))) { if(getTileTypeID(arena,posX,posY) == 0) { n1->compteur = n1->compteur+1; //direction = GAUCHE; n1=CalculatePath(arena,posX,posY,n1,player1,player2,compteur,0,minG); minG=n1->min; printf("minG = %i\n",minG); } } //1 vers le haut posX = player2->PositionX; posY = player2->PositionY - 1; if(((posX >=0) && (posX = 0) && (posY < NB_BLOCS_HAUTEUR))) { if(getTileTypeID(arena,posX,posY) == 0) { //direction = HAUT; n1=CalculatePath(arena,posX,posY,n1,player1,player2,compteur,0,minH); minH=n1->min; } } //1 vers le bas posX = player2->PositionX; posY = player2->PositionY + 1; if(((posX >= 0) && (posX < NB_BLOCS_LARGEUR ))&& ((posY >=0) && (posY < NB_BLOCS_HAUTEUR))) { if(getTileTypeID(arena,posX,posY) == 0) { //direction = BAS; n1=CalculatePath(arena,posX,posY,n1,player1,player2,compteur,0,minB); minB=n1->min; } } //1 vers la droite posX = player2->PositionX +1; posY = player2->PositionY ; if(((posX >= 0) && (posX < NB_BLOCS_LARGEUR ))&& ((posY >= 0) && (posY < NB_BLOCS_HAUTEUR))) { if(getTileTypeID(arena,posX,posY) == 0) { //direction = DROITE; n1=CalculatePath(arena,posX,posY,n1,player1,player2,compteur,0,minD); minD=n1->min; } } printf("minG = %i\n",minG); printf("minH = %i\n",minH); printf("minB = %i\n",minB); printf("minD = %i\n",minD); if(minG < minD) { if(minG < minH) { if(minG <= minB) { printf("ACTION GAUCHE 1\n"); action = 4; } else { printf("ACTION BAS 1\n"); action = 3; } } else { if(minH < minB) { printf("ACTION HAUT 1\n"); action = 1; } else { printf("ACTION BAS 2\n"); action = 3; } } } else { if(minD < minH) { if(minD < minB) { printf("ACTION DROITE 1\n"); action = 2; } else { printf("ACTION BAS 3\n"); action = 3; } } else { if(minH < minB) { printf("ACTION HAUT 2\n"); action = 1; } else { printf("ACTION BAS 4\n"); action = 3; } } } free(n1); return action; } int distance(int x1, int y1, int x2, int y2) { /* distance euclidienne */ int distX = abs(x2-x1); int distY = abs(y2-y1); return distX + distY; /* carré de la distance euclidienne */ /* return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2); */ } NOEUD * CalculatePath(ARENA_H_TILE* arena,int posX, int posY,NOEUD * n1,PLAYER * player1,PLAYER * player2, int compteur, int dist,int min) { int ID; if(((posX - 1 >= 0) && (posX - 1 < NB_BLOCS_LARGEUR ))&& ((posY >= 0) && (posY < NB_BLOCS_HAUTEUR))) { if((n1->ParentX == player1->PositionX ) && ( n1->ParentY == player1->PositionY)) { printf("n1->ParentX - 1 = %i et n1->ParentY =%i\n",n1->ParentX - 1 ,n1->ParentY); printf("RETURN N1\n"); return n1; } ID=getTileTypeID(arena,posX - 1,posY); if(( ID== 0) && (posX-1 != n1->ParentX)) { n1->ParentX = posX - 1; //Vers la gauche n1->compteur = n1->compteur + 1; //compteur = compteur + 1; printf("*****111*****\n"); printf("Position Player1 X: %i et Y: %i\n",player1->PositionX,player1->PositionY); printf("Position n1 player2 X: %i et Y: %i\n",n1->ParentX,n1->ParentY); printf("Position Player2 posX: %i et posY: %i\n",posX,posY); printf("ID de posx - 1 et posY : %i\n",ID); //while((posX - 1 != player1->PositionX) && (posY != player1->PositionY)) while((posX - 1 != player1->PositionX) || (posY != player1->PositionY)) { /*printf("*****222*****\n"); printf("Position Player1 X: %i et Y: %i\n",player1->PositionX,player1->PositionY); printf("Position n1 player2 X: %i et Y: %i\n",n1->ParentX,n1->ParentY); printf("Position Player2 posX: %i et posY: %i\n",posX,posY); printf("ID de posx - 1 et posY : %i\n",ID);*/ n1=CalculatePath(arena,posX - 1,posY,n1,player1,player2,compteur,dist,min); //Post-Traitement //Calcul du "poids" du chemin (nb de coups) dist = distance(player1->PositionX,player1->PositionY,posX - 1,posY) + n1->compteur; if(dist < n1->min) { printf("On rentre dans le min\n"); n1->min=dist; } return n1; } } } printf("n1->compteur : %i \n",n1->compteur ); printf("abs(player2->PositionX - player1->PositionY)-1 : %i \n",abs(player2->PositionX - player1->PositionY)-1 ); if(n1->compteur == abs(player2->PositionX - player1->PositionY)-1) { printf("Chemin plus court trouvé\n"); n1->min=n1->compteur; printf("n1->min : %i \n",n1->min ); return n1; } if(((posX +1 >= 0) && (posX + 1 < NB_BLOCS_LARGEUR ))&& ((posY >= 0) && (posY < NB_BLOCS_HAUTEUR))) { if((n1->ParentX == player1->PositionX ) && ( n1->ParentY == player1->PositionY)) { printf("n1->ParentX + 1 = %i et n1->ParentY =%i\n",n1->ParentX + 1 ,n1->ParentY); printf("RETURN N1\n"); return n1; } if((getTileTypeID(arena,posX + 1 ,posY) == 0) && (posX + 1 != n1->ParentX)) { n1->ParentX = posX + 1; //Vers la droite n1->compteur = n1->compteur + 1; //compteur = compteur + 1; //while((posX != player1->PositionX) && (posY != player1->PositionY)) while((posX != player1->PositionX) || (posY != player1->PositionY)) { n1=CalculatePath(arena,posX + 1,posY,n1,player1,player2,compteur,dist,min); //Post-Traitement //Calcul du "poids" du chemin (nb de coups) dist = distance(player1->PositionX,player1->PositionY,posX + 1,posY) + n1->compteur; printf("DIST = %i\n",dist); if(dist < n1->min) { n1->min=dist; } } } } printf("n1->compteur : %i \n",n1->compteur ); printf("abs(player2->PositionX - player1->PositionY)-1 : %i \n",abs(player2->PositionX - player1->PositionY)-1 ); if(n1->compteur == abs(player2->PositionX - player1->PositionY)-1) { printf("Chemin plus court trouvé\n"); n1->min=n1->compteur; return n1; } if(((posX >= 0) && (posX < NB_BLOCS_LARGEUR ))&& ((posY + 1 >=0) && (posY + 1ParentX == player1->PositionX ) && ( n1->ParentY == player1->PositionY)) { printf("n1->ParentX = %i et n1->ParentY +1 =%i\n",n1->ParentX ,n1->ParentY+1); printf("RETURN N1\n"); return n1; } if((getTileTypeID(arena,posX,posY + 1) == 0) && (posY + 1 != n1->ParentY)) { n1->ParentY = posY + 1; //Vers la bas n1->compteur = n1->compteur + 1; //compteur = compteur + 1; //while((posX != player1->PositionX) && (posY != player1->PositionY)) while((posX != player1->PositionX) || (posY != player1->PositionY)) { n1=CalculatePath(arena,posX,posY + 1,n1,player1,player2,compteur,dist,min); //Post-Traitement //Calcul du "poids" du chemin (nb de coups) dist = distance(player1->PositionX,player1->PositionY,posX,posY + 1) + n1->compteur; if(dist < n1->min) { n1->min=dist; } } } } printf("n1->compteur : %i \n",n1->compteur ); printf("abs(player2->PositionX - player1->PositionY)-1 : %i \n",abs(player2->PositionX - player1->PositionY)-1 ); if(n1->compteur == abs(player2->PositionX - player1->PositionY)-1) { printf("Chemin plus court trouvé\n"); n1->min=n1->compteur; return n1; } if(((posX >= 0) && (posX < NB_BLOCS_LARGEUR ))&& ((posY - 1 >= 0) && (posY - 1 < NB_BLOCS_HAUTEUR))) { if((n1->ParentX == player1->PositionX ) && ( n1->ParentY == player1->PositionY)) { printf("n1->ParentX = %i et n1->ParentY -1 =%i\n",n1->ParentX ,n1->ParentY - 1); printf("RETURN N1\n"); return n1; } if((getTileTypeID(arena,posX,posY-1) == 0) && (posY - 1 != n1->ParentY)) { n1->ParentY = posY - 1; //Vers la haut n1->compteur = n1->compteur + 1; //compteur = compteur + 1; //while((posX != player1->PositionX) && (posY != player1->PositionY)) while((posX != player1->PositionX) || (posY != player1->PositionY)) { n1=CalculatePath(arena,posX,posY - 1,n1,player1,player2,compteur,dist,min); //Post-Traitement //Calcul du "poids" du chemin (nb de coups) dist = distance(player1->PositionX,player1->PositionY,posX,posY - 1) + n1->compteur; if(dist < n1->min) { n1->min=dist; } } } } printf("n1->compteur : %i \n",n1->compteur ); printf("abs(player2->PositionX - player1->PositionY)-1 : %i \n",abs(player2->PositionX - player1->PositionY)-1 ); if(n1->compteur == abs(player2->PositionX - player1->PositionY)-1) { printf("Chemin plus court trouvé\n"); n1->min=n1->compteur; return n1; } printf("return n1\n"); return n1; } //Fonction de reflexion IA fonctionne mais les pierres et arbres sont bloquants int FindShortestPath(int Player1PositionX, int Player1PositionY, int Player2PositionX, int Player2PositionY) { printf("Player1PositionX : %i et Player1PositionY : %i \n",Player1PositionX,Player1PositionY); printf("Player2PositionX : %i et Player2PositionY : %i \n",Player2PositionX,Player2PositionY); int differenceX = abs(Player1PositionX - Player2PositionX); int differenceY = abs(Player1PositionY - Player2PositionY); printf("DifferenceX : %i et DifferenceY : %i \n",differenceX,differenceY); int action=0; /*if(((differenceX == 1) && (differenceY == 0)) || ((differenceX == 0) && (differenceY == 1))) { printf("Les 2 joueur sont à coté\n"); printf("Le joueur 2 va combattre\n"); action = 5; return action; }*/ if(((differenceX == 1) && (differenceY == 0)) || ((differenceX == 0) && (differenceY == 1))) { printf("Attack en cours\n"); return action = 5; } else if(differenceX > abs(Player1PositionX - (Player2PositionX - 1))) //if(differenceX > abs(Player1PositionX - (Player2PositionX - 1))) { printf("Chemin plus court sur X gauche\n"); printf("Le joueur 2 va vers la gauche\n"); action = 4; } else if(differenceX > abs(Player1PositionX - (Player2PositionX + 1))) { printf("Chemin plus court sur X droite\n"); printf("Le joueur 2 va vers la droite\n"); action = 2; } else if(differenceY > abs(Player1PositionY - (Player2PositionY + 1))) { printf("Chemin plus court sur Y\n"); printf("Le joueur 2 va vers le bas\n"); action = 3; } else if(differenceY > abs(Player1PositionY - (Player2PositionY - 1))) { printf("Chemin plus court sur Y\n"); printf("Le joueur 2 va vers le haut\n"); action = 1; } else { printf("Chemin plus long\n"); action = 0; } return action; }