508 lines
12 KiB
C
508 lines
12 KiB
C
/*
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
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 <NB_BLOCS_LARGEUR ))&& ((posY >= 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 + 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 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;
|
|
|
|
}
|
|
|