Skip to content

Commit 3597821

Browse files
authored
Merge pull request #146 from IanWhitney/implement_robot_simulator
Implement Robot Simulator
2 parents 9f9a637 + 9129c83 commit 3597821

File tree

6 files changed

+300
-0
lines changed

6 files changed

+300
-0
lines changed

config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"roman-numerals",
2323
"hexadecimal",
2424
"grade-school",
25+
"robot-simulator",
2526
"queen-attack",
2627
"sublist",
2728
"allergies",

exercises/robot-simulator/Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exercises/robot-simulator/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[package]
2+
name = "robot-simulator"
3+
version = "0.0.0"

exercises/robot-simulator/example.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#[derive(PartialEq, Debug, Copy, Clone)]
2+
pub enum Direction {
3+
North,
4+
East,
5+
South,
6+
West,
7+
}
8+
9+
impl Direction {
10+
pub fn previous_clockwise(&self) -> Self {
11+
match *self {
12+
Direction::North => Direction::West,
13+
Direction::East => Direction::North,
14+
Direction::South => Direction::East,
15+
Direction::West => Direction::South,
16+
}
17+
}
18+
19+
pub fn next_clockwise(&self) -> Self {
20+
match *self {
21+
Direction::North => Direction::East,
22+
Direction::East => Direction::South,
23+
Direction::South => Direction::West,
24+
Direction::West => Direction::North,
25+
}
26+
}
27+
}
28+
29+
#[derive(Clone, Copy)]
30+
struct Position {
31+
x: i32,
32+
y: i32,
33+
}
34+
35+
impl Position {
36+
fn new(x: i32, y: i32) -> Self {
37+
Position { x: x, y: y }
38+
}
39+
40+
fn advance(&self, direction: &Direction) -> Self {
41+
match *direction {
42+
Direction::North => Self::new(self.x, self.y + 1),
43+
Direction::South => Self::new(self.x, self.y - 1),
44+
Direction::East => Self::new(self.x + 1, self.y),
45+
Direction::West => Self::new(self.x - 1, self.y),
46+
}
47+
}
48+
}
49+
50+
#[derive(Clone)]
51+
pub struct Robot {
52+
position: Position,
53+
direction: Direction,
54+
}
55+
56+
impl Robot {
57+
pub fn new(x: i32, y: i32, d: Direction) -> Self {
58+
Robot::build(Position::new(x, y), d)
59+
}
60+
61+
fn build(position: Position, direction: Direction) -> Self {
62+
Robot {
63+
position: position,
64+
direction: direction,
65+
}
66+
}
67+
68+
pub fn turn_right(&self) -> Self {
69+
Self::build(self.position, self.direction.next_clockwise())
70+
}
71+
72+
pub fn turn_left(&self) -> Self {
73+
Self::build(self.position, self.direction.previous_clockwise())
74+
}
75+
76+
pub fn advance(&self) -> Self {
77+
Self::build(self.position.advance(&self.direction), self.direction)
78+
}
79+
80+
pub fn instructions(&self, instructions: &str) -> Self {
81+
instructions.chars().fold(self.clone(),
82+
|robot, instruction| robot.execute(instruction))
83+
}
84+
85+
pub fn position(&self) -> (i32, i32) {
86+
(self.position.x, self.position.y)
87+
}
88+
89+
pub fn direction(&self) -> &Direction {
90+
&self.direction
91+
}
92+
93+
fn execute(self, command: char) -> Self {
94+
match command {
95+
'R' => self.turn_right(),
96+
'L' => self.turn_left(),
97+
'A' => self.advance(),
98+
_ => self,
99+
}
100+
}
101+
}

