Show invalid boats in red
This commit is contained in:
parent
c7bfdb8d74
commit
2f426a1540
@ -133,16 +133,36 @@ fn ui<B: Backend>(
|
|||||||
) -> CoordinatesMapper {
|
) -> CoordinatesMapper {
|
||||||
let errors = model.layout.errors(rules);
|
let errors = model.layout.errors(rules);
|
||||||
|
|
||||||
|
// Color of current boat
|
||||||
let current_boat = ColoredCells {
|
let current_boat = ColoredCells {
|
||||||
color: Color::Green,
|
color: Color::Green,
|
||||||
cells: model.layout.0[model.curr_boat].all_coordinates(),
|
cells: model.layout.0[model.curr_boat].all_coordinates(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Color of invalid boats
|
||||||
|
let mut invalid_coordinates = vec![];
|
||||||
|
for (idx, pos) in model.layout.boats().iter().enumerate() {
|
||||||
|
if idx == model.curr_boat {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !model
|
||||||
|
.layout
|
||||||
|
.check_present_boat_position(idx, rules)
|
||||||
|
.is_empty()
|
||||||
|
{
|
||||||
|
invalid_coordinates.append(&mut pos.all_coordinates());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let invalid_boats = ColoredCells {
|
||||||
|
color: Color::Red,
|
||||||
|
cells: invalid_coordinates,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Color of other boats
|
||||||
let mut other_boats_cells = vec![];
|
let mut other_boats_cells = vec![];
|
||||||
for boat in &model.layout.0 {
|
for boat in &model.layout.0 {
|
||||||
for pos in boat.all_coordinates() {
|
other_boats_cells.append(&mut boat.all_coordinates());
|
||||||
other_boats_cells.push(pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let other_boats = ColoredCells {
|
let other_boats = ColoredCells {
|
||||||
@ -163,6 +183,7 @@ fn ui<B: Backend>(
|
|||||||
let mut game_map_widget = GameMapWidget::new(rules)
|
let mut game_map_widget = GameMapWidget::new(rules)
|
||||||
.set_default_empty_char(' ')
|
.set_default_empty_char(' ')
|
||||||
.add_colored_cells(current_boat)
|
.add_colored_cells(current_boat)
|
||||||
|
.add_colored_cells(invalid_boats)
|
||||||
.add_colored_cells(other_boats)
|
.add_colored_cells(other_boats)
|
||||||
.set_title("Choose your boat layout")
|
.set_title("Choose your boat layout")
|
||||||
.set_yield_func(|c, r| {
|
.set_yield_func(|c, r| {
|
||||||
@ -174,7 +195,7 @@ fn ui<B: Backend>(
|
|||||||
})
|
})
|
||||||
.set_legend(legend);
|
.set_legend(legend);
|
||||||
|
|
||||||
// Colorate neighbors if boats can not touch
|
// Color of neighbors if boats can not touch
|
||||||
if !rules.boats_can_touch {
|
if !rules.boats_can_touch {
|
||||||
let mut boats_neighbors_cells = vec![];
|
let mut boats_neighbors_cells = vec![];
|
||||||
for boat in &model.layout.0 {
|
for boat in &model.layout.0 {
|
||||||
|
@ -276,6 +276,39 @@ impl BoatsLayout {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check a boat already present in the layout has a valid position
|
||||||
|
pub fn check_present_boat_position(&self, boat: usize, rules: &GameRules) -> Vec<&'static str> {
|
||||||
|
let mut errors = vec![];
|
||||||
|
|
||||||
|
// Check boat coordinates
|
||||||
|
let boat_i_coordinates = self.0[boat].all_coordinates();
|
||||||
|
if boat_i_coordinates.iter().any(|c| !c.is_valid(rules)) {
|
||||||
|
errors.push("A boat goes outside the game map!");
|
||||||
|
}
|
||||||
|
|
||||||
|
for boat_j in 0..self.0.len() {
|
||||||
|
if boat == boat_j {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let boat_j_coords = self.0[boat_j].all_coordinates();
|
||||||
|
if boat_i_coordinates.iter().any(|c| boat_j_coords.contains(c)) {
|
||||||
|
errors.push("A collision between two boats has been detected!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !rules.boats_can_touch
|
||||||
|
&& self.0[boat]
|
||||||
|
.neighbor_coordinates(rules)
|
||||||
|
.iter()
|
||||||
|
.any(|c| boat_j_coords.contains(c))
|
||||||
|
{
|
||||||
|
errors.push("Two boats are touching!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errors
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if this boats layout is valid or not
|
/// Check if this boats layout is valid or not
|
||||||
pub fn errors(&self, rules: &GameRules) -> Vec<&'static str> {
|
pub fn errors(&self, rules: &GameRules) -> Vec<&'static str> {
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
@ -296,31 +329,7 @@ impl BoatsLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for boat_i in 0..self.0.len() {
|
for boat_i in 0..self.0.len() {
|
||||||
// Check boat coordinates
|
errors.append(&mut self.check_present_boat_position(boat_i, rules));
|
||||||
let boat_i_coordinates = self.0[boat_i].all_coordinates();
|
|
||||||
if boat_i_coordinates.iter().any(|c| !c.is_valid(rules)) {
|
|
||||||
errors.push("A boat goes outside the game map!");
|
|
||||||
}
|
|
||||||
|
|
||||||
for boat_j in 0..self.0.len() {
|
|
||||||
if boat_i == boat_j {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let boat_j_coords = self.0[boat_j].all_coordinates();
|
|
||||||
if boat_i_coordinates.iter().any(|c| boat_j_coords.contains(c)) {
|
|
||||||
errors.push("A collision between two boats has been detected!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !rules.boats_can_touch
|
|
||||||
&& self.0[boat_i]
|
|
||||||
.neighbor_coordinates(rules)
|
|
||||||
.iter()
|
|
||||||
.any(|c| boat_j_coords.contains(c))
|
|
||||||
{
|
|
||||||
errors.push("Two boats are touching!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errors
|
errors
|
||||||
@ -330,6 +339,11 @@ impl BoatsLayout {
|
|||||||
self.errors(rules).is_empty()
|
self.errors(rules).is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the list of boats
|
||||||
|
pub fn boats(&self) -> &[BoatPosition] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_boat_at_position(&self, pos: Coordinates) -> Option<&BoatPosition> {
|
pub fn find_boat_at_position(&self, pos: Coordinates) -> Option<&BoatPosition> {
|
||||||
self.0.iter().find(|f| f.all_coordinates().contains(&pos))
|
self.0.iter().find(|f| f.all_coordinates().contains(&pos))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user