Level 2 : Project 10


The Robot class models the state and behavior of virtual robots. Each robot corresponds to an object which is an instance of this class.

Each robot:

  • has a name (string)

  • has a position: given by the integer attributes x and y, knowing that x increases going east and y increases going north.

  • has a direction: given by the direction attribute which takes one of the values ​​"North", "East", "South" or "West".

  • can go forward one step: with the method without parameter advance().

  • can turn right by 90 ° to change direction (if its direction was "North" it becomes "East", if it was "East" it becomes "South", etc.): with the method without parameter right(). Robots cannot turn left.

  • can display its state in detail (using print)


The name, position and direction of a robot are given to it when it is created. The name is required but you can omit the position and direction, which are set to (0,0) and East by default.

1) Propose object code to represent the Robot class, while respecting the principle of data encapsulation.

2) We want to improve these robots by creating a New Generation, the RobotNG which do not replace the old robots but can coexist with them.

The RobotNG can do the same thing but also:

  • advance several steps at once using the advanceFast() method which takes the number of steps as a parameter.

  • turn left 90 ° using the left() method.

  • make a half turn using halfTurn() method


Write this new child class where:

  • a) advanceFast() = n * advance()
        left() = 3 * right()
        halfTurn() = 2 * right()

  • b) give a second more efficient solution that directly changes the state of the object without using the old methods


3) We want to put together Robot and RobotNG objects in a list.

a) how to declare the list?

b) how to display the status of all the robots contained in the list?


4) Modify the RobotNG class to be able to activate a "Turbo" mode and deactivate it. In this mode, each step is multiplied by 3. The call to the display() method should indicate at the end whether the robot is in Turbo mode or not.




Solution:


1)


class Robot {

  String _name;

  int _x;

  int _y;

  String _direction;

 

  Robot(String n) {

    _name = n;

    _x = 0;

    _y = 0;

    _direction = "East";

  }

  Robot.exactly(String n, int x, int y, String d) {

    _name = n;

    _x = x;

    _y = y;

    _direction = d;

  }

  void advance() {

    if (_direction == "North")

      _y++;

    else if (_direction == "East")

      _x++;

    else if (_direction == "South")

      _y--;

    else if (_direction == "West") _x--;

  }

 

  void right() {

    if (_direction == "North")

      _direction = "East";

    else if (_direction == "East")

      _direction = "South";

    else if (_direction == "South")

      _direction = "West";

    else if (_direction == "West") _direction = "North";

  }

 

  void display() {

    print("Name : $_name \n");

    print("Position : ( $_x , $_y ) ");

    print("Direction : $_direction");

  }

}


2) a)


 

class RobotNG extends Robot {

  RobotNG(String n) : super(n) {}

  RobotNG.exactly(String n, int x, int y, String direction)

      : super.exactly(n, x, y, direction) {}

  void advanceFast(int steps) {

    for (int i = 0; i < steps; i++) super.advance();

  }

 

  void left() {

    super.right();

    super.right();

    super.right();

  }

 

  void halfTurn() {

    super.right();

    super.right();

  }

}



2) b)


class Robot {

  String _name;

  int _x;

  int _y;

  String _direction;

 

  Robot(String n) {

    _name = n;

    _x = 0;

    _y = 0;

    _direction = "East";

  }

  Robot.exactly(String n, int x, int y, String d) {

    _name = n;

    _x = x;

    _y = y;

    _direction = d;

  }

  //getters and setters

  int getX() => _x;

  int getY() => _y;

  String getDirection() => _direction;

  void setX(int x) => _x = x;

  void setY(int y) => _y = y;

  void setDirection(String d) => _direction = d;

 

  void advance() {

    if (_direction == "North")

      _y++;

    else if (_direction == "East")

      _x++;

    else if (_direction == "South")

      _y--;

    else if (_direction == "West") _x--;

  }

 

  void right() {

    if (_direction == "North")

      _direction = "East";

    else if (_direction == "East")

      _direction = "South";

    else if (_direction == "South")

      _direction = "West";

    else if (_direction == "West") _direction = "North";

  }

 

  void display() {

    print("Name : $_name \n");

    print("Position : ( $_x , $_y ) ");

    print("Direction : $_direction");

  }

}

 

class RobotNG extends Robot {

  RobotNG(String n) : super(n) {}

  RobotNG.exactly(String n, int x, int y, String direction)

      : super.exactly(n, x, y, direction) {}

  void advanceFast(int steps) {

    if (getDirection() == "North")

      setY(getY() + steps);

    else if (getDirection() == "East")

      setX(getX() + steps);

    else if (getDirection() == "South")

      setY(getY() - steps);

    else //West

      setX(getX() - steps);

  }

 

  void left() {

    if (getDirection() == "North")

      setDirection("West");

    else if (getDirection() == "East")

      setDirection("North");

    else if (getDirection() == "South")

      setDirection("East");

    else //West

      setDirection("South");

  }

 

  void halfTurn() {

    if (getDirection() == "North")

      setDirection("South");

    else if (getDirection() == "East")

      setDirection("West");

    else if (getDirection() == "South")

      setDirection("North");

    else //West

      setDirection("East");

  }

}


3)a)


List<Robot> tab;


3)b)


  for (Robot r in tab) {

    if (r != null) {

      r.display();

    }

  }


4)


 

class RobotNG extends Robot {

  bool _turbo = false;

  RobotNG(String n) : super(n) {}

 

  RobotNG.exactly(String n, int x, int y, String direction)

      : super.exactly(n, x, y, direction) {}

  void setTurbo(bool activate) => _turbo = activate;

  bool isTurboActivated() => _turbo;

  void display() {

    super.display();

    print(_turbo ? "Turbo : ON" : "Turbo : OFF");

  }

 

  void advance() {

    if (_turbo)

      advanceFast(3);

    else

      super.advance();

  }

 

  void advanceFast(int steps) {

    if (_turbo) steps *= 3;

    if (getDirection() == "North")

      setY(getY() + steps);

    else if (getDirection() == "East")

      setX(getX() + steps);

    else if (getDirection() == "South")

      setY(getY() - steps);

    else //West

 

      setX(getX() - steps);

  }

 

  void left() {

    if (getDirection() == "North")

      setDirection("West");

    else if (getDirection() == "East")

      setDirection("North");

    else if (getDirection() == "South")

      setDirection("East");

    else //West

 

      setDirection("South");

  }

 

  void halfTurn() {

    if (getDirection() == "North")

      setDirection("South");

    else if (getDirection() == "East")

      setDirection("West");

    else if (getDirection() == "South")

      setDirection("North");

    else //West

 

      setDirection("East");

  }

}