tile work
This commit is contained in:
parent
fdec2ae764
commit
c9ceb5b2ab
@ -2,6 +2,7 @@
|
||||
name = "tak_bot"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
default-run = "tak_bot"
|
||||
|
||||
[dependencies]
|
||||
tak_lib = { path = "../tak_lib" }
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use std::fmt::Display;
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
#[repr(u8)]
|
||||
@ -7,7 +7,7 @@ pub enum Color {
|
||||
Black = 1,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[repr(u8)]
|
||||
pub enum Piece {
|
||||
None = 0,
|
||||
@ -15,7 +15,7 @@ pub enum Piece {
|
||||
Wall = 2,
|
||||
Caps = 3,
|
||||
}
|
||||
impl Display for Piece {
|
||||
impl Debug for Piece {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Piece::None => write!(f, "----"),
|
||||
@ -50,6 +50,29 @@ impl ColoredPiece {
|
||||
unsafe { std::mem::transmute(piece_val) }
|
||||
}
|
||||
|
||||
/// Constructs a new `ColoredPiece` from the given raw value.
|
||||
pub fn from_u8_opt(val: u8) -> Option<Self> {
|
||||
if val <= 7 && val != 4 {
|
||||
// safety: value is checked to be in range
|
||||
Some(unsafe { std::mem::transmute(val) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs a new `ColoredPiece` from the given raw value.
|
||||
///
|
||||
/// ## Panics
|
||||
/// This panics if `val` is outside the range `0..=7` or is `4`.
|
||||
pub fn from_u8(val: u8) -> Self {
|
||||
if val <= 7 && val != 4 {
|
||||
// safety: value is checked to be in range
|
||||
unsafe { std::mem::transmute(val) }
|
||||
} else {
|
||||
panic!("`val` ({}) was not in range for `ColoredPiece`!", val);
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the color of the piece,
|
||||
/// returning `Color::White` if `self` is `None`.
|
||||
pub fn color(&self) -> Color {
|
||||
|
||||
@ -1,35 +1,84 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use crate::piece::Piece;
|
||||
use crate::piece::ColoredPiece;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Tile {
|
||||
/// The colors of the stacked pieces.
|
||||
/// A tile on the board.
|
||||
///
|
||||
/// bit 0 represents the top of the stack (not counting the top piece).
|
||||
stack: u64,
|
||||
/// The length of the stack.
|
||||
stack_len: u8,
|
||||
/// The piece that is on the tile
|
||||
piece: Piece,
|
||||
}
|
||||
/// bits [2:0] represent the top piece (if any).
|
||||
/// - bit [2] being the color.
|
||||
/// - bits [1:0] being the piece type (if any).
|
||||
/// bits [15:8] represent the number of pieces underneath the top piece.
|
||||
/// bits [127:16] are the colors of the stacked pieces.
|
||||
/// - bit [16] is the top-most piece, and bit [127] is the bottom-most piece.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Tile(u128);
|
||||
|
||||
impl Debug for Tile {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if self.stack_len == 0 {
|
||||
write!(f, "{}", self.piece)
|
||||
if self.stack_len() == 0 {
|
||||
self.top_piece().fmt(f)
|
||||
} else {
|
||||
let stack: String = (0..self.stack_len)
|
||||
let stack = self.stack();
|
||||
let stack: String = (0..self.stack_len())
|
||||
.rev()
|
||||
.map(|i| if (self.stack >> i) & 1 == 1 { 'w' } else { 'b' })
|
||||
.map(|i| if (stack >> i) == 1 { 'b' } else { 'w' })
|
||||
.collect();
|
||||
write!(f, "{}{}", stack, self.piece)
|
||||
write!(f, "{}:{:?}", stack, self.top_piece())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Tile {
|
||||
/// An empty tile.
|
||||
pub const EMPTY: Tile = Tile(0);
|
||||
|
||||
const PIECE_OFFSET: u8 = 0;
|
||||
const PIECE_MASK: u128 = 0b111u128;
|
||||
|
||||
const LEN_OFFSET: u8 = 8;
|
||||
const LEN_MASK: u128 = 0xFF00u128;
|
||||
|
||||
const STACK_OFFSET: u8 = 16;
|
||||
const STACK_MASK: u128 = !0xFFFFu128;
|
||||
|
||||
/// Gets the top piece.
|
||||
pub fn top_piece(&self) -> ColoredPiece {
|
||||
ColoredPiece::from_u8((self.0 & 0b111) as u8)
|
||||
}
|
||||
|
||||
/// Sets the top piece.
|
||||
pub fn set_top_piece(&mut self, piece: ColoredPiece) {
|
||||
// clear top_piece
|
||||
self.0 &= !Self::PIECE_MASK;
|
||||
// set top_piece
|
||||
self.0 |= (piece as u128) << Self::PIECE_OFFSET;
|
||||
}
|
||||
|
||||
/// Gets the length of the stack.
|
||||
pub fn stack_len(&self) -> u8 {
|
||||
self.stack_len
|
||||
(self.0 >> 8) as u8
|
||||
}
|
||||
|
||||
/// Sets the stack length.
|
||||
pub fn set_stack_len(&mut self, len: u8) {
|
||||
// clear stack_len
|
||||
self.0 &= !Self::LEN_MASK;
|
||||
// set stack_len
|
||||
self.0 |= (len as u128) << Self::LEN_OFFSET;
|
||||
}
|
||||
|
||||
/// Gets the stacked pieces as a bit array.
|
||||
///
|
||||
/// The LSB is the top-most piece, whereas the MSB is the bottom-most piece.
|
||||
pub fn stack(&self) -> u128 {
|
||||
self.0 >> Self::STACK_OFFSET
|
||||
}
|
||||
|
||||
/// Sets the stacked pieces.
|
||||
pub fn set_stack(&mut self, stack: u128) {
|
||||
// clear stack
|
||||
self.0 &= !Self::STACK_MASK;
|
||||
// set stack
|
||||
self.0 |= (stack as u128) << Self::STACK_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user