---
# System prepended metadata

title: here version what the fuck

---

### version WhereCanGo
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int circirling_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistanceForNoSnake(DirectionSymbol, const Game&, size_t);
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType WhereCanGo(Position, DirectionSymbol, const Game&, size_t);
};
DirectionType CustomController::WhereCanGo(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id)
{
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;
        for (const Position& pos : anotherSnake.Body()) {

            if (dirSymbol == DirectionSymbol::UP) {

                if (abs(snakePos.x - pos.x) < turn_radius * 2 && pos.x > snakePos.x && abs(snakePos.y - pos.y) < turn_radius * 2 ) {
                    return DirectionType::kLeft;
                }
                else if (abs(snakePos.x - pos.x) < turn_radius * 2 && pos.x < snakePos.x && abs(snakePos.y - pos.y) < turn_radius * 2 ) {
                    return DirectionType::kRight;
                }
            }
            if (dirSymbol == DirectionSymbol::DOWN) {

                if (abs(snakePos.x - pos.x) < turn_radius * 2 && pos.x > snakePos.x && abs(snakePos.y - pos.y) < turn_radius * 2 ) {
                    return DirectionType::kRight;
                }
                else if (abs(snakePos.x - pos.x) < turn_radius * 2 && pos.x < snakePos.x && abs(snakePos.y - pos.y) < turn_radius * 2 ) {
                    return DirectionType::kLeft;
                }
            }
            if (dirSymbol == DirectionSymbol::LEFT) {
            	if (abs(snakePos.y - game.FieldHeight()) < turn_radius * 2)
			    {
			            return DirectionType::kRight;
			    }
                if (abs(snakePos.x - pos.x) < turn_radius * 2  && abs(snakePos.y - pos.y) < turn_radius * 2 && snakePos.y > pos.y) 
                {
                	return DirectionType::kLeft;
				}
                else if(abs(snakePos.x - pos.x) < turn_radius * 2  && abs(snakePos.y - pos.y) < turn_radius * 2 && snakePos.y < pos.y)
                {
                	  	return DirectionType::kRight;
				}
            }
            if (dirSymbol == DirectionSymbol::RIGHT) {

                if (abs(snakePos.x - pos.x) < turn_radius * 2 && abs(snakePos.y - pos.y) < turn_radius * 2 && pos.y > snakePos.y) {
                    return DirectionType::kLeft;
                }
                else if(abs(snakePos.x - pos.x) < turn_radius * 2  && abs(snakePos.y - pos.y) < turn_radius * 2 && snakePos.y < pos.y)
                {
                	return DirectionType::kRight;
				}
            }
        }

    }
    //std::cout << "test" << std::endl;

    if (snakePos.y - 0 < turn_radius * 2)
    {
        if (_dirSymbol == DirectionSymbol::RIGHT)
            return DirectionType::kRight;
        else if (_dirSymbol == DirectionSymbol::LEFT)
            return DirectionType::kLeft;
    }
    else if (abs(snakePos.y - game.FieldHeight()) < turn_radius * 2)
    {
        if (_dirSymbol == DirectionSymbol::RIGHT)
            return DirectionType::kLeft;
        else if (_dirSymbol == DirectionSymbol::LEFT)
            return DirectionType::kRight;
    }
    return _turnDirection;
}
int CustomController::howManySnake(const Game& game) {
    int amount = 0;
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    if (howManySnake(game) == 1) // for test_A
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistanceForNoSnake(_dirSymbol, game, id);

        if (distance > 0 && distance * 1.2 < turn_radius + circirling_times * 39.25) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            circirling_times++;

        }
        else {
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else // other condition
    {
        // if is turning around
        // keep turning
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(snake.Head(), _dirSymbol, game, id);

		
        // if 0 < distance < min_distance
        if (distance > 0 && distance < turn_radius * 1.5) {
        	
//			if(_turnDirection == DirectionType::kRight)
//				std::cout <<"right" <<std::endl;
//			else if (_turnDirection == DirectionType::kLeft)
//				std::cout <<"left" <<std::endl;
//			else 
//				std::cout <<"forward" <<std::endl;		
            // start turning around
//            if(_turnDirection == WhereCanGo(snake.Head(), _dirSymbol, game, id))
//            {	
//            	if(_turnDirection == DirectionType::kRight)
//					_turnDirection = DirectionType::kLeft;
//				else if(_turnDirection == DirectionType::kLeft)
//					_turnDirection = DirectionType::kRight;
//			}
//			else

			_turnDirection = WhereCanGo(snake.Head(), _dirSymbol, game, id);
            _currentDirType = _turnDirection;
            if (_currentDirType == DirectionType::kRight) {
                _final_angle = snake.Direction() + 90;
                //_turnDirection = DirectionType::kLeft;
            }
            else if (_currentDirType == DirectionType::kLeft) {
                _final_angle = snake.Direction() - 90;
                //_turnDirection = DirectionType::kRight;
            }
            
        }
        else {
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
}
float CustomController::GetCollisionDistanceForNoSnake(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());

    // check front collision distance with other snakes
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2

        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                }
            }

        }

    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    angle = int(angle) % 360;
    if(angle < 0)
        angle += 360;
    
    if (int(angle) % 90 != 0) {
        return DirectionSymbol::NONE;
    }
    // can be converted into 4 directions
    int dir = abs(angle / 90);
    dir %= 4;
    return static_cast<DirectionSymbol>(dir);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }

        return distanceY;
    }
    return -1;
}
```
# here version what the fuck
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType Radar(Position, DirectionSymbol, Game, size_t);
    float distance_cal(Position, Position);
    int radar[5][5];
};

DirectionType CustomController::Radar(Position snakeHead, DirectionSymbol _dirSymbol, Game game, size_t id){
    float radar_range = turn_radius;
    for(int i = 0;i < 5;i++)
        for(int j = 0;j < 5;j++)
            radar[i][j] = 0;
    Position starting_point;
    starting_point.x = snakeHead.x - 2*radar_range;
    starting_point.y = snakeHead.y - 2*radar_range;
    for(int i = 0; i < 5;i++){
        for(int j = 0; j < 5;j++){
            if(game.FieldWidth() - starting_point.x - j*radar_range < radar_range || starting_point.x + j*radar_range < radar_range){
                radar[i][j] = 1;
            }else if(game.FieldHeight() - starting_point.y - i*radar_range < radar_range || starting_point.y + i*radar_range < radar_range){
                radar[i][j] = 1;
            }
        }
    }
    
    std :: map<size_t, Snake> snakes = game.Snakes();
    for(int i = 0;i < snakes.size();i++){
        std :: list<Position> body = snakes[i].Body();
        if(snakeHead.x == snakes[i].Head().x && snakeHead.y == snakes[i].Head().y ){
            continue;
        }
        for(Position p : body){
            for(int k = 0; k < 5;k++){
                for(int r = 0; r < 5;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, p) < radar_range - game.kSnakeRadius){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }
//
    if(_dirSymbol == DirectionSymbol::RIGHT){
        radar[2][2] = 2, radar[2][1] = 2, radar[2][0] = 2;
        int n = 5;
        for(int i=0;i<n/2;i++){
           for(int j=i;j<n-i-1;j++)
           {
             // Swapping elements after each iteration in Anticlockwise direction
               int temp=radar[i][j];
               radar[i][j]=radar[j][n-i-1];
               radar[j][n-i-1]=radar[n-i-1][n-j-1];
               radar[n-i-1][n-j-1]=radar[n-j-1][i];
               radar[n-j-1][i]=temp;
           }
        }

    }else if(_dirSymbol == DirectionSymbol::DOWN){
        radar[0][2] = 2, radar[1][2] = 2, radar[2][2] = 2;
        for(int q = 0; q < 2;q++){
            //Tranposing the matrix
            for(int i=0; i<5; i++){
              for(int j=i+1; j<5; j++)
                  std :: swap(radar[i][j], radar[j][i]);
             }

            //Reversing each row of the matrix
            for(int i=0; i<5; i++){
              for(int j=0; j<5/2; j++){
                 std :: swap(radar[i][j], radar[i][5-j-1]);
              }
            }
        }
    }else if(_dirSymbol == DirectionSymbol::LEFT){
        //Tranposing the matrix
        radar[2][2] = 2, radar[2][3] = 2, radar[2][4] = 2;
        for(int i=0; i<5; i++){
          for(int j=i+1; j<5; j++)
              std :: swap(radar[i][j], radar[j][i]);
         }

        //Reversing each row of the matrix
        for(int i=0; i<5; i++){
          for(int j=0; j<5/2; j++){
             std :: swap(radar[i][j], radar[i][5-j-1]);
          }
        }
    }else{
        radar[2][2] = 2, radar[3][2] = 2, radar[4][2] = 2;
    }
    
//        for(int i = 0;i < 5;i++){
//            for(int j = 0;j < 5;j++){
//                std :: cout << radar[i][j] << " ";
//            }
//            std :: cout << std :: endl;
//        }
//        std :: cout << std :: endl;

    
    //forward left right
    bool dir[3] = {true, true, true};
    if(radar[1][0] == 1 || radar[1][1] == 1){
        dir[1] = false;
    }
    if(radar[1][3] == 1 || radar[1][4] == 1){
        dir[2] = false;
    }
    if(radar[0][2] == 1 || radar[1][2] == 1){
        dir[0] = false;
    }
    //define dead-end
    if(dir[0]){
        if(radar[0][1] == 1 || radar[0][3] == 1){
            dir[0] = false;
        }
    }
    

    
    if(dir[0]){
        //not in danger
        return DirectionType::kForward;
    }else{
        if(dir[2]){
            return DirectionType::kRight;
        }else if(dir[1]){
            return DirectionType::kLeft;
        }else{
            return DirectionType::kForward;
        }
    }
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
        Radar(snake.Head(), _dirSymbol, game, id);
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
//
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        _currentDirType = DirectionType::kForward;
        _currentDirType = Radar(snake.Head(), _dirSymbol, game, id);
        if(_currentDirType == DirectionType::kRight){
            _final_angle = snake.Direction() + 90;
        }else if(_currentDirType == DirectionType::kLeft){
            _final_angle = snake.Direction() - 90;
        }
        return _currentDirType;
    }
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    // check front collision distance with other snakes
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                }
            }

        }

    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    if (int(angle) % 90 != 0) {
        return DirectionSymbol::NONE;
    }
    angle = int(angle) % 360;
    if(angle < 0){
        angle += 360;
    }
    // can be converted into 4 directions
    return static_cast<DirectionSymbol>(angle/90);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }

        return distanceY;
    }
    return -1;
}
float CustomController::distance_cal(Position a, Position b){
    float ans = pow((a.x - b.x),2) + pow((a.y - b.y), 2);
    ans = sqrt(ans);
    return ans;
}
```
# another fuck
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType Radar(Position, DirectionSymbol, Game, size_t);
    float distance_cal(Position, Position);
    int radar[5][5];
};

