engine WIP

This commit is contained in:
Mitchell Marino 2025-12-21 20:15:59 -06:00
parent c9ceb5b2ab
commit 13aa9ffffe
2 changed files with 146 additions and 1 deletions

73
tak_lib/src/engine.rs Normal file
View File

@ -0,0 +1,73 @@
use crate::{
Board, Direction, Move,
piece::{ColoredPiece, Piece},
};
impl<const N: usize> Board<N> {
pub fn moves(&self) -> impl Iterator<Item = Move<N>> {
let to_move = self.to_move;
let tiles = &self.tiles;
let can_place_caps = if Self::N_CAPS == 0 {
false
} else {
let caps_on_board = self
.tiles
.iter()
.flat_map(|col| col.iter())
.filter(|t| {
let piece = t.top_piece();
piece.color_opt() == Some(to_move) && piece.piece() == Piece::Caps
})
.count() as u8;
caps_on_board < Self::N_CAPS
};
let chords = (0..(N as u8)).flat_map(|x| (0..(N as u8)).map(move |y| (x, y)));
chords.flat_map(move |(x, y)| {
let top_piece = tiles[x as usize][y as usize].top_piece();
if top_piece == ColoredPiece::None {
// possible moves are place moves
get_placement_moves(x, y, can_place_caps)
} else if top_piece.color() == to_move {
get_movement_moves(x, y, tiles[x as usize][y as usize].stack_len())
} else {
Vec::with_capacity(0)
}
})
}
}
fn get_placement_moves<const N: usize>(x: u8, y: u8, can_place_caps: bool) -> Vec<Move<N>> {
let mut moves = Vec::with_capacity(2 + can_place_caps as usize);
moves.push(Move::Place {
piece: Piece::Flat,
at: (x, y),
});
moves.push(Move::Place {
piece: Piece::Wall,
at: (x, y),
});
if can_place_caps {
moves.push(Move::Place {
piece: Piece::Caps,
at: (x, y),
});
}
moves
}
fn get_movement_moves<const N: usize>(x: u8, y: u8, stack_len: u8) -> Vec<Move<N>> {
let max_grab = u8::min(N as u8, stack_len + 1);
// East
let max_dist_east = max_grab.min(N as u8 - x - 1);
// North
let max_dist_north = max_grab.min(N as u8 - y - 1);
// West
let max_dist_west = max_grab.min(x);
// South
let max_dist_south = max_grab.min(y);
}
fn get_drop_amounts<const N: usize>(max_grab: u8, max_dist: u8) -> impl Iterator<Item = [u8; N]> {}

View File

@ -1,10 +1,82 @@
pub mod engine;
pub mod piece; pub mod piece;
pub mod tile; pub mod tile;
use crate::{piece::Color, tile::Tile}; use crate::{
piece::{Color, Piece},
tile::Tile,
};
use std::fmt::Display;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Direction {
East,
North,
West,
South,
}
impl Display for Direction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Direction::East => write!(f, "e"),
Direction::North => write!(f, "n"),
Direction::West => write!(f, "w"),
Direction::South => write!(f, "s"),
}
}
}
impl Direction {
const ALL: [Direction; 4] = [
Direction::East,
Direction::North,
Direction::West,
Direction::South,
];
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub struct Board<const N: usize> { pub struct Board<const N: usize> {
to_move: Color, to_move: Color,
tiles: [[Tile; N]; N], tiles: [[Tile; N]; N],
} }
impl<const N: usize> Board<N> {
/// The number of capstones in each players' pouches.
pub const N_STONES: u8 = match N {
3 => 10,
4 => 15,
5 => 21,
6 => 30,
8 => 50,
_ => panic!("N must be 3, 4, 5, 6, or 8"),
};
/// The number of capstones in the players' pouches.
pub const N_CAPS: u8 = match N {
3 => 0,
4 => 0,
5 => 1,
6 => 1,
8 => 2,
_ => panic!("N must be 3, 4, 5, 6, or 8"),
};
pub fn new() -> Self {
Board {
to_move: Color::White,
tiles: [[Tile::EMPTY; N]; N],
}
}
}
pub enum Move<const N: usize> {
Place {
piece: Piece,
at: (u8, u8),
},
Move {
from: (u8, u8),
count: u8,
dir: Direction,
drop: [u8; N],
},
}