Can check if shooting a location is worthwhile or not
This commit is contained in:
parent
6832aebedb
commit
977345fb81
@ -65,7 +65,8 @@ pub struct CurrentGameStatus {
|
|||||||
impl CurrentGameStatus {
|
impl CurrentGameStatus {
|
||||||
/// Check if opponent can fire at a given location
|
/// Check if opponent can fire at a given location
|
||||||
pub fn can_fire_at_location(&self, location: Coordinates) -> bool {
|
pub fn can_fire_at_location(&self, location: Coordinates) -> bool {
|
||||||
!self.opponent_map.successful_strikes.contains(&location)
|
location.is_valid(&self.rules)
|
||||||
|
&& !self.opponent_map.successful_strikes.contains(&location)
|
||||||
&& !self.opponent_map.failed_strikes.contains(&location)
|
&& !self.opponent_map.failed_strikes.contains(&location)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +212,35 @@ impl CurrentGameStatus {
|
|||||||
boats_size.first().cloned()
|
boats_size.first().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_unshoot_room(&self, start: Coordinates, diff_x: i32, diff_y: i32) -> usize {
|
||||||
|
let mut size = 0;
|
||||||
|
|
||||||
|
let mut c = start;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
c = c.add_x(diff_x).add_y(diff_y);
|
||||||
|
if !self.can_fire_at_location(c) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check whether it is relevant to fire a location or not
|
||||||
|
pub fn should_fire_at_location(&self, c: Coordinates) -> bool {
|
||||||
|
if !self.can_fire_at_location(c) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let smallest_boat = self.get_size_of_smallest_un_sunk_boat().unwrap_or_default();
|
||||||
|
|
||||||
|
(self.get_unshoot_room(c, -1, 0) + 1 + self.get_unshoot_room(c, 0, 1)) >= smallest_boat
|
||||||
|
|| (self.get_unshoot_room(c, 0, -1) + 1 + self.get_unshoot_room(c, 0, 1))
|
||||||
|
>= smallest_boat
|
||||||
|
}
|
||||||
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
@ -353,4 +383,64 @@ mod test {
|
|||||||
status.get_size_of_smallest_un_sunk_boat().unwrap()
|
status.get_size_of_smallest_un_sunk_boat().unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn relevant_fire_location_empty_game() {
|
||||||
|
let status = CurrentGameStatus::default();
|
||||||
|
assert!(status.can_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
assert!(status.should_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn relevant_fire_location_two_failed_attempt_around() {
|
||||||
|
let mut status = CurrentGameStatus::default();
|
||||||
|
status
|
||||||
|
.opponent_map
|
||||||
|
.failed_strikes
|
||||||
|
.push(Coordinates::new(0, 1));
|
||||||
|
status
|
||||||
|
.opponent_map
|
||||||
|
.failed_strikes
|
||||||
|
.push(Coordinates::new(1, 0));
|
||||||
|
assert!(status.can_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
assert!(!status.should_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn relevant_fire_location_two_failed_attempt_smallest_boat_not_sunk() {
|
||||||
|
let mut status = CurrentGameStatus::default();
|
||||||
|
status
|
||||||
|
.opponent_map
|
||||||
|
.failed_strikes
|
||||||
|
.push(Coordinates::new(0, 2));
|
||||||
|
status
|
||||||
|
.opponent_map
|
||||||
|
.failed_strikes
|
||||||
|
.push(Coordinates::new(2, 0));
|
||||||
|
assert!(status.can_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
assert!(status.should_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn relevant_fire_location_two_failed_attempt_smallest_boat_sunk() {
|
||||||
|
let mut status = CurrentGameStatus::default();
|
||||||
|
status
|
||||||
|
.opponent_map
|
||||||
|
.failed_strikes
|
||||||
|
.push(Coordinates::new(0, 2));
|
||||||
|
status
|
||||||
|
.opponent_map
|
||||||
|
.failed_strikes
|
||||||
|
.push(Coordinates::new(2, 0));
|
||||||
|
status.opponent_map.sunk_boats.push(BoatPosition {
|
||||||
|
start: Coordinates::new(
|
||||||
|
status.rules.map_width as i32 - 1,
|
||||||
|
status.rules.map_height as i32 - 1,
|
||||||
|
),
|
||||||
|
len: 2,
|
||||||
|
direction: BoatDirection::Left,
|
||||||
|
});
|
||||||
|
assert!(status.can_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
assert!(!status.should_fire_at_location(Coordinates::new(0, 0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user