Compare commits
No commits in common. "c9ceb5b2ab7ee38ba218124b1732afa5dde0fb17" and "2e344fed0a327f9662663a7bddb2b5b1252f99ba" have entirely different histories.
c9ceb5b2ab
...
2e344fed0a
19
.gitignore
vendored
19
.gitignore
vendored
@ -1,19 +0,0 @@
|
|||||||
# will have compiled files and executables
|
|
||||||
debug/
|
|
||||||
target/
|
|
||||||
.vscode/
|
|
||||||
.zed/
|
|
||||||
.helix/
|
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
|
||||||
**/*.rs.bk
|
|
||||||
|
|
||||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
|
||||||
*.pdb
|
|
||||||
|
|
||||||
# RustRover
|
|
||||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
||||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
||||||
#.idea/
|
|
||||||
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -1,22 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 4
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tak_bot"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"tak_lib",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tak_lib"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tak_server"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tak_visualizer"
|
|
||||||
version = "0.1.0"
|
|
||||||
@ -2,7 +2,5 @@
|
|||||||
name = "tak_bot"
|
name = "tak_bot"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
default-run = "tak_bot"
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tak_lib = { path = "../tak_lib" }
|
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
pub mod piece;
|
pub fn add(left: u64, right: u64) -> u64 {
|
||||||
pub mod tile;
|
left + right
|
||||||
|
}
|
||||||
use crate::{piece::Color, tile::Tile};
|
|
||||||
|
#[cfg(test)]
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
mod tests {
|
||||||
pub struct Board<const N: usize> {
|
use super::*;
|
||||||
to_move: Color,
|
|
||||||
tiles: [[Tile; N]; N],
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,105 +0,0 @@
|
|||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum Color {
|
|
||||||
White = 0,
|
|
||||||
Black = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum Piece {
|
|
||||||
None = 0,
|
|
||||||
Flat = 1,
|
|
||||||
Wall = 2,
|
|
||||||
Caps = 3,
|
|
||||||
}
|
|
||||||
impl Debug for Piece {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Piece::None => write!(f, "----"),
|
|
||||||
Piece::Flat => write!(f, "Flat"),
|
|
||||||
Piece::Wall => write!(f, "Wall"),
|
|
||||||
Piece::Caps => write!(f, "Caps"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum ColoredPiece {
|
|
||||||
None = 0,
|
|
||||||
WhiteFlat = 1,
|
|
||||||
WhiteWall = 2,
|
|
||||||
WhiteCaps = 3,
|
|
||||||
|
|
||||||
BlackFlat = 5,
|
|
||||||
BlackWall = 6,
|
|
||||||
BlackCaps = 7,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColoredPiece {
|
|
||||||
/// Constructs a new `ColoredPiece`.
|
|
||||||
pub fn new(piece: Piece, color: Color) -> Self {
|
|
||||||
let mut piece_val = (piece as u8) | ((color as u8) << 2);
|
|
||||||
if piece_val == 4 {
|
|
||||||
piece_val = 0;
|
|
||||||
}
|
|
||||||
// safety: value will always be in range
|
|
||||||
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 {
|
|
||||||
if (*self as u8 >> 2) == 1 {
|
|
||||||
Color::Black
|
|
||||||
} else {
|
|
||||||
Color::White
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the color of the piece,
|
|
||||||
/// returning `None` if `self` is `None`.
|
|
||||||
pub fn color_opt(&self) -> Option<Color> {
|
|
||||||
let val = *self as u8;
|
|
||||||
if val == 0 {
|
|
||||||
return None;
|
|
||||||
} else if (val >> 2) == 1 {
|
|
||||||
Some(Color::Black)
|
|
||||||
} else {
|
|
||||||
Some(Color::White)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the piece type of this piece.
|
|
||||||
pub fn piece(&self) -> Piece {
|
|
||||||
let piece_val = *self as u8 & 0b11;
|
|
||||||
// safety: value will always be in range
|
|
||||||
unsafe { std::mem::transmute(piece_val) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
use crate::piece::ColoredPiece;
|
|
||||||
|
|
||||||
/// A tile on the board.
|
|
||||||
///
|
|
||||||
/// 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 {
|
|
||||||
self.top_piece().fmt(f)
|
|
||||||
} else {
|
|
||||||
let stack = self.stack();
|
|
||||||
let stack: String = (0..self.stack_len())
|
|
||||||
.rev()
|
|
||||||
.map(|i| if (stack >> i) == 1 { 'b' } else { 'w' })
|
|
||||||
.collect();
|
|
||||||
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.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