DirectionType CustomController::Radar(Position snakeHead, DirectionSymbol _dirSymbol, Game game, size_t id){
    float radar_range = turn_radius;
    for(int i = 0;i < 5;i++)
        for(int j = 0;j < 5;j++)
            radar[i][j] = 0;
    Position starting_point;
    starting_point.x = snakeHead.x - 2*radar_range;
    starting_point.y = snakeHead.y - 2*radar_range;
    for(int i = 0; i < 5;i++){
        for(int j = 0; j < 5;j++){
            if(game.FieldWidth() - starting_point.x - j*radar_range < radar_range || starting_point.x + j*radar_range < radar_range){
                radar[i][j] = 1;
            }else if(game.FieldHeight() - starting_point.y - i*radar_range < radar_range || starting_point.y + i*radar_range < radar_range){
                radar[i][j] = 1;
            }
        }
    }
    
    std :: map<size_t, Snake> snakes = game.Snakes();
    for(int i = 0;i < snakes.size();i++){
        std :: list<Position> body = snakes[i].Body();
        if(snakeHead.x == snakes[i].Head().x && snakeHead.y == snakes[i].Head().y ){
            continue;
        }
        for(Position p : body){
            for(int k = 0; k < 5;k++){
                for(int r = 0; r < 5;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, p) < radar_range - game.kSnakeRadius){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }
//
    bool dir[3] = {true, true, true};
    if(_dirSymbol == DirectionSymbol::RIGHT){
        radar[2][2] = 2, radar[2][1] = 2, radar[2][0] = 2;
        if(radar[0][3] == 1 || radar[1][3] == 1){
            dir[1] = false;
        }
        if(radar[3][3] == 1 || radar[4][3] == 1){
            dir[2] = false;
        }
        if(radar[2][4] == 1 || radar[2][3] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][4] == 1 || radar[3][4] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::DOWN){
        radar[0][2] = 2, radar[1][2] = 2, radar[2][2] = 2;
        if(radar[3][3] == 1 || radar[3][4] == 1){
            dir[1] = false;
        }
        if(radar[3][0] == 1 || radar[3][1] == 1){
            dir[2] = false;
        }
        if(radar[3][2] == 1 || radar[4][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[4][1] == 1 || radar[4][3] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::LEFT){
        //Tranposing the matrix
        radar[2][2] = 2, radar[2][3] = 2, radar[2][4] = 2;
        if(radar[3][1] == 1 || radar[4][1] == 1){
            dir[1] = false;
        }
        if(radar[0][1] == 1 || radar[1][1] == 1){
            dir[2] = false;
        }
        if(radar[2][0] == 1 || radar[2][1] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][0] == 1 || radar[3][0] == 1){
                dir[0] = false;
            }
        }
    }else{
        radar[2][2] = 2, radar[3][2] = 2, radar[4][2] = 2;
        if(radar[1][0] == 1 || radar[1][1] == 1){
            dir[1] = false;
        }
        if(radar[1][3] == 1 || radar[1][4] == 1){
            dir[2] = false;
        }
        if(radar[0][2] == 1 || radar[1][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[0][1] == 1 || radar[0][3] == 1){
                dir[0] = false;
            }
        }
    }
    
//        for(int i = 0;i < 5;i++){
//            for(int j = 0;j < 5;j++){
//                std :: cout << radar[i][j] << " ";
//            }
//            std :: cout << std :: endl;
//        }
//        std :: cout << std :: endl;

    
    //forward left right

    
    if(dir[0]){
        //not in danger
        return DirectionType::kForward;
    }else{
        if(dir[2]){
            return DirectionType::kRight;
        }else if(dir[1]){
            return DirectionType::kLeft;
        }else{
            return DirectionType::kForward;
        }
    }
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
        Radar(snake.Head(), _dirSymbol, game, id);
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
//
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        _currentDirType = DirectionType::kForward;
        _currentDirType = Radar(snake.Head(), _dirSymbol, game, id);
        if(_currentDirType == DirectionType::kRight){
            _final_angle = snake.Direction() + 90;
        }else if(_currentDirType == DirectionType::kLeft){
            _final_angle = snake.Direction() - 90;
        }
        return _currentDirType;
    }
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    // check front collision distance with other snakes
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                }
            }

        }

    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    if (int(angle) % 90 != 0) {
        return DirectionSymbol::NONE;
    }
    angle = int(angle) % 360;
    if(angle < 0){
        angle += 360;
    }
    // can be converted into 4 directions
    return static_cast<DirectionSymbol>(angle/90);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }

        return distanceY;
    }
    return -1;
}
float CustomController::distance_cal(Position a, Position b){
    float ans = pow((a.x - b.x),2) + pow((a.y - b.y), 2);
    ans = sqrt(ans);
    return ans;
}
```

# version might be a little fucking quicker
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType Radar(Position, DirectionSymbol, Game, size_t);
    float distance_cal(Position, Position);
    DirectionType safeDirection(const Snake& snake, const Game&);
    int radar[5][5];
};

DirectionType CustomController::safeDirection(const Snake& snake, const Game& game){
    const auto& head = snake.Head();
    const auto& directions = {DirectionSymbol::RIGHT, DirectionSymbol::LEFT};
    const auto& dir = {DirectionType::kRight, DirectionType::kLeft};
    std :: vector<float> distances;
    for(const auto& direction : directions){
        distances.push_back(GetCollisionDistance(head, direction, game, snake.Id()));
    }
    if(distances[0] >= distances[1]){
        return DirectionType::kRight;
    }else{
        return DirectionType::kLeft;
    }
}

DirectionType CustomController::Radar(Position snakeHead, DirectionSymbol _dirSymbol, Game game, size_t id){
    float radar_range = turn_radius;
    for(int i = 0;i < 5;i++)
        for(int j = 0;j < 5;j++)
            radar[i][j] = 0;
    Position starting_point;
    starting_point.x = snakeHead.x - 2*radar_range;
    starting_point.y = snakeHead.y - 2*radar_range;
    for(int i = 0; i < 5;i++){
        for(int j = 0; j < 5;j++){
            if(game.FieldWidth() - starting_point.x - j*radar_range < radar_range || starting_point.x + j*radar_range < radar_range){
                radar[i][j] = 1;
            }else if(game.FieldHeight() - starting_point.y - i*radar_range < radar_range || starting_point.y + i*radar_range < radar_range){
                radar[i][j] = 1;
            }
        }
    }
    
    std :: map<size_t, Snake> snakes = game.Snakes();
    for(int i = 0;i < snakes.size();i++){
        std :: list<Position> body = snakes[i].Body();
        if(snakeHead.x == snakes[i].Head().x && snakeHead.y == snakes[i].Head().y ){
            continue;
        }
        for(Position p : body){
            if(_dirSymbol == DirectionSymbol::RIGHT){
                for(int k = 0; k < 5;k++){
                    for(int r = 2; r < 5;r++){
                        Position center;
                        center.x = starting_point.x + r*radar_range;
                        center.y = starting_point.y + k*radar_range;
                        if(distance_cal(center, p) < pow((radar_range - game.kSnakeRadius),2)){
                            radar[k][r] = 1;
                        }
                    }
                }
            }else if(_dirSymbol == DirectionSymbol::DOWN){
                for(int k = 2; k < 5;k++){
                    for(int r = 2; r < 5;r++){
                        Position center;
                        center.x = starting_point.x + r*radar_range;
                        center.y = starting_point.y + k*radar_range;
                        if(distance_cal(center, p) < pow((radar_range - game.kSnakeRadius),2)){
                            radar[k][r] = 1;
                        }
                    }
                }
            }else if(_dirSymbol == DirectionSymbol::LEFT){
                //Tranposing the matrix
                for(int k = 0; k < 5;k++){
                    for(int r = 2; r < 3;r++){
                        Position center;
                        center.x = starting_point.x + r*radar_range;
                        center.y = starting_point.y + k*radar_range;
                        if(distance_cal(center, p) < pow((radar_range - game.kSnakeRadius),2)){
                            radar[k][r] = 1;
                        }
                    }
                }

            }else{
                for(int k = 0; k < 3;k++){
                    for(int r = 0; r < 5;r++){
                        Position center;
                        center.x = starting_point.x + r*radar_range;
                        center.y = starting_point.y + k*radar_range;
                        if(distance_cal(center, p) < pow((radar_range - game.kSnakeRadius),2)){
                            radar[k][r] = 1;
                        }
                    }
                }
            }
        }
    }
//
    bool dir[3] = {true, true, true};
    if(_dirSymbol == DirectionSymbol::RIGHT){
        radar[2][2] = 2, radar[2][1] = 2, radar[2][0] = 2;
        if(radar[0][3] == 1 || radar[1][3] == 1){
            dir[1] = false;
        }
        if(radar[3][3] == 1 || radar[4][3] == 1){
            dir[2] = false;
        }
        if(radar[2][4] == 1 || radar[2][3] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][4] == 1 || radar[3][4] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::DOWN){
        radar[0][2] = 2, radar[1][2] = 2, radar[2][2] = 2;
        if(radar[3][3] == 1 || radar[3][4] == 1){
            dir[1] = false;
        }
        if(radar[3][0] == 1 || radar[3][1] == 1){
            dir[2] = false;
        }
        if(radar[3][2] == 1 || radar[4][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[4][1] == 1 || radar[4][3] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::LEFT){
        //Tranposing the matrix
        radar[2][2] = 2, radar[2][3] = 2, radar[2][4] = 2;
        if(radar[3][1] == 1 || radar[4][1] == 1){
            dir[1] = false;
        }
        if(radar[0][1] == 1 || radar[1][1] == 1){
            dir[2] = false;
        }
        if(radar[2][0] == 1 || radar[2][1] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][0] == 1 || radar[3][0] == 1){
                dir[0] = false;
            }
        }
    }else{
        radar[2][2] = 2, radar[3][2] = 2, radar[4][2] = 2;
        if(radar[1][0] == 1 || radar[1][1] == 1){
            dir[1] = false;
        }
        if(radar[1][3] == 1 || radar[1][4] == 1){
            dir[2] = false;
        }
        if(radar[0][2] == 1 || radar[1][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[0][1] == 1 || radar[0][3] == 1){
                dir[0] = false;
            }
        }
    }
    
//        for(int i = 0;i < 5;i++){
//            for(int j = 0;j < 5;j++){
//                std :: cout << radar[i][j] << " ";
//            }
//            std :: cout << std :: endl;
//        }
//        std :: cout << std :: endl;

    
    //forward left right

    
    if(dir[0]){
        //not in danger
        return DirectionType::kForward;
    }else{
        if(dir[2] && dir[1]){
//            return safeDirection(game.Snakes().at(id), game);
            return DirectionType::kRight;
        }else if(dir[1]){
            return DirectionType::kLeft;
        }else if(dir[2]){
            return DirectionType::kRight;
        }
    }
    return DirectionType::kForward;
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
        Radar(snake.Head(), _dirSymbol, game, id);
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
//
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        _currentDirType = DirectionType::kForward;
        _currentDirType = Radar(snake.Head(), _dirSymbol, game, id);
        if(_currentDirType == DirectionType::kRight){
            _final_angle = snake.Direction() + 90;
        }else if(_currentDirType == DirectionType::kLeft){
            _final_angle = snake.Direction() - 90;
        }
        return _currentDirType;
    }
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    // check front collision distance with other snakes
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                }
            }

        }

    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    if (int(angle) % 90 != 0) {
        return DirectionSymbol::NONE;
    }
    angle = int(angle) % 360;
    if(angle < 0){
        angle += 360;
    }
    // can be converted into 4 directions
    return static_cast<DirectionSymbol>(angle/90);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }

        return distanceY;
    }
    return -1;
}
float CustomController::distance_cal(Position a, Position b){
    float ans = pow((a.x - b.x),2) + pow((a.y - b.y), 2);
//    ans = sqrt(ans);
    return ans;
}
```

