bool BalleCB::actionTrou() { // Fait disparaître la balle lorsqu'elle tombe dans le trou bouger(); dx = 0; dy = 0; grille->getCase(x, y)->libere(); grille->getCase(x, y)->paint(); return false; }
void chercheObjectif(Objectif obj[], int nbObj, Couleur couleur) { static int indiceCurrentObj = 0; static bool attendFinMatch = false; int nextX, nextY; int currentX = getPosX(); int currentY = getPosY(); nextX = calculX(couleur,obj[indiceCurrentObj].nextX); nextY = obj[indiceCurrentObj].nextY; // On regarde si on a atteind le prochain objectif if ((nextX == currentX) && (nextY == currentY)) { // On a atteind le prochain objectif indiceCurrentObj++; if (indiceCurrentObj == nbObj) { // On vérifie qu'on a pas attend la fin de la liste des objectifs attendFinMatch = true; } else { nextX = calculX(couleur,obj[indiceCurrentObj].nextX); nextY = obj[indiceCurrentObj].nextY; } } // On calcule le prochain déplacement if (!attendFinMatch) { switch (obj[indiceCurrentObj].typeMvt) { case CALLER: caller(nextX, nextY); break; case AVANCER: case RECULER: case BOUGER: bouger(nextX, nextY, obj[indiceCurrentObj].typeMvt); break; case ROTATION_HORAIRE: case ROTATION_ANTI_HORAIRE: default: break; } } }
void RobotEcoAgent::faireFuite() { //En état de fuite, on perd la cible actuelle. cible = NULL; // Si on est sur une réserve, on pose la caisse if( monde->getType( getNoeud() ) == RESERVE && !getMainsVides() ) { cheminReserve.clear(); getCaisse()->setEnReserve(true); monde->getPile( getNoeud() ).push( dynamic_cast<CaisseEcoAgent*>(getCaisse()) ); deposerCaisse( getNoeud() ); } // S'il n'y a aucune directive à suivre, on calcule un nouveau chemin else if( cheminReserve.empty() ) { RobotEcoAgent* robot = NULL; CaisseEcoAgent* caisse = NULL; robot = dynamic_cast<RobotEcoAgent*>(agresseur); caisse = dynamic_cast<CaisseEcoAgent*>(agresseur); // Si l'agresseur est une caisse if(caisse != NULL) { // On calcule le chemin jusqu'à la réserve la plus proche s'il n'est pas déjà calculé if( cheminReserve.empty() ) { CHEMIN(Point) cheminTemporaire; double min = 100000; for(auto it = monde->getReserves().begin(); it != monde->getReserves().end(); ++it) { double l = AEtoile<Point>(cheminTemporaire, getNoeud(), *it, distance_euclidienne); if(l < min) { cheminReserve = cheminTemporaire; min = l; } } } } // Si l'agresseur est un robot else if(robot != NULL) { // On cherche une case vide autour de soi auto it = getNoeud()->successeurs.begin(); bool b = false; while( it != getNoeud()->successeurs.end() && !b ) { if( monde->getPlace( it->cible ) > 0 ) { cheminReserve.push_front( it->cible ); b = true; } ++it; } // Si le robot ne peut fuir nulle part, acculé, il attaque son agresseur. if( !b ) { robot->seFaireAgresser(this); } } } // On tente de suivre le chemin existant if( cheminReserve.front() != getNoeud() && monde->getPlace(cheminReserve.front()) > 0 ) { monde->changerPlace( getNoeud(), 1 ); bouger( cheminReserve.front() ); monde->changerPlace( getNoeud(), -1 ); cheminReserve.pop_front(); } }
void RobotEcoAgent::faireSatisfaction() { // Un robot avec une caisse entre les mains est entièrement satisfait : par conséquent, il ne fera rien. if( getMainsVides() ) { cheminReserve.clear(); // Si la cible actuelle est dans une réserve ou dans les bras d'un autre robot, on perd le ciblage if( cible != NULL && (!cible->getATerre() || cible->getEnReserve()) ) cible = NULL; // S'il y a une caisse sur la case actuelle, on la prend et on ne fait plus rien. auto &pile = monde->getPile( getNoeud() ); if( monde->getType( getNoeud() ) != RESERVE && !pile.empty() ) { prendreCaisse( pile.top() ); pile.pop(); cible = NULL; } else { // Si on n'a pas de cible, on en cherche une if( cible == NULL ) { CHEMIN(Point) cheminTemporaire; double min = 100000; for(auto it = monde->getObjets().begin(); it != monde->getObjets().end(); ++it) { if( (*it)->getATerre() && !(*it)->getEnReserve() ) { double l = AEtoile<Point>(cheminTemporaire, getNoeud(), (*it)->getNoeud(), distance_euclidienne); if(l < min) { cheminCaisse.clear(); cheminCaisse = cheminTemporaire; min = l; cible = *it; } } } } // Si on n'a toujours pas de cible, on cherche la réserve la plus proche et on s'y dirige // afin de ne pas trop gêner les autres robots if( cible == NULL ) { CHEMIN(Point) cheminTemporaire; double min = 100000; for(auto it = monde->getReserves().begin(); it != monde->getReserves().end(); ++it) { double l = AEtoile<Point>(cheminTemporaire, getNoeud(), *it, distance_euclidienne); if(l < min) { cheminCaisse = cheminTemporaire; min = l; } } } if( cheminCaisse.front() != getNoeud() && monde->getPlace(cheminCaisse.front()) > 0 ) { monde->changerPlace( getNoeud(), 1 ); bouger( cheminCaisse.front() ); monde->changerPlace( getNoeud(), -1 ); cheminCaisse.pop_front(); } } } }