use std::iter::FromIterator;
use std::ops::{Index, IndexMut};
use crate::types::board::Board;
use crate::types::piece::Piece;
use crate::types::place::{File, Rank, Tier};
#[derive(Clone, Copy, Debug, Default)]
#[repr(transparent)]
pub struct Arena {
boards: [Board; 8],
}
impl Arena {
const SIZE: usize = 8;
pub fn new() -> Self {
Self::default()
}
pub fn all(&self) -> &[Board] {
&self.boards
}
pub fn get(&self, file: File, rank: Rank, tier: Tier) -> &Piece {
self.index(tier).get(file, rank)
}
#[doc(hidden)]
#[must_use]
pub fn var(&mut self, file: File, rank: Rank, tier: Tier) -> &mut Piece {
self.index_mut(tier).var(file, rank)
}
pub fn set(&mut self, file: File, rank: Rank, tier: Tier, piece: Piece) {
self.index_mut(tier).set(file, rank, piece);
}
pub fn del(&mut self, file: File, rank: Rank, tier: Tier) {
self.index_mut(tier).del(file, rank);
}
pub fn has(&self, file: File, rank: Rank, tier: Tier, piece: Piece) -> bool {
self.index(tier).get(file, rank).contains(piece)
}
#[doc(hidden)]
pub fn xy(&self) -> [Board; Self::SIZE] {
self.boards
}
#[doc(hidden)]
pub fn yz(&self) -> [Board; Self::SIZE] {
todo!()
}
#[doc(hidden)]
pub fn xz(&self) -> [Board; Self::SIZE] {
todo!()
}
#[must_use]
fn convert(tier: Tier) -> usize {
tier.convert()
}
}
impl From<[Board; Arena::SIZE]> for Arena {
fn from(value: [Board; Self::SIZE]) -> Self {
Self { boards: value }
}
}
impl FromIterator<Board> for Arena {
fn from_iter<I: IntoIterator<Item = Board>>(iter: I) -> Self {
let mut boards: [Board; Self::SIZE] = [Board::default(); Self::SIZE];
for (i, board) in iter.into_iter().enumerate() {
boards[i] = board;
}
Self { boards }
}
}
impl Index<Tier> for Arena {
type Output = Board;
fn index(&self, index: Tier) -> &Self::Output {
&self.boards[Self::convert(index)]
}
}
impl IndexMut<Tier> for Arena {
fn index_mut(&mut self, index: Tier) -> &mut Self::Output {
&mut self.boards[Self::convert(index)]
}
}