Created
March 3, 2021 11:07
-
-
Save reillysiemens/985a9a02f1983de4eab3c41315cc1674 to your computer and use it in GitHub Desktop.
Battleship, but it's an int.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! # Bitmask Battleship | |
//! | |
//! The ship sections and their status are maintained in a 17-bit mapping. A | |
//! zero bit means the section is OK and a one means the section has been hit. | |
//! | |
//! ```text,ignore | |
//! 1 | |
//! 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | |
//! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
//! | C | b | c | s | d | | |
//! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
//! | |
//! C: Carrier, b: Battleship, c: Cruiser, s: submarine, d: Destroyer | |
//! ``` | |
//! | |
//! ## Examples: | |
//! | |
//! - `0b00010111100000010`: The battleship has been sunk and the carrier and | |
//! destroyer have each suffered hits. | |
//! - `0b01100000001011100`: The submarine has been sunk and the carrier and | |
//! cruiser have each suffered hits. | |
use std::fmt; | |
#[derive(Debug, PartialEq)] | |
pub struct Player { | |
pub name: String, | |
pub ships: u32, | |
} | |
impl Player { | |
// (Mask,shift) tuples for retrieving individual ships. | |
const CARRIER: (u32, u8) = (0b11111_0000_000_000_00, 12); | |
const BATTLESHIP: (u32, u8) = (0b00000_1111_000_000_00, 8); | |
const CRUISER: (u32, u8) = (0b00000_0000_111_000_00, 5); | |
const SUBMARINE: (u32, u8) = (0b00000_0000_000_111_00, 2); | |
const DESTROYER: (u32, u8) = (0b00000_0000_000_000_11, 0); | |
/// Create a new player. | |
pub fn new(name: String) -> Self { | |
Player { | |
name, | |
ships: 0b00000_0000_000_000_00, | |
} | |
} | |
/// Retrive the carrier from the player's ships. | |
pub fn carrier(&self) -> u32 { | |
(self.ships & Self::CARRIER.0) >> Self::CARRIER.1 | |
} | |
/// Retrive the battleship from the player's ships. | |
pub fn battleship(&self) -> u32 { | |
(self.ships & Self::BATTLESHIP.0) >> Self::BATTLESHIP.1 | |
} | |
/// Retrive the cruiser from the player's ships. | |
pub fn cruiser(&self) -> u32 { | |
(self.ships & Self::CRUISER.0) >> Self::CRUISER.1 | |
} | |
/// Retrive the submarine from the player's ships. | |
pub fn submarine(&self) -> u32 { | |
(self.ships & Self::SUBMARINE.0) >> Self::SUBMARINE.1 | |
} | |
/// Retrive the destroyer from the player's ships. | |
pub fn destroyer(&self) -> u32 { | |
(self.ships & Self::DESTROYER.0) >> Self::DESTROYER.1 | |
} | |
} | |
impl fmt::Display for Player { | |
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
write!(f, "{}: {:#019b}", self.name, self.ships,) | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use super::Player; | |
#[test] | |
fn test_ships() { | |
let p1 = Player { | |
name: "Player 1".to_string(), | |
ships: 0b00010_1111_000_000_10, | |
}; | |
assert_eq!(p1.carrier(), 0b00010); | |
assert_eq!(p1.battleship(), 0b1111); | |
assert_eq!(p1.cruiser(), 0b000); | |
assert_eq!(p1.submarine(), 0b000); | |
assert_eq!(p1.destroyer(), 0b10); | |
} | |
#[test] | |
fn test_display() { | |
let p1 = Player { | |
name: "Player 1".to_string(), | |
ships: 0b00010_1111_000_000_10, | |
}; | |
assert_eq!( | |
format!("{}", p1), | |
"Player 1: 0b00010111100000010".to_string() | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment