Show invalid boats in red
This commit is contained in:
		@@ -133,16 +133,36 @@ fn ui<B: Backend>(
 | 
			
		||||
) -> CoordinatesMapper {
 | 
			
		||||
    let errors = model.layout.errors(rules);
 | 
			
		||||
 | 
			
		||||
    // Color of current boat
 | 
			
		||||
    let current_boat = ColoredCells {
 | 
			
		||||
        color: Color::Green,
 | 
			
		||||
        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![];
 | 
			
		||||
    for boat in &model.layout.0 {
 | 
			
		||||
        for pos in boat.all_coordinates() {
 | 
			
		||||
            other_boats_cells.push(pos);
 | 
			
		||||
        }
 | 
			
		||||
        other_boats_cells.append(&mut boat.all_coordinates());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let other_boats = ColoredCells {
 | 
			
		||||
@@ -163,6 +183,7 @@ fn ui<B: Backend>(
 | 
			
		||||
    let mut game_map_widget = GameMapWidget::new(rules)
 | 
			
		||||
        .set_default_empty_char(' ')
 | 
			
		||||
        .add_colored_cells(current_boat)
 | 
			
		||||
        .add_colored_cells(invalid_boats)
 | 
			
		||||
        .add_colored_cells(other_boats)
 | 
			
		||||
        .set_title("Choose your boat layout")
 | 
			
		||||
        .set_yield_func(|c, r| {
 | 
			
		||||
@@ -174,7 +195,7 @@ fn ui<B: Backend>(
 | 
			
		||||
        })
 | 
			
		||||
        .set_legend(legend);
 | 
			
		||||
 | 
			
		||||
    // Colorate neighbors if boats can not touch
 | 
			
		||||
    // Color of neighbors if boats can not touch
 | 
			
		||||
    if !rules.boats_can_touch {
 | 
			
		||||
        let mut boats_neighbors_cells = vec![];
 | 
			
		||||
        for boat in &model.layout.0 {
 | 
			
		||||
 
 | 
			
		||||
@@ -276,6 +276,39 @@ impl BoatsLayout {
 | 
			
		||||
        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
 | 
			
		||||
    pub fn errors(&self, rules: &GameRules) -> Vec<&'static str> {
 | 
			
		||||
        let mut errors = vec![];
 | 
			
		||||
@@ -296,31 +329,7 @@ impl BoatsLayout {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for boat_i in 0..self.0.len() {
 | 
			
		||||
            // Check boat coordinates
 | 
			
		||||
            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.append(&mut self.check_present_boat_position(boat_i, rules));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        errors
 | 
			
		||||
@@ -330,6 +339,11 @@ impl BoatsLayout {
 | 
			
		||||
        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> {
 | 
			
		||||
        self.0.iter().find(|f| f.all_coordinates().contains(&pos))
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user