engine WIP
This commit is contained in:
parent
c9ceb5b2ab
commit
13aa9ffffe
73
tak_lib/src/engine.rs
Normal file
73
tak_lib/src/engine.rs
Normal 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]> {}
|
||||||
@ -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],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user