106 lines
2.3 KiB
Dart
106 lines
2.3 KiB
Dart
enum Direction {
|
|
north('N'),
|
|
east('E'),
|
|
south('S'),
|
|
west('W');
|
|
|
|
final String code;
|
|
const Direction(this.code);
|
|
|
|
static Direction fromCode(String code) {
|
|
return Direction.values.firstWhere((d) => d.code == code);
|
|
}
|
|
|
|
Direction turnLeft() {
|
|
return Direction.values[(index + 3) % 4];
|
|
}
|
|
|
|
Direction turnRight() {
|
|
return Direction.values[(index + 1) % 4];
|
|
}
|
|
}
|
|
|
|
class Position {
|
|
final int x;
|
|
final int y;
|
|
|
|
Position(this.x, this.y);
|
|
|
|
Position moveNorth() => Position(x, y + 1);
|
|
Position moveEast() => Position(x + 1, y);
|
|
Position moveSouth() => Position(x, y - 1);
|
|
Position moveWest() => Position(x - 1, y);
|
|
}
|
|
|
|
class Plateau {
|
|
final int width;
|
|
final int height;
|
|
|
|
Plateau(this.width, this.height);
|
|
|
|
Position wrap(Position position) {
|
|
final wrappedX = _wrapCoordinate(position.x, width);
|
|
final wrappedY = _wrapCoordinate(position.y, height);
|
|
return Position(wrappedX, wrappedY);
|
|
}
|
|
|
|
int _wrapCoordinate(int value, int max) {
|
|
final wrapped = value % (max + 1);
|
|
return wrapped < 0 ? wrapped + max + 1 : wrapped;
|
|
}
|
|
}
|
|
|
|
class Rover {
|
|
Position _position;
|
|
Direction _direction;
|
|
final Plateau plateau;
|
|
|
|
Rover({
|
|
required int x,
|
|
required int y,
|
|
required String direction,
|
|
int plateauWidth = 100,
|
|
int plateauHeight = 100,
|
|
}) : _position = Position(x, y),
|
|
_direction = Direction.fromCode(direction),
|
|
plateau = Plateau(plateauWidth, plateauHeight);
|
|
|
|
int get x => _position.x;
|
|
int get y => _position.y;
|
|
String get direction => _direction.code;
|
|
|
|
void turnLeft() {
|
|
_direction = _direction.turnLeft();
|
|
}
|
|
|
|
void turnRight() {
|
|
_direction = _direction.turnRight();
|
|
}
|
|
|
|
void moveForward() {
|
|
final newPosition = switch (_direction) {
|
|
Direction.north => _position.moveNorth(),
|
|
Direction.east => _position.moveEast(),
|
|
Direction.south => _position.moveSouth(),
|
|
Direction.west => _position.moveWest(),
|
|
};
|
|
_position = plateau.wrap(newPosition);
|
|
}
|
|
|
|
void execute(String commands) {
|
|
for (var i = 0; i < commands.length; i++) {
|
|
final command = commands[i];
|
|
switch (command) {
|
|
case 'L':
|
|
turnLeft();
|
|
break;
|
|
case 'R':
|
|
turnRight();
|
|
break;
|
|
case 'M':
|
|
moveForward();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|