*: move from /*** */ doc-comments to ///
This commit is contained in:
@@ -6,15 +6,15 @@ ExactSizeIterator => Map<Range<i64>> is not an ESI. But Range<i32> is an ESI.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
impl Rank {
|
impl Rank {
|
||||||
/** Generate an iterator over all ranks. */
|
/// Generate an iterator over all ranks.
|
||||||
pub fn iter_all() -> impl ExactSizeIterator<Item = Rank> {
|
pub fn iter_all() -> impl ExactSizeIterator<Item = Rank> {
|
||||||
(0i32..13)
|
(0i32..13)
|
||||||
.map(|n| n as i64)
|
.map(|n| n as i64)
|
||||||
.map(|n| Rank::try_from(n).unwrap())
|
.map(|n| Rank::try_from(n).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over all cards within a rank, ordered by Suit. The
|
/// Generate an iterator over all cards within a rank, ordered by Suit. The
|
||||||
cards are all default initialised w.r.t. deck (0).*/
|
/// cards are all default initialised w.r.t. deck (0).
|
||||||
pub fn cards(self) -> impl ExactSizeIterator<Item = Card> {
|
pub fn cards(self) -> impl ExactSizeIterator<Item = Card> {
|
||||||
let n = self as i32;
|
let n = self as i32;
|
||||||
((n * 4)..((n + 1) * 4)).map(|x| Card::from(x as i64))
|
((n * 4)..((n + 1) * 4)).map(|x| Card::from(x as i64))
|
||||||
@@ -22,13 +22,13 @@ impl Rank {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Suit {
|
impl Suit {
|
||||||
/** Generate an iterator over all suits. */
|
/// Generate an iterator over all suits.
|
||||||
pub fn iter_all() -> impl ExactSizeIterator<Item = Suit> {
|
pub fn iter_all() -> impl ExactSizeIterator<Item = Suit> {
|
||||||
(0i32..4).map(|n| Suit::try_from(n as i64).unwrap())
|
(0i32..4).map(|n| Suit::try_from(n as i64).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over all cards within a suit, ordered by Rank. The
|
/// Generate an iterator over all cards within a suit, ordered by Rank. The
|
||||||
cards are all default initialised in terms of deck (0).*/
|
/// cards are all default initialised in terms of deck (0).
|
||||||
pub fn cards(self) -> impl ExactSizeIterator<Item = Card> {
|
pub fn cards(self) -> impl ExactSizeIterator<Item = Card> {
|
||||||
Rank::iter_all().map(move |rank| Card::make_playing_card(0, rank, self))
|
Rank::iter_all().map(move |rank| Card::make_playing_card(0, rank, self))
|
||||||
}
|
}
|
||||||
@@ -45,8 +45,8 @@ impl PlayingCard {
|
|||||||
(rank * 4) + suit
|
(rank * 4) + suit
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over all Playing Cards in the `nth` deck. By
|
/// Generate an iterator over all Playing Cards in the `nth` deck. By
|
||||||
construction this is in ascending order. */
|
/// construction this is in ascending order.
|
||||||
pub fn iter_all(n: i64) -> impl ExactSizeIterator<Item = Self> {
|
pub fn iter_all(n: i64) -> impl ExactSizeIterator<Item = Self> {
|
||||||
(0i32..52)
|
(0i32..52)
|
||||||
.map(|x| x as i64)
|
.map(|x| x as i64)
|
||||||
@@ -90,12 +90,11 @@ impl Card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate an iterator over a `n` decks of Cards. Each deck is
|
/// Generate an iterator over `n` decks of Cards. Each deck is concatenated
|
||||||
concatenated together. By construction, each "deck" of the iterator is in
|
/// together. By construction, each "deck" of the iterator is in ascending
|
||||||
ascending order.
|
/// order.
|
||||||
|
///
|
||||||
Note that each deck gets two jokers.
|
/// Note that each deck gets two jokers.
|
||||||
*/
|
|
||||||
pub fn iter_all(n: i64) -> impl Iterator<Item = Card> {
|
pub fn iter_all(n: i64) -> impl Iterator<Item = Card> {
|
||||||
// NOTE: I cannot make this into an ExactSizeIterator using the i32
|
// NOTE: I cannot make this into an ExactSizeIterator using the i32
|
||||||
// trick. Chain<ESI, ESI> is not an ESI, nor is FlatMap<T,U,T->U>
|
// trick. Chain<ESI, ESI> is not an ESI, nor is FlatMap<T,U,T->U>
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
use crate::card::{Card, PlayingCard, Rank, Suit};
|
use crate::card::{Card, PlayingCard, Rank, Suit};
|
||||||
|
|
||||||
|
/// Excessively simple card iterator.
|
||||||
pub struct CardIterator(Card);
|
pub struct CardIterator(Card);
|
||||||
|
|
||||||
impl Iterator for CardIterator {
|
impl Iterator for CardIterator {
|
||||||
type Item = Card;
|
type Item = Card;
|
||||||
|
|
||||||
|
/// Generate the next card in the deck based on the current state of the
|
||||||
|
/// CardIterator. Iteration terminates at the 2 of Spades for the current
|
||||||
|
/// deck.
|
||||||
fn next(&mut self) -> Option<Card> {
|
fn next(&mut self) -> Option<Card> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Card::Joker(_) => None,
|
Card::Joker(_) => None,
|
||||||
@@ -25,6 +29,9 @@ impl Iterator for CardIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DoubleEndedIterator for CardIterator {
|
impl DoubleEndedIterator for CardIterator {
|
||||||
|
/// Generate the previous card in the deck based on the current state of the
|
||||||
|
/// CardIterator. Iteration terminates at the 3 of Diamonds for the current
|
||||||
|
/// deck.
|
||||||
fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
|
fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Card::Joker(_) => None,
|
Card::Joker(_) => None,
|
||||||
@@ -45,6 +52,8 @@ impl DoubleEndedIterator for CardIterator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Card {
|
impl Card {
|
||||||
|
/// Create a CardIterator from the current card, moving the card in the
|
||||||
|
/// process.
|
||||||
pub fn into_iter(self) -> CardIterator {
|
pub fn into_iter(self) -> CardIterator {
|
||||||
CardIterator(self)
|
CardIterator(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
/** Given an array of arguments, return them sorted.
|
/// Given an array of arguments, return them sorted. Best utilised with array
|
||||||
Best utilised with array destructuring. */
|
/// destructuring.
|
||||||
pub fn ordered<T: Ord, const N: usize>(mut xs: [T; N]) -> [T; N] {
|
pub fn ordered<T: Ord, const N: usize>(mut xs: [T; N]) -> [T; N] {
|
||||||
xs.sort();
|
xs.sort();
|
||||||
xs
|
xs
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An iterator adaptor (derived from ExactSizedIterator) which has a guaranteed
|
/// An iterator adaptor (derived from ExactSizedIterator) which has a guaranteed
|
||||||
compile time size, allowing for collection of an iterator into a stack allocated
|
/// compile time size, allowing for collection of an iterator into a stack
|
||||||
array. */
|
/// allocated array.
|
||||||
pub trait ExactSizedArr<I>: ExactSizeIterator<Item = I> + Sized
|
pub trait ExactSizedArr<I>: ExactSizeIterator<Item = I> + Sized
|
||||||
where
|
where
|
||||||
I: Default,
|
I: Default,
|
||||||
@@ -21,7 +21,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Default implementation of ExactSizedArr for any ExactSizeIterator. */
|
/// Default implementation of ExactSizedArr for any ExactSizeIterator.
|
||||||
impl<T, I> ExactSizedArr<T> for I
|
impl<T, I> ExactSizedArr<T> for I
|
||||||
where
|
where
|
||||||
T: Default + Copy + Clone,
|
T: Default + Copy + Clone,
|
||||||
@@ -29,9 +29,9 @@ where
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A macro which generates Eq, PartialEq, and PartialOrd implementations for
|
/// A macro which generates Eq, PartialEq, and PartialOrd implementations for
|
||||||
some given type. These implementations are dependent on Ord already being
|
/// some given type. These implementations are dependent on Ord already being
|
||||||
implemented for that type. */
|
/// implemented for that type.
|
||||||
macro_rules! impl_cmp_eq_on_ord {
|
macro_rules! impl_cmp_eq_on_ord {
|
||||||
($type:ident) => {
|
($type:ident) => {
|
||||||
impl PartialEq for $type {
|
impl PartialEq for $type {
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ pub trait Hand: Ord {
|
|||||||
!self.is_proper()
|
!self.is_proper()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Given two instances of a Hand (`self` and `other`), verify if `self`
|
/// Given two instances of a Hand (`self` and `other`), verify if `self`
|
||||||
footstools `other`.
|
/// footstools `other`.
|
||||||
*/
|
|
||||||
fn footstool(&self, other: &Self) -> Footstool;
|
fn footstool(&self, other: &Self) -> Footstool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,12 +28,11 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/** Given two hands, assert that applying a footstool both ways fits a
|
/// Given two hands, assert that applying a footstool both ways fits a
|
||||||
recognised basic pattern for footstools (in a generic sense). Return the
|
/// recognised basic pattern for footstools (in a generic sense). Return
|
||||||
results of the two footstool checks (x on y, y on x).
|
/// the results of the two footstool checks (x on y, y on x).
|
||||||
|
///
|
||||||
Obviously may panic.
|
/// Obviously may panic.
|
||||||
*/
|
|
||||||
pub fn test_footstool<T>(x: &T, y: &T) -> (Footstool, Footstool)
|
pub fn test_footstool<T>(x: &T, y: &T) -> (Footstool, Footstool)
|
||||||
where
|
where
|
||||||
T: Hand + Copy + Display + Debug,
|
T: Hand + Copy + Display + Debug,
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ use crate::card::Card;
|
|||||||
pub struct Single(Card);
|
pub struct Single(Card);
|
||||||
|
|
||||||
impl Single {
|
impl Single {
|
||||||
/** Create a new single from a card `c`. Will return None if a Single
|
/// Create a new single from a card `c`. Will return None if a Single
|
||||||
cannot be constructed from that card.
|
/// cannot be constructed from that card.
|
||||||
|
///
|
||||||
The only situation where a card cannot be converted into a Single is if it's
|
/// The only situation where a card cannot be converted into a Single is if
|
||||||
a Joker.
|
/// it's a Joker.
|
||||||
*/
|
|
||||||
pub fn new(c: Card) -> Option<Single> {
|
pub fn new(c: Card) -> Option<Single> {
|
||||||
matches!(c, Card::PlayingCard(_)).then_some(Single(c))
|
matches!(c, Card::PlayingCard(_)).then_some(Single(c))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ use crate::{card::Card, helper::ordered};
|
|||||||
pub struct Triple(Card, Card, Card);
|
pub struct Triple(Card, Card, Card);
|
||||||
|
|
||||||
impl Triple {
|
impl Triple {
|
||||||
/** Create a new triple utilising 3 cards: `c1`, `c2`, and `c3`. Will
|
/// Create a new triple utilising 3 cards: `c1`, `c2`, and `c3`. Will
|
||||||
return None iff a Triple cannot be constructed out of those 3 cards.
|
/// return None iff a Triple cannot be constructed out of those 3 cards.
|
||||||
|
///
|
||||||
NOTE: By construction, if a triple includes 1 Joker, then Triple::0 is that
|
/// NOTE: By construction, if a triple includes 1 Joker, then Triple::0 is
|
||||||
joker. If a triple includes 2 jokers, then Triple::0 and Triple::1 are
|
/// that joker. If a triple includes 2 jokers, then Triple::0 and Triple::1
|
||||||
those jokers. This means Triple::2 will always be a valid playing card.
|
/// are those jokers. This means Triple::2 will always be a valid playing
|
||||||
*/
|
/// card.
|
||||||
pub fn new(c1: Card, c2: Card, c3: Card) -> Option<Triple> {
|
pub fn new(c1: Card, c2: Card, c3: Card) -> Option<Triple> {
|
||||||
let [c1, c2, c3] = ordered([c1, c2, c3]);
|
let [c1, c2, c3] = ordered([c1, c2, c3]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user