# last dance 
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType Radar(Position, DirectionSymbol, Game, size_t, Snake);
    float distance_cal(Position, Position);
    DirectionType safeDirection(const Snake& snake, const Game&);
    int radar[5][5];
};

DirectionType CustomController::Radar(Position snakeHead, DirectionSymbol _dirSymbol, Game game, size_t id, Snake snake){
    float radar_range = turn_radius;
    for(int i = 0;i < 5;i++)
        for(int j = 0;j < 5;j++)
            radar[i][j] = 0;
    Position starting_point;
    starting_point.x = snakeHead.x - 2*radar_range;
    starting_point.y = snakeHead.y - 2*radar_range;
    for(int i = 0; i < 5;i++){
        for(int j = 0; j < 5;j++){
            if(game.FieldWidth() - starting_point.x - j*radar_range < radar_range || starting_point.x + j*radar_range < radar_range){
                radar[i][j] = 1;
            }else if(game.FieldHeight() - starting_point.y - i*radar_range < radar_range || starting_point.y + i*radar_range < radar_range){
                radar[i][j] = 1;
            }
        }
    }
    
    GetCollisionDistance(snakeHead, _dirSymbol, game, id);
    GetCollisionDistance(snakeHead, AngleToSymbol(snake.Direction()+90), game, id);
    GetCollisionDistance(snakeHead, AngleToSymbol(snake.Direction()-90), game, id);
    
    bool dir[3] = {true, true, true};
    if(_dirSymbol == DirectionSymbol::RIGHT){
        radar[2][2] = 2, radar[2][1] = 2, radar[2][0] = 2;
        if(radar[0][3] == 1 || radar[1][3] == 1 || radar[1][2] == 1){
            dir[1] = false;
        }
        if(radar[3][3] == 1 || radar[4][3] == 1 || radar[3][2] == 1){
            dir[2] = false;
        }
        if(radar[2][4] == 1 || radar[2][3] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][4] == 1 || radar[3][4] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::DOWN){
        radar[0][2] = 2, radar[1][2] = 2, radar[2][2] = 2;
        if(radar[3][3] == 1 || radar[3][4] == 1 || radar[2][3]){
            dir[1] = false;
        }
        if(radar[3][0] == 1 || radar[3][1] == 1 || radar[2][1]){
            dir[2] = false;
        }
        if(radar[3][2] == 1 || radar[4][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[4][1] == 1 || radar[4][3] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::LEFT){
        //Tranposing the matrix
        radar[2][2] = 2, radar[2][3] = 2, radar[2][4] = 2;
        if(radar[3][1] == 1 || radar[4][1] == 1 || radar[3][2] == 1){
            dir[1] = false;
        }
        if(radar[0][1] == 1 || radar[1][1] == 1 || radar[1][2] == 1){
            dir[2] = false;
        }
        if(radar[2][0] == 1 || radar[2][1] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][0] == 1 || radar[3][0] == 1){
                dir[0] = false;
            }
        }
    }else{
        radar[2][2] = 2, radar[3][2] = 2, radar[4][2] = 2;
        if(radar[1][0] == 1 || radar[1][1] == 1 || radar[2][1] == 1){
            dir[1] = false;
        }
        if(radar[1][3] == 1 || radar[1][4] == 1 || radar[2][3] == 1){
            dir[2] = false;
        }
        if(radar[0][2] == 1 || radar[1][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[0][1] == 1 || radar[0][3] == 1){
                dir[0] = false;
            }
        }
    }
    //forward left right
//    for(int i = 0;i < 5;i++){
//        for(int j = 0;j < 5;j++){
//            std :: cout << radar[i][j] << " ";
//        }
//        std :: cout << std :: endl;
//    }
//    std :: cout << std :: endl;
    
    if(dir[0]){
        //not in danger
        return DirectionType::kForward;
    }else{
        if(dir[2] && dir[1]){
//            return safeDirection(game.Snakes().at(id), game);
            return DirectionType::kRight;
        }else if(dir[1]){
            return DirectionType::kLeft;
        }else if(dir[2]){
            return DirectionType::kRight;
        }
    }
    return DirectionType::kForward;
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
            if (_currentDirType != DirectionType::kForward) {
                float remaining_angle = abs(_final_angle - snake.Direction());
                if (remaining_angle > 0) { //still turning
                    return _currentDirType;
                }
                // finished turning
                _dirSymbol = AngleToSymbol(snake.Direction());
            }
                            
            _currentDirType = DirectionType::kForward;
            _currentDirType = Radar(snake.Head(), _dirSymbol, game, id, snake);
            if(_currentDirType == DirectionType::kRight){
                _final_angle = snake.Direction() + 90;
            }else if(_currentDirType == DirectionType::kLeft){
                _final_angle = snake.Direction() - 90;
            }
            return _currentDirType;
    }
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    // check front collision distance with other snakes
    Snake neareat;
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                    if(distance == d_body){
                        neareat = anotherSnake;
                    }
                }
            }
        }
    }
    
    float radar_range = turn_radius;
    Position starting_point;
    starting_point.x = snakePos.x - 2*radar_range;
    starting_point.y = snakePos.y - 2*radar_range;

    if(dirSymbol == AngleToSymbol(game.Snakes().at(id).Direction())){
        for(Position pos : neareat.Body()){
            for(int k = 0; k < 4;k++){
                for(int r = 0; r < 5;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, pos) < pow((radar_range - game.kSnakeRadius),2)){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }else if(dirSymbol == AngleToSymbol(game.Snakes().at(id).Direction() + 90)){
        for(Position pos : neareat.Body()){
            for(int k = 0; k < 5;k++){
                for(int r = 0; r < 4;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, pos) < pow((radar_range - game.kSnakeRadius),2)){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }else if(dirSymbol == AngleToSymbol(game.Snakes().at(id).Direction() - 90)){
        for(Position pos : neareat.Body()){
            for(int k = 0; k < 5;k++){
                for(int r = 2; r < 5;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, pos) < pow((radar_range - game.kSnakeRadius),2)){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    angle = int(angle) % 360;
    if(angle < 0){
        angle += 360;
    }
    // can be converted into 4 directions
    return static_cast<DirectionSymbol>(angle/90);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
    }
    return -1;
}
float CustomController::distance_cal(Position a, Position b){
    float ans = pow((a.x - b.x),2) + pow((a.y - b.y), 2);
//    ans = sqrt(ans);
    return ans;
}
```

# go farest place
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType Radar(Position, DirectionSymbol, Game, size_t);
    float distance_cal(Position, Position);
    DirectionType safeDirection(const Snake& snake, const Game&);
    int radar[5][5];
};

DirectionType CustomController::Radar(Position snakeHead, DirectionSymbol _dirSymbol, Game game, size_t id){
    float radar_range = turn_radius;
    for(int i = 0;i < 5;i++)
        for(int j = 0;j < 5;j++)
            radar[i][j] = 0;
    Position starting_point;
    starting_point.x = snakeHead.x - 2*radar_range;
    starting_point.y = snakeHead.y - 2*radar_range;
    for(int i = 0; i < 5;i++){
        for(int j = 0; j < 5;j++){
            if(game.FieldWidth() - starting_point.x - j*radar_range < radar_range || starting_point.x + j*radar_range < radar_range){
                radar[i][j] = 1;
            }else if(game.FieldHeight() - starting_point.y - i*radar_range < radar_range || starting_point.y + i*radar_range < radar_range){
                radar[i][j] = 1;
            }
        }
    }
//
    bool dir[3] = {true, true, true};
    if(_dirSymbol == DirectionSymbol::RIGHT){
        radar[2][2] = 2, radar[2][1] = 2, radar[2][0] = 2;
        if(radar[0][3] == 1 || radar[1][3] == 1){
            dir[1] = false;
        }
        if(radar[3][3] == 1 || radar[4][3] == 1){
            dir[2] = false;
        }
        if(radar[2][4] == 1 || radar[2][3] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][4] == 1 || radar[3][4] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::DOWN){
        radar[0][2] = 2, radar[1][2] = 2, radar[2][2] = 2;
        if(radar[3][3] == 1 || radar[3][4] == 1){
            dir[1] = false;
        }
        if(radar[3][0] == 1 || radar[3][1] == 1){
            dir[2] = false;
        }
        if(radar[3][2] == 1 || radar[4][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[4][1] == 1 || radar[4][3] == 1){
                dir[0] = false;
            }
        }
    }else if(_dirSymbol == DirectionSymbol::LEFT){
        //Tranposing the matrix
        radar[2][2] = 2, radar[2][3] = 2, radar[2][4] = 2;
        if(radar[3][1] == 1 || radar[4][1] == 1){
            dir[1] = false;
        }
        if(radar[0][1] == 1 || radar[1][1] == 1){
            dir[2] = false;
        }
        if(radar[2][0] == 1 || radar[2][1] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][0] == 1 || radar[3][0] == 1){
                dir[0] = false;
            }
        }
    }else{
        radar[2][2] = 2, radar[3][2] = 2, radar[4][2] = 2;
        if(radar[1][0] == 1 || radar[1][1] == 1){
            dir[1] = false;
        }
        if(radar[1][3] == 1 || radar[1][4] == 1){
            dir[2] = false;
        }
        if(radar[0][2] == 1 || radar[1][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[0][1] == 1 || radar[0][3] == 1){
                dir[0] = false;
            }
        }
    }
    //forward left right

    
    if(dir[0]){
        //not in danger
        return DirectionType::kForward;
    }else{
        if(dir[2] && dir[1]){
//            return safeDirection(game.Snakes().at(id), game);
            return DirectionType::kRight;
        }else if(dir[1]){
            return DirectionType::kLeft;
        }else if(dir[2]){
            return DirectionType::kRight;
        }
    }
    return DirectionType::kForward;
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
//        Radar(snake.Head(), _dirSymbol, game, id, );
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance =  GetCollisionDistance(snake.Head(), _dirSymbol, game, id);
        float distance_right = GetCollisionDistance(snake.Head(), DirectionSymbol(AngleToSymbol(snake.Direction()+90)), game, id);
        float distance_left = GetCollisionDistance(snake.Head(), DirectionSymbol(AngleToSymbol(snake.Direction()-90)), game, id);
        
        float max = distance;
        max = std :: max(max, distance_right);
        max = std :: max(max, distance_left);
        
        if ((snake.Head().y - 0) < turn_radius*2)
        {
            if (snake.Direction() == 0)
                _turnDirection = DirectionType::kRight;
            else
                _turnDirection = DirectionType::kLeft;
        }
        if (abs(snake.Head().y - 2500) < turn_radius*2)
        {
            if (snake.Direction() == 0)
                _turnDirection = DirectionType::kLeft;
            else
                _turnDirection = DirectionType::kRight;
        }
        
        // if 0 < distance < min_distance
        if (distance > 0 && distance < turn_radius*1.2) {
            if(max == distance_left){
                _currentDirType = DirectionType::kLeft;
                _final_angle = snake.Direction() - 90;
            }else if(max == distance_right){
                _currentDirType = DirectionType::kRight;
                _final_angle = snake.Direction() + 90;
            }
        }
        else {
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    // check front collision distance with other snakes
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                }
            }
        }
    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    if (int(angle) % 90 != 0) {
        return DirectionSymbol::NONE;
    }
    angle = int(angle) % 360;
    if(angle < 0){
        angle += 360;
    }
    // can be converted into 4 directions
    return static_cast<DirectionSymbol>(angle/90);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
    }
    return -1;
}
float CustomController::distance_cal(Position a, Position b){
    float ans = pow((a.x - b.x),2) + pow((a.y - b.y), 2);
//    ans = sqrt(ans);
    return ans;
}
```
# Demo this shit 
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;

    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    DirectionType Radar(Position, DirectionSymbol, Game, size_t, Snake);
    float distance_cal(Position, Position);
    DirectionType safeDirection(const Snake& snake, const Game&);
    void clearPath(Position, Position);
    Position lastturnPosition = {2500, 1250};
    int radar[5][5];
    int path[501][501] = {0};
    
};



void CustomController::clearPath(Position a, Position b){
    Position start = {a.x/50, a.y/50};
    Position end = {b.x/50, b.y/50};
    
    if(start.x == end.x){
        for(int i = start.y; i <= end.y;i++){
            path[i][int(start.x)] = 1;
        }
    }else if(start.y == end.y){
        for(int i = start.x; i <= end.x;i++){
            path[int(start.y)][i] = 1;
        }
    }else{
//        std :: cout << "what ?? " << std :: endl;
    }
}

DirectionType CustomController::Radar(Position snakeHead, DirectionSymbol _dirSymbol, Game game, size_t id, Snake snake){
    float radar_range = turn_radius;
    for(int i = 0;i < 5;i++)
        for(int j = 0;j < 5;j++)
            radar[i][j] = 0;
    Position starting_point;
    starting_point.x = snakeHead.x - 2*radar_range;
    starting_point.y = snakeHead.y - 2*radar_range;
    for(int i = 0; i < 5;i++){
        for(int j = 0; j < 5;j++){
            if(game.FieldWidth() - starting_point.x - j*radar_range < radar_range || starting_point.x + j*radar_range < radar_range){
                radar[i][j] = 1;
            }else if(game.FieldHeight() - starting_point.y - i*radar_range < radar_range || starting_point.y + i*radar_range < radar_range){
                radar[i][j] = 1;
            }
        }
    }
    
    float distance = GetCollisionDistance(snakeHead, _dirSymbol, game, id);
    float distance_right = GetCollisionDistance(snakeHead, AngleToSymbol(snake.Direction()+90), game, id);
    float distance_left = GetCollisionDistance(snakeHead, AngleToSymbol(snake.Direction()-90), game, id);
    
    float max = std :: max(distance, distance_right);
    max = std :: max(distance_left, max);
    
    bool dir[3] = {true, true, true};
    bool visited[3] = {false, false, false};
    int a = snakeHead.x/50, b = snakeHead.y/50;
    if(_dirSymbol == DirectionSymbol::RIGHT){
        radar[2][2] = 2, radar[2][1] = 2, radar[2][0] = 2;
        if(radar[0][3] == 1 || radar[1][3] == 1 || radar[1][2] == 1){
            dir[1] = false;
        }
        if(radar[3][3] == 1 || radar[4][3] == 1 || radar[3][2] == 1){
            dir[2] = false;
        }
        if(radar[2][4] == 1 || radar[2][3] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][4] == 1 || radar[3][4] == 1){
                dir[0] = false;
            }
        }
        if(path[a+1][b-1] == 1){
            visited[1] = true;
        }
        if(path[a+1][b+1] == 1){
            visited[2] = true;
        }
        if(path[a+1][b] == 1){
            visited[0] = true;
        }
    }else if(_dirSymbol == DirectionSymbol::DOWN){
        radar[0][2] = 2, radar[1][2] = 2, radar[2][2] = 2;
        if(radar[3][3] == 1 || radar[3][4] == 1 || radar[2][3]){
            dir[1] = false;
        }
        if(radar[3][0] == 1 || radar[3][1] == 1 || radar[2][1]){
            dir[2] = false;
        }
        if(radar[3][2] == 1 || radar[4][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[4][1] == 1 || radar[4][3] == 1){
                dir[0] = false;
            }
        }
        if(path[a+1][b+1] == 1){
            visited[1] = true;
        }
        if(path[a-1][b+1] == 1){
            visited[2] = true;
        }
        if(path[a][b+1] == 1){
            visited[0] = true;
        }
    }else if(_dirSymbol == DirectionSymbol::LEFT){
        //Tranposing the matrix
        radar[2][2] = 2, radar[2][3] = 2, radar[2][4] = 2;
        if(radar[3][1] == 1 || radar[4][1] == 1 || radar[3][2] == 1){
            dir[1] = false;
        }
        if(radar[0][1] == 1 || radar[1][1] == 1 || radar[1][2] == 1){
            dir[2] = false;
        }
        if(radar[2][0] == 1 || radar[2][1] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[1][0] == 1 || radar[3][0] == 1){
                dir[0] = false;
            }
        }
        if(path[a-1][b+1] == 1){
            visited[1] = true;
        }
        if(path[a-1][b-1] == 1){
            visited[2] = true;
        }
        if(path[a-1][b] == 1){
            visited[0] = true;
        }
    }else{
        radar[2][2] = 2, radar[3][2] = 2, radar[4][2] = 2;
        if(radar[1][0] == 1 || radar[1][1] == 1 || radar[2][1] == 1){
            dir[1] = false;
        }
        if(radar[1][3] == 1 || radar[1][4] == 1 || radar[2][3] == 1){
            dir[2] = false;
        }
        if(radar[0][2] == 1 || radar[1][2] == 1){
            dir[0] = false;
        }
        //define dead-end
        if(dir[0]){
            if(radar[0][1] == 1 || radar[0][3] == 1){
                dir[0] = false;
            }
        }
        if(path[a-1][b-1] == 1){
            visited[1] = true;
        }
        if(path[a+1][b-1] == 1){
            visited[2] = true;
        }
        if(path[a][b-1] == 1){
            visited[0] = true;
        }
    }
    int cnt = 0;
    for(int i = 0; i< 3;i++)
        if(visited[i] == false)
            cnt++;
    if(cnt > 0)
        for(int i = 0;i < 3;i++)
            dir[i] = (dir[i] && !visited[i]);
    
    if(dir[0]){
        return DirectionType::kForward;
    }else{
        if(dir[1] && dir[2]){
            if(distance_left > distance_right){
                return DirectionType::kLeft;
            }
            return DirectionType::kRight;
        }else if(dir[1]){
            return DirectionType::kLeft;
        }else if(dir[2]){
            return DirectionType::kRight;
        }
    }
    return DirectionType::kForward;
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
            if (_currentDirType != DirectionType::kForward) {
                float remaining_angle = abs(_final_angle - snake.Direction());
                if (remaining_angle > 0) { //still turning
                    return _currentDirType;
                }
                // finished turning
                _dirSymbol = AngleToSymbol(snake.Direction());
                lastturnPosition = snake.Head();
            }
            _currentDirType = DirectionType::kForward;
            _currentDirType = Radar(snake.Head(), _dirSymbol, game, id, snake);
            if(_currentDirType == DirectionType::kRight){
                _final_angle = snake.Direction() + 90;
                clearPath(lastturnPosition, snake.Head());
            }else if(_currentDirType == DirectionType::kLeft){
                _final_angle = snake.Direction() - 90;
                clearPath(lastturnPosition, snake.Head());
            }
            return _currentDirType;
    }
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    // check front collision distance with other snakes
    Snake neareat;
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius, dirSymbol, pos, Game::kSnakeRadius);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                    if(distance == d_body){
                        neareat = anotherSnake;
                    }
                }
            }
        }
    }
    
    
    float radar_range = turn_radius;
    
