zchess 0.1.0

(WIP) A library for calculating chess moves in a 3-dimensional space.
Documentation
// std...
use std::iter::FromIterator;
use std::ops::{Index, IndexMut};

// types...
use crate::types::board::Board;
use crate::types::piece::Piece;
use crate::types::place::{File, Rank, Tier};

/// Represents a chess arena (3D extension of a chess board).
#[derive(Clone, Copy, Debug, Default)]
#[repr(transparent)]
pub struct Arena {
    boards: [Board; 8],
}

impl Arena {
    /// Represents the number of [`Board`]s stored.
    const SIZE: usize = 8;

    /// Returns a new [`Arena`].
    pub fn new() -> Self {
        Self::default()
    }

    /// Returns all of the [`Board`]s stored.
    pub fn all(&self) -> &[Board] {
        &self.boards
    }

    /// Returns a reference to the [`Piece`] stored at the specified location.
    pub fn get(&self, file: File, rank: Rank, tier: Tier) -> &Piece {
        self.index(tier).get(file, rank)
    }

    /// Returns a mutable reference to the [`Piece`] stored at the specified location.
    #[doc(hidden)]
    #[must_use]
    pub fn var(&mut self, file: File, rank: Rank, tier: Tier) -> &mut Piece {
        self.index_mut(tier).var(file, rank)
    }

    /// Sets the [`Piece`] stored at the specified location.
    pub fn set(&mut self, file: File, rank: Rank, tier: Tier, piece: Piece) {
        self.index_mut(tier).set(file, rank, piece);
    }

    /// Deletes the [`Piece`] stored at the specified location.
    pub fn del(&mut self, file: File, rank: Rank, tier: Tier) {
        self.index_mut(tier).del(file, rank);
    }

    /// Returns whether the [`Piece`] found at the specified location matches the [`Piece`] provided.
    pub fn has(&self, file: File, rank: Rank, tier: Tier, piece: Piece) -> bool {
        self.index(tier).get(file, rank).contains(piece)
    }

    /// Returns xy-views of the [`Board`]s.
    #[doc(hidden)]
    pub fn xy(&self) -> [Board; Self::SIZE] {
        self.boards
    }

    /// Returns yz-views of the [`Board`]s.
    #[doc(hidden)]
    pub fn yz(&self) -> [Board; Self::SIZE] {
        todo!()
    }

    /// Returns xz-views of the [`Board`]s.
    #[doc(hidden)]
    pub fn xz(&self) -> [Board; Self::SIZE] {
        todo!()
    }

    /// Converts the [`Tier`] provided to an indexable value.
    #[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)]
    }
}