controoler

mail@pastecode.io avatar
unknown
c_cpp
2 years ago
9.4 kB
1
Indexable
Never
#ifndef DSAP_CUSTOM_CONTROLLER_H
#define DSAP_CUSTOM_CONTROLLER_H

#include "ISnakeController.h"
#include "DirectionType.h"
#include "Snake.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <vector>
#include <algorithm>

bool addDanger = true;


class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game& game, size_t id);
    const Position& SnakeHead(const Game& game, const size_t id){return game.Snakes().find(id)->second.Head();};
    const std::list<Position> SnakeBodyList(const Game& game, const size_t id){return game.Snakes().find(id)->second.Body();};
    const Position& MyHead(const Game& game){return game.Center();};
    const Snake Me(const Game& game){return game.Snakes().find(1)->second;};
public:
    
        _final_angle { init_dir },
        _turnDirection { turnDirection },
        _currentDirType { DirectionType::kForward },
        _dirSymbol { AngleToSymbol(_final_angle) } {}
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection;
    DirectionType _currentDirType;
    float _final_angle;
    DirectionSymbol _dirSymbol;
    const float turn_radius =  3 * 180 / 3.1415926 + 30;

    DirectionSymbol AngleToSymbol(float);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);


    
};



DirectionType CustomController::NextDirection(const Game& game, size_t id){
    std::cout << game.Time() << ": " << game.Center().x << " " << game.Center().y  << ", Cur Direction " << game.Snakes().find(1)->second.Direction() << std::endl;
    const int radius = 100;
    Position pos = MyHead(game);
    long left = std::abs(game.FieldHeight() - pos.y);
    long right = std::abs(0 - pos.y);
    long forward = std::abs(game.FieldWidth() - pos.x);
    
    // judge snake is in front left or right
    
    
    
    
    
    std::vector<Position> danger_ = {};
    
// /////////////////////////////// tips
//    std::cout << SnakeHead(game, 1).x;
//    std::list<Position> bodyLst = SnakeBodyList(game, 2);
    
//    for (auto it = bodyLst.begin(); it != bodyLst.end(); it++) {
//        std::cout << it->x << ", " << it->y << std::endl;
//    }
//    std::cout << MyHead(game).x << " " << MyHead(game).y << std::endl;
///////////////////////////////////////////////////////////////////
    

    
    for(size_t i = 1; i < game.Snakes().size(); ++i){
        if(i == id){
            continue;
        }
        
        
//       for (auto it = bodyLst.begin(); it != bodyLst.end(); it++) {
//            long other_x = it->x;
//            long other_y = it->y;
            long other_x = SnakeHead(game, i).x;
            long other_y = SnakeHead(game, i).y;
            long new_other_x = std::cos(-(Me(game).Direction()-90)) * other_x +  std::sin(-(Me(game).Direction()-90)) * other_y;
            long new_other_y = -1 * std::sin(-(Me(game).Direction()-90)) * other_x + std::cos(-(Me(game).Direction()-90)) * other_y;
            if(new_other_y > pos.y - radius){  // if in my first or second quadrant
                
                if((pos.x + radius) > (new_other_x - radius) || (pos.x - radius) < (new_other_x + radius)){  // snake in my forward
                    std::cout << "forward!" << std::endl;
                    long temp_forward = std::abs((new_other_y - radius) - (pos.y + radius));
                    if(temp_forward < forward){
                        forward = temp_forward;
                    }
                }
                if (new_other_x > pos.x){  // right
                    if((pos.y + radius) > (new_other_y - radius) || (pos.y - radius) < (new_other_y + radius)){  // snake in my right
                        std::cout << "right!" << std::endl;
                        long temp_right = std::abs((new_other_x - radius) - (pos.x + radius));
                        if(temp_right < right){
                            right = temp_right;
                        }
                    }
                }

                if (new_other_x < pos.x){  // snake in my left
                    if((pos.y + radius) > (new_other_y - radius) || (pos.y - radius) < (new_other_y + radius)){  // snake in my left
                        std::cout << "left!" << std::endl;
                        long temp_left = std::abs((new_other_x - radius) - (pos.x + radius));
                        if(temp_left < left){
                            left = temp_left;
                        }
                    }
                }
            }

//
//        }  // end of snake i's body for loop
        
        
    }  // end of snakes for loop
    
    
    
    
    
    
    
    
    // print current status
    //////////////////////////////////////////////////////////////
//
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//    if(game.Time() == 200){
//        first = true;
//    }
    
    // first go to the bottom
//    if(first == true){
//        if(game.Snakes().find(1)->second.Direction() == 90){
//            first = false;
//            second = true;
//        }
//        return DirectionType::kRight;
//    }
    // than turn left
//    if(second == true){
//        if(game.Center().y > 2300 && game.Snakes().find(1)->second.Direction() > 0){
//            return DirectionType::kLeft;
//        }
//    }
   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
//    if(dir_sum < -360 || dir_sum > 360){
//        return DirectionType::kForward;
//    }
//    long XSAVE_DISTANCE = 200;
//    long YSAVE_DISTANCE = 50;
//    long SNAKESAVE_DISTANCE = 50;
//    // default: right edge turn left; left edge turn right
//    if(game.Center().y < 125 && game.Snakes().find(1)->second.Direction() == -180){
//        reverse = true;
//    }
//
//
//    if(reverse == true){
//
//
//        if(game.Center().x + XSAVE_DISTANCE > game.FieldWidth()){
////            std::cout << "1) Edge" << std::endl;
//            return DirectionType::kRight;
//        }
//        // if collide with left edge
//        if(game.Center().x - XSAVE_DISTANCE < 0){
////            std::cout << "2) Edge" << std::endl;
//            return DirectionType::kLeft;
//        }
////                for(size_t i = 1; i < game.Snakes().size(); ++i){
////                    if(ymin_edges[i] < game.Center().y + YSAVE_DISTANCE  && ymax_edges[i] > game.Center().y + YSAVE_DISTANCE){
////                        if(game.Center().x + SNAKESAVE_DISTANCE > xmin_edges[i] ){
////                            std::cout << "3) Snake: " << xmin_edges[i] << std::endl;
////                            return DirectionType::kRight;
////                        }
////                        if(game.Center().x - SNAKESAVE_DISTANCE < xmax_edges[i]){
////                            std::cout << "4) Snake: " << xmax_edges[i]<< std::endl;
////                            return DirectionType::kLeft;
////                        }
////                    }
////                }
//        return DirectionType::kForward;
//
//    }
//    else if(reverse == false){
//
////
//        // if collide with right edge
//        if(game.Center().x + XSAVE_DISTANCE > game.FieldWidth()){
////            std::cout << "5) Edge!" << std::endl;
//            return DirectionType::kLeft;
//        }
//        // if collide with left edge
//        if(game.Center().x - XSAVE_DISTANCE < 0){
////            std::cout << "6) Edge!" << std::endl;
//            return DirectionType::kRight;
//        }
//
//                for(size_t i = 1; i < game.Snakes().size(); ++i){
//                    if(ymin_edges[i] < game.Center().y + YSAVE_DISTANCE  && ymax_edges[i] > game.Center().y + YSAVE_DISTANCE){
//                        if(game.Center().x + SNAKESAVE_DISTANCE > xmin_edges[i]){
////                            std::cout << "7) Snake: " << xmin_edges[i] << std::endl;
//                            return DirectionType::kLeft;
//                        }
//                        if(game.Center().x - SNAKESAVE_DISTANCE < xmax_edges[i]){
////                            std::cout << "8) Snake: " << xmax_edges[i] << std::endl;
//                            return DirectionType::kRight;
//                        }
//                    }
//                }
////        std::cout << "9)Forward!" << std::endl;
    
    std::cout << "[left] " << left << ", [right] " << right << "[forward] " << forward << std::endl;
    // choose the largest one
    if(left > right && left > forward){
        return DirectionType::kLeft;
    }
    else if(right > left && right > forward){
        return DirectionType::kRight;
    }
    else{
        return DirectionType::kForward;
    }
        
}



#endif // DSAP_CUSTOM_CONTROLLER_H