Skip to content

Instantly share code, notes, and snippets.

@reillysiemens
Created March 3, 2021 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reillysiemens/985a9a02f1983de4eab3c41315cc1674 to your computer and use it in GitHub Desktop.
Save reillysiemens/985a9a02f1983de4eab3c41315cc1674 to your computer and use it in GitHub Desktop.
Battleship, but it's an int.
//! # 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