//    if(distance > radar_range*5/2){
//        return distance;
//    }
    
    Position starting_point;
    starting_point.x = snakePos.x - 2*radar_range;
    starting_point.y = snakePos.y - 2*radar_range;

    

    if(dirSymbol == AngleToSymbol(game.Snakes().at(id).Direction())){
        for(Position pos : neareat.Body()){
            for(int k = 0; k < 3;k++){
                for(int r = 0; r < 5;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, pos) < pow((radar_range - game.kSnakeRadius),2)){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }else if(dirSymbol == AngleToSymbol(game.Snakes().at(id).Direction() + 90)){
        for(Position pos : neareat.Body()){
            for(int k = 0; k < 5;k++){
                for(int r = 0; r < 3;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, pos) < pow((radar_range - game.kSnakeRadius),2)){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }else if(dirSymbol == AngleToSymbol(game.Snakes().at(id).Direction() - 90)){
        for(Position pos : neareat.Body()){
            for(int k = 0; k < 5;k++){
                for(int r = 2; r < 5;r++){
                    Position center;
                    center.x = starting_point.x + r*radar_range;
                    center.y = starting_point.y + k*radar_range;
                    if(distance_cal(center, pos) < pow((radar_range - game.kSnakeRadius),2)){
                        radar[k][r] = 1;
                    }
                }
            }
        }
    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    angle = int(angle) % 360;
    if(angle < 0){
        angle += 360;
    }
    // can be converted into 4 directions
    return static_cast<DirectionSymbol>(angle/90);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT || dirSymbol == DirectionSymbol::RIGHT) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }
    

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP || dirSymbol == DirectionSymbol::DOWN) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
    }
    return -1;
}
float CustomController::distance_cal(Position a, Position b){
    float ans = pow((a.x - b.x),2) + pow((a.y - b.y), 2);
//    ans = sqrt(ans);
    return ans;
}
```
# divide world into small piece of shit




### fucking collision
```cpp=
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT && snakePos.x - target.x > 0) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }else if(dirSymbol == DirectionSymbol::RIGHT && snakePos.x - target.x < 0){
    	if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
	}

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP && snakePos.y - target.y > 0) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
    }else	if(dirSymbol == DirectionSymbol::DOWN && snakePos.y - target.y < 0){
    	if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
	}
    return -1;
}
```

# new shit alarm 
```cpp=
class CustomController : public ISnakeController {
public:
    DirectionType NextDirection(const Game&, size_t) override;
private:
    enum class DirectionSymbol {
        RIGHT, DOWN, LEFT, UP, NONE
    };
    DirectionType _turnDirection = DirectionType::kRight;
    DirectionType _currentDirType = DirectionType::kForward;
    float _final_angle = 0;
    DirectionSymbol _dirSymbol = AngleToSymbol(_final_angle);
    const float turn_radius = 3 * 180 / 3.1415926 + 30;
    int A_times = 1;
    DirectionSymbol AngleToSymbol(float);
    int howManySnake(const Game& game);
    float GetCollisionDistance(Position, DirectionSymbol, const Game&, size_t);
    float GetCollisionDistance(DirectionSymbol, const Game&, size_t);//for A
    float GetFrontCollisionDistance(Position, float, DirectionSymbol, Position, float);
    float FrontWallDistance(Position, DirectionSymbol, float, float);
    void clearPath(Position, Position);
    void clearPath(Position);
    void markDown(Game, size_t);
    Position last_turn = {2500, 1250};
    int path[501][501] = {0};
};

