tdd-katas/lib/mars_rover.dart
2026-02-24 10:56:30 +07:00

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;
}
}
}
}