exercises/robot-simulator/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// The code below is a stub. Just enough to satisfy the compiler.
2+
// In order to pass the tests you can add-to or change any of this code.
3+
4+
#[derive(PartialEq, Debug)]
5+
pub enum Direction {
6+
North,
7+
East,
8+
South,
9+
West,
10+
}
11+
12+
pub struct Robot;
13+
14+
impl Robot {
15+
#[allow(unused_variables)]
16+
pub fn new(x: isize, y: isize, d: Direction) -> Self {
17+
unimplemented!()
18+
}
19+
20+
pub fn turn_right(self) -> Self {
21+
unimplemented!()
22+
}
23+
24+
pub fn turn_left(self) -> Self {
25+
unimplemented!()
26+
}
27+
28+
pub fn advance(self) -> Self {
29+
unimplemented!()
30+
}
31+
32+
#[allow(unused_variables)]
33+
pub fn instructions(self, instructions: &str) -> Self {
34+
unimplemented!()
35+
}
36+
37+
pub fn position(&self) -> (isize, isize) {
38+
unimplemented!()
39+
}
40+
41+
pub fn direction(&self) -> &Direction {
42+
unimplemented!()
43+
}
44+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
extern crate robot_simulator;
2+
3+
use robot_simulator::*;
4+
5+
#[test]
6+
fn robots_are_created_with_position_and_direction() {
7+
let robot = Robot::new(0, 0, Direction::North);
8+
assert_eq!((0, 0), robot.position());
9+
assert_eq!(&Direction::North, robot.direction());
10+
}
11+
12+
#[test]
13+
#[ignore]
14+
fn positions_can_be_negative() {
15+
let robot = Robot::new(-1, -1, Direction::South);
16+
assert_eq!((-1, -1), robot.position());
17+
assert_eq!(&Direction::South, robot.direction());
18+
}
19+
20+
#[test]
21+
#[ignore]
22+
fn turning_right_does_not_change_position() {
23+
let robot = Robot::new(0, 0, Direction::North).turn_right();
24+
assert_eq!((0, 0), robot.position());
25+
}
26+
27+
#[test]
28+
#[ignore]
29+
fn turning_right_from_north_points_the_robot_east() {
30+
let robot = Robot::new(0, 0, Direction::North).turn_right();
31+
assert_eq!(&Direction::East, robot.direction());
32+
}
33+
34+
#[test]
35+
#[ignore]
36+
fn turning_right_from_east_points_the_robot_south() {
37+
let robot = Robot::new(0, 0, Direction::East).turn_right();
38+
assert_eq!(&Direction::South, robot.direction());
39+
}
40+
41+
#[test]
42+
#[ignore]
43+
fn turning_right_from_south_points_the_robot_west() {
44+
let robot = Robot::new(0, 0, Direction::South).turn_right();
45+
assert_eq!(&Direction::West, robot.direction());
46+
}
47+
48+
#[test]
49+
#[ignore]
50+
fn turning_right_from_west_points_the_robot_north() {
51+
let robot = Robot::new(0, 0, Direction::West).turn_right();
52+
assert_eq!(&Direction::North, robot.direction());
53+
}
54+
55+
#[test]
56+
#[ignore]
57+
fn turning_left_does_not_change_position() {
58+
let robot = Robot::new(0, 0, Direction::North).turn_left();
59+
assert_eq!((0, 0), robot.position());
60+
}
61+
62+
#[test]
63+
#[ignore]
64+
fn turning_left_from_north_points_the_robot_west() {
65+
let robot = Robot::new(0, 0, Direction::North).turn_left();
66+
assert_eq!(&Direction::West, robot.direction());
67+
}
68+
69+
#[test]
70+
#[ignore]
71+
fn turning_left_from_west_points_the_robot_south() {
72+
let robot = Robot::new(0, 0, Direction::West).turn_left();
73+
assert_eq!(&Direction::South, robot.direction());
74+
}
75+
76+
#[test]
77+
#[ignore]
78+
fn turning_left_from_south_points_the_robot_east() {
79+
let robot = Robot::new(0, 0, Direction::South).turn_left();
80+
assert_eq!(&Direction::East, robot.direction());
81+
}
82+
83+
#[test]
84+
#[ignore]
85+
fn turning_left_from_east_points_the_robot_north() {
86+
let robot = Robot::new(0, 0, Direction::East).turn_left();
87+
assert_eq!(&Direction::North, robot.direction());
88+
}
89+
90+
#[test]
91+
#[ignore]
92+
fn advance_does_not_change_the_direction() {
93+
let robot = Robot::new(0, 0, Direction::North).advance();
94+
assert_eq!(&Direction::North, robot.direction());
95+
}
96+
97+
#[test]
98+
#[ignore]
99+
fn advance_increases_the_y_coordinate_by_one_when_facing_north() {
100+
let robot = Robot::new(0, 0, Direction::North).advance();
101+
assert_eq!((0, 1), robot.position());
102+
}
103+
104+
#[test]
105+
#[ignore]
106+
fn advance_decreases_the_y_coordinate_by_one_when_facing_south() {
107+
let robot = Robot::new(0, 0, Direction::South).advance();
108+
assert_eq!((0, -1), robot.position());
109+
}
110+
111+
#[test]
112+
#[ignore]
113+
fn advance_increases_the_x_coordinate_by_one_when_facing_east() {
114+
let robot = Robot::new(0, 0, Direction::East).advance();
115+
assert_eq!((1, 0), robot.position());
116+
}
117+
118+
#[test]
119+
#[ignore]
120+
fn advance_decreases_the_x_coordinate_by_one_when_facing_west() {
121+
let robot = Robot::new(0, 0, Direction::West).advance();
122+
assert_eq!((-1, 0), robot.position());
123+
}
124+
125+
#[test]
126+
#[ignore]
127+
fn follow_instructions_to_move_west_and_north() {
128+
let robot = Robot::new(0, 0, Direction::North).instructions("LAAARALA");
129+
assert_eq!((-4, 1), robot.position());
130+
assert_eq!(&Direction::West, robot.direction());
131+
}
132+
133+
#[test]
134+
#[ignore]
135+
fn follow_instructions_to_move_west_and_south() {
136+
let robot = Robot::new(2, -7, Direction::East).instructions("RRAAAAALA");
137+
assert_eq!((-3, -8), robot.position());
138+
assert_eq!(&Direction::South, robot.direction());
139+
}
140+
141+
#[test]
142+
#[ignore]
143+
fn follow_instructions_to_move_east_and_north() {
144+
let robot = Robot::new(8, 4, Direction::South).instructions("LAAARRRALLLL");
145+
assert_eq!((11, 5), robot.position());
146+
assert_eq!(&Direction::North, robot.direction());
147+
}

0 commit comments

Comments
 (0)