void CustomController::clearPath(Position a){
    path[int(round(a.x/50))][int(round(a.y/50))] = 1;
    return;
}


void CustomController::clearPath(Position a, Position b){
    Position start = {round(a.x/50), round(a.y/50)};
    Position end = {round(b.x/50), round(b.y/50)};

    if(start.x == end.x){
        for(int i = start.y; i <= end.y;i++){
            path[i][int(start.x)] = 1;
        }
    }else if(start.y == end.y){
        for(int i = start.x; i <= end.x;i++){
            path[int(start.y)][i] = 1;
        }
    }
}

int CustomController::howManySnake(const Game& game){
    int amount = 0;
    for(auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it){
        amount++;
    }
    return amount;
}
DirectionType CustomController::NextDirection(const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    int amount = howManySnake(game);
    if(amount == 1)
    {
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            // finished turning
            _dirSymbol = AngleToSymbol(snake.Direction());
        }
        float distance = GetCollisionDistance(_dirSymbol, game, id);
        if (distance > 0 && distance*1.2 < turn_radius + A_times*39.2) {
            // start turning around
            _currentDirType = _turnDirection;
            _final_angle = snake.Direction() + 90;
            A_times++;
        }else{
            // no collision problem, just go straight forward
            _currentDirType = DirectionType::kForward;
        }
        return _currentDirType;
    }
    else
    {
        // if is turning around
        // keep turning
        if (_currentDirType != DirectionType::kForward) {
            float remaining_angle = abs(_final_angle - snake.Direction());
            if (remaining_angle > 0) { //still turning
                return _currentDirType;
            }
            last_turn = snake.Head();
            _dirSymbol = AngleToSymbol(snake.Direction());
            _currentDirType = DirectionType::kForward;
        }
        float distance=  GetCollisionDistance(snake.Head() , _dirSymbol, game, id);
        float distance_right;
        float distance_left;
        float predict = turn_radius;
        Position rightTurn = { predict , 0 };
        Position downTurn = { 0 , predict };
        Position leftTurn = { -predict , 0 };
        Position upTurn = { 0 , -predict };
        if (_dirSymbol == DirectionSymbol::RIGHT) {
            distance_right = GetCollisionDistance(snake.Head() +rightTurn , DirectionSymbol::DOWN , game, id);
            distance_left = GetCollisionDistance(snake.Head() +rightTurn , DirectionSymbol::UP , game, id);
        }
        if (_dirSymbol == DirectionSymbol::DOWN) {
                distance_right = GetCollisionDistance(snake.Head() +downTurn, DirectionSymbol::LEFT, game, id);
                distance_left = GetCollisionDistance(snake.Head() +downTurn, DirectionSymbol::RIGHT, game, id);
        }
        if (_dirSymbol == DirectionSymbol::LEFT) {
                distance_right = GetCollisionDistance(snake.Head() +leftTurn, DirectionSymbol::UP, game, id);
                distance_left = GetCollisionDistance(snake.Head() +leftTurn, DirectionSymbol::DOWN, game, id);
        }
        if (_dirSymbol == DirectionSymbol::UP) {
                distance_right = GetCollisionDistance(snake.Head() +upTurn, DirectionSymbol::RIGHT, game, id);
                distance_left = GetCollisionDistance(snake.Head() +upTurn, DirectionSymbol::LEFT, game, id);
        }
        // if 0 < distance < min_distance
        if (distance > 0  && distance < turn_radius* 1.8 ) {
            float max = distance;
            max = std :: max(max, distance_right);
            max = std :: max(max, distance_left);
            if(max == distance_left ){
                _currentDirType = DirectionType::kLeft;
                _final_angle = snake.Direction() - 90;
                clearPath(snake.Head(), last_turn);
            }else if(max == distance_right ){
                _currentDirType = DirectionType::kRight;
                _final_angle = snake.Direction() + 90;
                clearPath(snake.Head(), last_turn);
            }else{
                _currentDirType = DirectionType::kForward;
            }
        }
        else {
                bool visited[3] = {false, false, false};
                int a = snake.Head().x/50, b = snake.Head().y/50;
                if(_dirSymbol == DirectionSymbol::RIGHT){
                        if(path[a+3][b-3] == 1){
                            visited[1] = true;
                        }if(path[a+3][b+3] == 1){
                            visited[2] = true;
                        }if(path[a+3][b] == 1){
                            visited[0] = true;
                        }
                }else if(_dirSymbol == DirectionSymbol::DOWN){
                        if(path[a+3][b+3] == 1){
                            visited[1] = true;
                        }if(path[a-3][b+3] == 1){
                            visited[2] = true;
                        }if(path[a][b+3] == 1){
                            visited[0] = true;
                        }
                }else if(_dirSymbol == DirectionSymbol::LEFT){
                        //Tranposing the matrix
                        if(path[a-3][b+3] == 1){
                            visited[1] = true;
                        }if(path[a-3][b-3] == 1){
                            visited[2] = true;
                        }if(path[a-3][b] == 1){
                            visited[0] = true;
                        }
                }else{
                        if(path[a-3][b-3] == 1){
                            visited[1] = true;
                        }if(path[a+3][b-3] == 1){
                            visited[2] = true;
                        }if(path[a][b-3] == 1){
                            visited[0] = true;
                        }
                }
                if(!visited[0]){
                    return DirectionType::kForward;
                }else if(!visited[1]){
                    _final_angle = snake.Direction() - 90;
                    clearPath(snake.Head(), last_turn);
                    _currentDirType = DirectionType::kLeft;
                    return DirectionType::kLeft;
                }else if(!visited[2]){
                    _final_angle = snake.Direction() + 90;
                    clearPath(snake.Head(), last_turn);
                    _currentDirType = DirectionType::kRight;
                    return DirectionType::kRight;
                }
            }
        }
        return DirectionType::kForward;
}
float CustomController::GetCollisionDistance(DirectionSymbol dirSymbol, const Game& game, size_t id) {
    const auto& snake = game.Snakes().at(id);
    float distance = FrontWallDistance(snake.Head(), dirSymbol, game.FieldWidth(), game.FieldHeight());
    return distance;
}
float CustomController::GetCollisionDistance(Position snakePos, DirectionSymbol dirSymbol, const Game& game, size_t id) {

    // check front collision distance with field
    float distance = FrontWallDistance(snakePos, dirSymbol, game.FieldWidth(), game.FieldHeight());
    //std::cout << "wall_distance" << distance << std::endl;
    // check front collision distance with other snakes
    for (auto it = game.Snakes().begin(); it != game.Snakes().end(); ++it) {
        const size_t anotherID = it->first;
        const Snake& anotherSnake = it->second;
        if (anotherID == id) continue;

        float d = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius*2, dirSymbol, anotherSnake.Head(), Game::kSnakeRadius*2);//Game::kSnakeRadius*2
        
        if (d > 0) {
            if (distance < 0)    distance = d;
            else {
                distance = std::min(distance, d);
            }
        }

        for (const Position& pos : anotherSnake.Body()) {
            float d_body = GetFrontCollisionDistance(snakePos, Game::kSnakeRadius*2, dirSymbol, pos, Game::kSnakeRadius*2);
            if (d_body > 0) {
                if (distance < 0)    distance = d_body;
                else {
                    distance = std::min(distance, d_body);
                }
            }
        }
    }
    return distance;
}

