diff --git a/src/entities/coach/coach.cpp b/src/entities/coach/coach.cpp index 8703452..55db1a5 100644 --- a/src/entities/coach/coach.cpp +++ b/src/entities/coach/coach.cpp @@ -88,6 +88,60 @@ float distanceToSegment(const QVector2D &point, const QVector2D &segmentStart, c } } +QVector2D Coach::findClosestObstacle(const QVector2D& start, const QVector2D& end, const QList& obstacles) { + QVector2D closestObstacle = QVector2D(getWorldMap()->maxX(), getWorldMap()->maxY()); + float minDistance = std::numeric_limits::max(); //rastrear a menor distância encontrada durante a iteração pelos obstáculos + + for (const auto& obstacle : obstacles) { + float distance = distanceToSegment(start, end, obstacle); + + if (distance <= (ROBOT_RADIUS + BALL_RADIUS) * 2.5f && distance < minDistance) { + closestObstacle = obstacle; + minDistance = distance; + } + } + + return closestObstacle; +} + +void Coach::avoidObstacle(Player *player) { + QVector2D robotPosition = player->getPosition(); + QVector2D ballPosition = getWorldMap()->ballPosition(); + const QVector2D targetPoint(4.5f, 0.0f); + //obtém a posição de todos os robôs amarelos + QList yellowPositions = getYellowPositions(); + QVector2D obstaclePosition = QVector2D (getWorldMap()->maxX(),getWorldMap()->maxY()) ; + + //todos os robôs amarelos + for (const auto& yellowPosition : yellowPositions) { + + if(distanceToSegment(yellowPosition,player->getPosition(),targetPoint) >= ROBOT_DIAMETER * 2){ + yellowPositions.removeOne(yellowPosition); + } + } + // filtra os robôs que são obstáculos para o ponto desejado + + obstaclePosition = findClosestObstacle(player->getPosition(), targetPoint, yellowPositions); + // spdlog :: info("{}",yellowPositions.length()); + if ((distanceToSegment(obstaclePosition, robotPosition, targetPoint) <= (ROBOT_DIAMETER + ROBOT_DIAMETER)) || robotPosition.distanceToPoint(obstaclePosition) <= 0.5f) { + //const QVector2D targetPoint(4.5f, 0.0f); + //calcula a direção para desviar do robô amarelo + // spdlog :: info("testando"); + QVector2D avoidanceDirection = (robotPosition - obstaclePosition * 3).normalized(); // ajustar para virar 90º + QVector2D adjustedDirection(-avoidanceDirection.y(), avoidanceDirection.x()); + QVector2D newRobotPosition = obstaclePosition + adjustedDirection * (ROBOT_DIAMETER + 3.0F) * 2.0F; //adjustedDirection + //atualiza a posição do robô + player->goTo(newRobotPosition); + + //spdlog :: info("({},{})", newRobotPosition.x(), newRobotPosition.y()); + } + else{ + player->goTo(ballPosition); + // player->stop(); + } + player->rotateTo(targetPoint); +} + QList Coach::getYellowPositions() { QList yellowPositions; for (int i = 0; i < 6; i++) { @@ -128,16 +182,22 @@ void Coach::runCoach() { } for (quint8 playerId : players.keys()){ + if(players.value(playerId).has_value()){ + if(playerId == 5){ _gk_control -> setPlayer(players.value(playerId).value()); players.value(playerId).value()->rotateTo(ballPosition); players.value(playerId).value()->dribble(true); - if(players.value(playerId).value()->getPosition().distanceToPoint(ballPosition)<=(ROBOT_RADIUS + BALL_RADIUS)){ //se a bola tiver dentro da area passa - _gk_control->pass(getPlayer(BLUE, 0).value()); - //spdlog :: info("testando"); + if(getWorldMap()->isBallInsideOurPenaltyArea(ballPosition)){ + players.value(playerId).value()->goTo(ballPosition); + + if(players.value(playerId).value()->getPosition().distanceToPoint(ballPosition)<=(ROBOT_RADIUS + BALL_RADIUS)){ //se a bola tiver dentro da area passa + _gk_control->pass(getPlayer(BLUE, 0).value()); + //spdlog :: info("testando"); + } } else { //defend @@ -158,7 +218,7 @@ void Coach::runCoach() { } } - if(playerId == 4){ + if(playerId == 4){ // defensor blue 4 _dk_control -> setDPlayer(players.value(playerId).value()); players.value(playerId).value()->dribble(true); @@ -172,13 +232,48 @@ void Coach::runCoach() { } - if(playerId == 1){ + if(playerId == 1){ //atacante lateral superior blue 1 _ak_control -> setAPlayer(players.value(playerId).value()); players.value(playerId).value()->dribble(true); if(ballPosition.x()<= 0.0f){ - _ak_control->atackposition1(); + _ak_control->attackposition1(); } + if(ballPosition.x()> 0.0f){ + _ak_control->attack1(getPlayer(BLUE, 3).value()); + } + + } + + if(playerId == 2){ + _ak_control -> setAPlayer(players.value(playerId).value()); + players.value(playerId).value()->dribble(true); + + if(ballPosition.x()<= 0.0f){ + _ak_control->attackposition2(); + } + + if(ballPosition.x()> 0.0f){ + _ak_control->attack2(getPlayer(BLUE, 3).value()); + } + + } + + if(playerId == 3){ + + _ak_control -> setAPlayer(players.value(playerId).value()); + players.value(playerId).value()->dribble(true); + + + if(ballPosition.x() == 0 && ballPosition.y() == 0){ + + _ak_control->inicial(); + + } + + if(ballPosition.x()< 0 && ballPosition.x() < 1.7) + + players.value(playerId).value()-> goTo(ballPosition); } diff --git a/src/entities/player/ak_control.cpp b/src/entities/player/ak_control.cpp index 54d559a..e6d6068 100644 --- a/src/entities/player/ak_control.cpp +++ b/src/entities/player/ak_control.cpp @@ -15,7 +15,7 @@ void ak_control::setAPlayer (Player *player) _aPlayer = player; } -void ak_control::atackposition1() +void ak_control::attackposition1() { if(_aPlayer != nullptr){ QVector2D ballPosition = _worldMap->ballPosition(); @@ -24,3 +24,140 @@ void ak_control::atackposition1() _aPlayer->rotateTo(ballPosition); } } + +void ak_control::attackposition2() +{ + if(_aPlayer != nullptr){ + QVector2D ballPosition = _worldMap->ballPosition(); + const QVector2D pontoCerto(0.2f, -1.7f); + _aPlayer->goTo(pontoCerto); + _aPlayer->rotateTo(ballPosition); + } +} + + +void ak_control::attack1(Player *Player3){ + + if(_aPlayer != nullptr){ + QVector2D ballPosition = _worldMap->ballPosition(); + _aPlayer->dribble(true); + + if(ballPosition.x() > 0.0f && ballPosition.y() >= 0.0){ + + _aPlayer->rotateTo(ballPosition); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<(ROBOT_RADIUS + BALL_RADIUS) *6){ + _aPlayer->goTo(ballPosition); + } + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<= (ROBOT_RADIUS + BALL_RADIUS)){ + QVector2D ballPosition = _worldMap->ballPosition(); + const QVector2D golposition(4.4f,0.4f); + + QVector2D targetDirection = golposition - ballPosition; //calcula a direção da bola até o alvo + _aPlayer->rotateTo(golposition); + + float playerOrientation = _aPlayer->getOrientation(); + + float targetDirectionAngle = atan2(targetDirection.y(), targetDirection.x()); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition) <= (ROBOT_RADIUS + BALL_RADIUS) && abs(playerOrientation - targetDirectionAngle) < 0.02){ + // Chuta a bola + _aPlayer->kick(6,false); + } + } + } + + } + +} + +void ak_control::attack2(Player *Player3){ + + if(_aPlayer != nullptr){ + QVector2D ballPosition = _worldMap->ballPosition(); + _aPlayer->dribble(true); + + if(ballPosition.x() > 0.0f && ballPosition.y() <= 0.0){ + + _aPlayer->rotateTo(ballPosition); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<(ROBOT_RADIUS + BALL_RADIUS) *6){ + _aPlayer->goTo(ballPosition); + } + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<= (ROBOT_RADIUS + BALL_RADIUS)){ + QVector2D ballPosition = _worldMap->ballPosition(); + const QVector2D golposition(4.4f,-0.4f); + + QVector2D targetDirection = golposition - ballPosition; //calcula a direção da bola até o alvo + _aPlayer->rotateTo(golposition); + + float playerOrientation = _aPlayer->getOrientation(); + + float targetDirectionAngle = atan2(targetDirection.y(), targetDirection.x()); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition) <= (ROBOT_RADIUS + BALL_RADIUS) && abs(playerOrientation - targetDirectionAngle) < 0.02){ + // Chuta a bola + _aPlayer->kick(6,false); + } + } + } + + } + +} + +void ak_control ::inicial(){ + + if(_aPlayer != nullptr){ + QVector2D ballPosition = _worldMap->ballPosition(); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<(ROBOT_RADIUS + BALL_RADIUS) * 8){ + _aPlayer->goTo(ballPosition); + } + + if(_aPlayer->getPosition().distanceToPoint(ballPosition) <= (ROBOT_RADIUS + BALL_RADIUS)){ + _aPlayer->kick(6.0f, false); + } + + } + +} + +void ak_control::attack3(Player *Player3){ + + if(_aPlayer != nullptr){ + QVector2D ballPosition = _worldMap->ballPosition(); + _aPlayer->dribble(true); + + if(ballPosition.x() > 0.0f && ballPosition.y() <= 0.0){ + + _aPlayer->rotateTo(ballPosition); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<(ROBOT_RADIUS + BALL_RADIUS) *6){ + _aPlayer->goTo(ballPosition); + } + + if(_aPlayer->getPosition().distanceToPoint(ballPosition)<= (ROBOT_RADIUS + BALL_RADIUS)){ + QVector2D ballPosition = _worldMap->ballPosition(); + const QVector2D golposition(4.4f,-0.4f); + + QVector2D targetDirection = golposition - ballPosition; //calcula a direção da bola até o alvo + _aPlayer->rotateTo(golposition); + + float playerOrientation = _aPlayer->getOrientation(); + + float targetDirectionAngle = atan2(targetDirection.y(), targetDirection.x()); + + if(_aPlayer->getPosition().distanceToPoint(ballPosition) <= (ROBOT_RADIUS + BALL_RADIUS) && abs(playerOrientation - targetDirectionAngle) < 0.02){ + // Chuta a bola + _aPlayer->kick(6,false); + } + } + } + + } + +} + diff --git a/src/entities/player/ak_control.h b/src/entities/player/ak_control.h index eb6cdfe..d37078c 100644 --- a/src/entities/player/ak_control.h +++ b/src/entities/player/ak_control.h @@ -11,12 +11,25 @@ class ak_control { + public: ak_control(WorldMap *worldMap); void setAPlayer(Player *player); - void atackposition1(); - void atackposition2(); + void attackposition1(); + void attackposition2(); + void attack1(Player *player3); + void attack2(Player *player3); + void attack3(Player *player3); + void attackd(); + void attacka(); + void inicial(); + + + //talvez implemente desvio + QList getYellowPositions(); + void avoidObstacle(Player *player); + QVector2D findClosestObstacle(const QVector2D& start, const QVector2D& end, const QList& obstacles); private: