Context
- An object is moving in one direction: Up, Right, Down, or Left.
- The next direction will be chosen randomly.
- The next possible direction cannot be backwards.
Example
If it is going Right, it could go Up, Right or Down, but not Left.
Enum
There is a simple enum for directions:
#[derive(Debug, PartialEq)]
enum Direction {
Up,
Right,
Down,
Left,
}
Function signature
I would say that this is the function signature that accomplishes the task:
fn next_direction(current_dir: Direction) -> Direction
Current implementation
This is my current implementation:
use rand::prelude::*;
fn next_direction(current_dir: Direction) -> Direction {
let mut rng = thread_rng();
// Possible next direction
let next_dir_iter = [
Direction::Up,
Direction::Down,
Direction::Left,
Direction::Right,
]
.iter()
.filter(|&dir| match (current_dir, dir) {
(Direction::Up, Direction::Down) => false,
(Direction::Down, Direction::Up) => false,
(Direction::Left, Direction::Right) => false,
(Direction::Right, Direction::Left) => false,
(_, _) => true,
});
// Choose one
let dir = next_dir_iter.choose(&mut rng).unwrap();
// Return Direction instead of &Direction
match dir {
Direction::Up => Direction::Up,
Direction::Down => Direction::Down,
Direction::Left => Direction::Left,
Direction::Right => Direction::Right,
}
}
Could this function be written in a clearer, simpler, more efficient way?
I would say that readability is a plus, so a one liner or code golf implementation could not be optimal.
I have found How do I choose a random value from an enum?