CustomController::DirectionSymbol CustomController::AngleToSymbol(float angle) {
    // if angle is not a multiple of 90
    angle = int(angle) % 360;
    if(angle < 0)
        angle += 360;
    
    if (int(angle) % 90 != 0) {
        return DirectionSymbol::NONE;
    }
    // can be converted into 4 directions
    int dir = abs(angle / 90);
    dir %= 4;
    return static_cast<DirectionSymbol>(dir);
}

float CustomController::FrontWallDistance(Position snakeHead, DirectionSymbol dirSymbol, float rightWall, float downWall) {
    Position frontFieldCollisionPos{ 0, 0 };
    if (dirSymbol == DirectionSymbol::LEFT) {
        frontFieldCollisionPos.x = 0;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::RIGHT) {
        frontFieldCollisionPos.x = rightWall;
        frontFieldCollisionPos.y = snakeHead.y;
    }
    else if (dirSymbol == DirectionSymbol::UP) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = 0;
    }
    else if (dirSymbol == DirectionSymbol::DOWN) {
        frontFieldCollisionPos.x = snakeHead.x;
        frontFieldCollisionPos.y = downWall;
    }

    return GetFrontCollisionDistance(snakeHead, Game::kSnakeRadius, dirSymbol, frontFieldCollisionPos, 0);
}
float CustomController::GetFrontCollisionDistance(Position snakePos, float snakeRadius, DirectionSymbol dirSymbol, Position target, float targetRadius) {
    float distanceX = abs(snakePos.x - target.x) - snakeRadius - targetRadius;
    float distanceY = abs(snakePos.y - target.y) - snakeRadius - targetRadius;

    // if direction is Left/Right
    if (dirSymbol == DirectionSymbol::LEFT && snakePos.x - target.x > 0) {
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }else if(dirSymbol == DirectionSymbol::RIGHT && snakePos.x - target.x < 0){
        if (distanceY > 0) { // if will not hit target y, return -1
            return -1;
        }
        return distanceX;
    }

    // if direction is Up/Down
    if (dirSymbol == DirectionSymbol::UP && snakePos.y - target.y > 0) {
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
    }else    if(dirSymbol == DirectionSymbol::DOWN && snakePos.y - target.y < 0){
        if (distanceX > 0) { // if will not hit target x, return -1
            return -1;
        }
        return distanceY;
    }
    return -1;
}

```
