Can get relevant grid locations

This commit is contained in:
Pierre HUBERT 2022-09-21 16:37:34 +02:00
parent 977345fb81
commit 7d0fed27a9
3 changed files with 119 additions and 3 deletions

View File

@ -241,6 +241,28 @@ impl CurrentGameStatus {
>= smallest_boat >= smallest_boat
} }
/// Get the locations on the grid where the player could fire
pub fn get_relevant_grid_locations(&self) -> Vec<Coordinates> {
let min_boat_size = self.get_size_of_smallest_un_sunk_boat().unwrap_or_default();
let mut coordinates = vec![];
let mut y = 0;
while y < self.rules.map_height {
let mut x = (min_boat_size - 1 + y) % min_boat_size;
while x < self.rules.map_width {
let c = Coordinates::new(x as i32, y as i32);
if self.should_fire_at_location(c) {
coordinates.push(c);
}
x += min_boat_size
}
y += 1;
}
coordinates
}
pub fn get_your_map(&self) -> String { pub fn get_your_map(&self) -> String {
PrintableCurrentGameMapStatus(self.rules.clone(), self.your_map.clone()).get_map() PrintableCurrentGameMapStatus(self.rules.clone(), self.your_map.clone()).get_map()
} }
@ -260,6 +282,8 @@ impl CurrentGameStatus {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::fmt::Write as _;
use crate::data::*; use crate::data::*;
#[test] #[test]
@ -443,4 +467,96 @@ mod test {
assert!(status.can_fire_at_location(Coordinates::new(0, 0))); assert!(status.can_fire_at_location(Coordinates::new(0, 0)));
assert!(!status.should_fire_at_location(Coordinates::new(0, 0))); assert!(!status.should_fire_at_location(Coordinates::new(0, 0)));
} }
fn print_coordinates_grid(status: &CurrentGameStatus, locs: &[Coordinates]) -> String {
let mut s = String::with_capacity(200);
s.push('\n');
for y in 0..status.rules.map_height {
for x in 0..status.rules.map_width {
let c = Coordinates::new(x as i32, y as i32);
write!(
s,
"{}",
match locs.contains(&c) {
true => "X",
false => ".",
}
)
.unwrap();
}
s.push('\n');
}
s
}
#[test]
fn relevant_grid_locations_new_game_min_boat_of_size_2() {
let _ = env_logger::builder().is_test(true).try_init();
let status = CurrentGameStatus::default();
let locs = status.get_relevant_grid_locations();
log::debug!("{}", print_coordinates_grid(&status, &locs));
for y in 0..status.rules.map_height {
for x in 0..status.rules.map_width {
let c = Coordinates::new(x as i32, y as i32);
if (x + y) % 2 == 1 {
assert!(locs.contains(&c), "Missing {}", c.human_print());
} else {
assert!(
!locs.contains(&c),
"Unwanted presence of {}",
c.human_print()
);
}
}
}
}
#[test]
fn relevant_grid_locations_new_game_min_boat_of_size_3() {
let _ = env_logger::builder().is_test(true).try_init();
let mut status = CurrentGameStatus::default();
status.rules.set_boats_list(&vec![3, 4, 5]);
let locs = status.get_relevant_grid_locations();
log::debug!("{}", print_coordinates_grid(&status, &locs));
assert!(!locs.contains(&Coordinates::new(0, 0)));
assert!(!locs.contains(&Coordinates::new(1, 0)));
assert!(locs.contains(&Coordinates::new(2, 0)));
assert!(locs.contains(&Coordinates::new(0, 1)));
assert!(!locs.contains(&Coordinates::new(1, 1)));
assert!(!locs.contains(&Coordinates::new(2, 1)));
assert!(locs.contains(&Coordinates::new(3, 1)));
}
#[test]
fn relevant_grid_locations_partial_play() {
let _ = env_logger::builder().is_test(true).try_init();
let mut status = CurrentGameStatus::default();
status.rules.set_boats_list(&vec![3, 4, 5]);
status
.opponent_map
.failed_strikes
.push(Coordinates::new(0, 0));
status
.opponent_map
.failed_strikes
.push(Coordinates::new(3, 0));
status
.opponent_map
.failed_strikes
.push(Coordinates::new(2, 1));
let locs = status.get_relevant_grid_locations();
log::debug!("{}", print_coordinates_grid(&status, &locs));
assert!(!locs.contains(&Coordinates::new(1, 0)));
assert!(!locs.contains(&Coordinates::new(2, 0)));
}
} }

View File

@ -61,7 +61,7 @@ impl GameRules {
} }
/// Remove last boat /// Remove last boat
pub fn pop_boat(&mut self) -> usize { pub fn remove_last_boat(&mut self) -> usize {
let list = self.boats_list(); let list = self.boats_list();
self.set_boats_list(&list[0..list.len() - 1]); self.set_boats_list(&list[0..list.len() - 1]);
*list.last().unwrap() *list.last().unwrap()

View File

@ -106,7 +106,7 @@ async fn invalid_boats_layout_number_of_boats() {
wait_for_port(TestPort::RandomBotInvalidBoatsLayoutNumberOfBoats.port()).await; wait_for_port(TestPort::RandomBotInvalidBoatsLayoutNumberOfBoats.port()).await;
let mut rules_modified = rules.clone(); let mut rules_modified = rules.clone();
rules_modified.pop_boat(); rules_modified.remove_last_boat();
let layout = BoatsLayout::gen_random_for_rules(&rules_modified).unwrap(); let layout = BoatsLayout::gen_random_for_rules(&rules_modified).unwrap();
let res = bot_client::BotClient::new( let res = bot_client::BotClient::new(
@ -138,7 +138,7 @@ async fn invalid_boats_layout_len_of_a_boat() {
wait_for_port(TestPort::RandomBotInvalidBoatsLayoutLenOfABoat.port()).await; wait_for_port(TestPort::RandomBotInvalidBoatsLayoutLenOfABoat.port()).await;
let mut rules_modified = rules.clone(); let mut rules_modified = rules.clone();
let previous = rules_modified.pop_boat(); let previous = rules_modified.remove_last_boat();
rules_modified.add_boat(previous - 1); rules_modified.add_boat(previous - 1);
let layout = BoatsLayout::gen_random_for_rules(&rules_modified).unwrap(); let layout = BoatsLayout::gen_random_for_rules(&rules_modified).unwrap();