pub struct BasicPile(/* private fields */);Implementations§
Source§impl BasicPile
impl BasicPile
Sourcepub fn draw(&mut self, n: usize) -> Option<Self>
pub fn draw(&mut self, n: usize) -> Option<Self>
Returns n number of BasicCards from the
beginning of the BasicPile. If there are not enough cards in the BasicPile to satisfy
the request, None is returned.
CoPilot’s suggestion:
use card_game_engine::prelude::{BasicPile, Pile};
Where TF is CoPilot getting card_game_engine from???use cardpack::prelude::*;
let mut pile = Pinochle::deck().into_basic_pile();
let hand = pile.draw(5).unwrap();
assert_eq!(hand.to_string(), "A♠ A♠ T♠ T♠ K♠");Sourcepub fn draw_first(&mut self) -> Option<BasicCard>
pub fn draw_first(&mut self) -> Option<BasicCard>
This is very much suboptimal, but I don’t have an easy way to avoid it. My common currency is vectors. The idea of treating the end of the vector as the top of the deck seems like a good one.
Sourcepub fn shuffle(&mut self)
pub fn shuffle(&mut self)
Shuffles the BasicPile in place using the process default RNG
(rand::rng()). For deterministic shuffling, use
shuffle_with_seed.
Sourcepub fn shuffled(&self) -> Self
pub fn shuffled(&self) -> Self
Returns a new shuffled version of the BasicPile.
For deterministic shuffling, use
shuffled_with_seed.
Sourcepub fn shuffle_with_seed(&mut self, seed: u64)
pub fn shuffle_with_seed(&mut self, seed: u64)
Shuffles the BasicPile in place deterministically from a u64 seed.
Uses rand::rngs::StdRng internally. Same seed produces the same
permutation within one rand major version; a rand upgrade may
change the result. For long-lived replay logs or cross-version
reproducibility, pass a portable RNG (e.g., ChaCha8Rng from
rand_chacha) to shuffle_with_rng instead.
use cardpack::prelude::*;
let pile = Pile::<Standard52>::basic_pile();
let a = pile.shuffled_with_seed(42);
let b = pile.shuffled_with_seed(42);
assert_eq!(a, b);Sourcepub fn shuffled_with_seed(&self, seed: u64) -> Self
pub fn shuffled_with_seed(&self, seed: u64) -> Self
Returns a new BasicPile shuffled deterministically from a u64 seed.
See shuffle_with_seed for the
portability caveat.
Sourcepub fn shuffle_with_rng<R: Rng + ?Sized>(&mut self, rng: &mut R)
pub fn shuffle_with_rng<R: Rng + ?Sized>(&mut self, rng: &mut R)
Shuffles the BasicPile in place using the caller’s RNG.
Generic over any R: Rng + ?Sized. The seed-based methods are sugar
over this primitive — pass your own RNG (e.g., ChaCha8Rng) for
algorithm-stable reproducibility across rand major-version bumps.
Sourcepub fn shuffled_with_rng<R: Rng + ?Sized>(&self, rng: &mut R) -> Self
pub fn shuffled_with_rng<R: Rng + ?Sized>(&self, rng: &mut R) -> Self
Returns a new BasicPile shuffled using the caller’s RNG.
pub fn contains(&self, card: &BasicCard) -> bool
pub fn extend(&mut self, other: &Self)
pub fn first(&self) -> Option<&BasicCard>
pub fn get(&self, position: usize) -> Option<&BasicCard>
pub fn is_empty(&self) -> bool
pub fn iter(&self) -> Iter<'_, BasicCard> ⓘ
pub fn len(&self) -> usize
pub fn pop(&mut self) -> Option<BasicCard>
pub fn push(&mut self, card: BasicCard)
pub fn reverse(&mut self)
pub fn remove(&mut self, position: usize) -> BasicCard
pub fn sort(&mut self)
Sourcepub fn sort_by_rank(&mut self)
pub fn sort_by_rank(&mut self)
This sorts the cards by rank instead of suit.
use cardpack::prelude::*;
let mut hand = BasicPile::from(vec![FrenchBasicCard::KING_SPADES, FrenchBasicCard::ACE_DIAMONDS]);
// By default `BasicPile` sorts by suit.
hand.sort();
assert_eq!(hand.to_string(), "K♠ A♦");
hand.sort_by_rank();
assert_eq!(hand.to_string(), "A♦ K♠");Sourcepub fn sorted(&self) -> Self
pub fn sorted(&self) -> Self
Returns a new BasicPile sorted.
use cardpack::prelude::*;
assert_eq!(basic!("2♠ A♣ 3♠ 4♠ 5♣").sorted().to_string(), "4♠ 3♠ 2♠ A♣ 5♣");Sourcepub fn sorted_by_rank(self) -> Self
pub fn sorted_by_rank(self) -> Self
Returns a new BasicPile with the BasicCards sorted.
use cardpack::prelude::*;
assert_eq!(basic!("2♠ A♣ 3♠ 4♠ 5♣").sorted_by_rank().to_string(), "A♣ 5♣ 4♠ 3♠ 2♠");Trait Implementations§
Source§impl<'de> Deserialize<'de> for BasicPile
impl<'de> Deserialize<'de> for BasicPile
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Display for BasicPile
use cardpack::prelude::*;
let hand = BasicPile::from(
vec![
FrenchBasicCard::NINE_CLUBS,
FrenchBasicCard::EIGHT_DIAMONDS,
FrenchBasicCard::SEVEN_CLUBS,
]
);
assert_eq!(hand.to_string(), "9♣ 8♦ 7♣");
impl Display for BasicPile
use cardpack::prelude::*;
let hand = BasicPile::from(
vec![
FrenchBasicCard::NINE_CLUBS,
FrenchBasicCard::EIGHT_DIAMONDS,
FrenchBasicCard::SEVEN_CLUBS,
]
);
assert_eq!(hand.to_string(), "9♣ 8♦ 7♣");impl Eq for BasicPile
Source§impl FromIterator<BasicCard> for BasicPile
impl FromIterator<BasicCard> for BasicPile
Source§impl FromIterator<BasicPile> for Combos
impl FromIterator<BasicPile> for Combos
Source§impl<'a> IntoIterator for &'a BasicPile
A win for CoPilot!
impl<'a> IntoIterator for &'a BasicPile
A win for CoPilot!
I initially got an error from the Rust compiler:
warning: `iter` method without an `IntoIterator` impl for `&Pile`
--> src/basic/types/pile.rs:163:5
|
163 | / pub fn iter(&self) -> std::slice::Iter<BasicCard> {
164 | | self.0.iter()
165 | | }
| |_____^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#iter_without_into_iter
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![warn(clippy::pedantic)]
| ^^^^^^^^^^^^^^^^
= note: `#[warn(clippy::iter_without_into_iter)]` implied by `#[warn(clippy::pedantic)]`
help: consider implementing `IntoIterator` for `&Pile`
|
14 +
15 + impl IntoIterator for &Pile {
16 + type Item = &basic::types::basic_card::BasicCard;
17 + type IntoIter = std::slice::Iter<'_, basic::types::basic_card::BasicCard>;
18 + fn into_iter(self) -> Self::IntoIter {
19 + self.iter()
20 + }
21 + }
|Trying this code recommendation created the following error:
error: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
--> src/basic/types/pile.rs:281:17
|
281 | type Item = &basic::types::basic_card::BasicCard;
| ^ this lifetime must come from the implemented type
error[E0637]: `'_` cannot be used here
--> src/basic/types/pile.rs:282:38
|
282 | type IntoIter = std::slice::Iter<'_, basic::types::basic_card::BasicCard>;
| ^^ `'_` is a reserved lifetime name
error[E0433]: failed to resolve: use of undeclared crate or module `basic`
--> src/basic/types/pile.rs:281:18
|
281 | type Item = &basic::types::basic_card::BasicCard;
| ^^^^^ use of undeclared crate or module `basic`
|
help: consider importing this module
|
1 + use crate::basic::types::basic_card;
|
help: if you import `basic_card`, refer to it directly
|
281 - type Item = &basic::types::basic_card::BasicCard;
281 + type Item = &basic_card::BasicCard;
|
error[E0433]: failed to resolve: use of undeclared crate or module `basic`
--> src/basic/types/pile.rs:282:42
|
282 | type IntoIter = std::slice::Iter<'_, basic::types::basic_card::BasicCard>;
| ^^^^^ use of undeclared crate or module `basic`
|
help: consider importing this module
|
1 + use crate::basic::types::basic_card;
|
help: if you import `basic_card`, refer to it directly
|
282 - type IntoIter = std::slice::Iter<'_, basic::types::basic_card::BasicCard>;
282 + type IntoIter = std::slice::Iter<'_, basic_card::BasicCard>;
|This does give me hope that the mighty Rust compiler isn’t infallible. This does, however,
provide one with a moment’s pause, that one has to be careful, even when getting advice from
the final arbiter of truth in Rustlevania.
This led me to some DuckDuckGoing where I found an useful
article by wrongbyte.
After playing around with that I came up with this:
impl<'a> IntoIterator for &Pile {
type Item = &'a BasicCard;
type IntoIter = std::slice::Iter<'a, BasicCard>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}which got us down to one error:
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/basic/types/pile.rs:326:6
|
326 | impl<'a> IntoIterator for &Pile {
| ^^ unconstrained lifetime parameterAh yes, the dreaded error #E0207, my old friend.
This is why coding in Rust is maybe not the best of ideas for idiot savants like me who
had diving into this level of trivia. Maybe I’m a Zig developer in a Rust devs body or
something, but I just want this shit to work.
Up till now, CoPilot has been just regurgitating back out the code I already wrote. In a
final hail mary I decided to ask it and see what it came up with.
How do I fix the “the lifetime parameter
'ais not constrained by the impl trait, self type, or predicates” error on impl<’a> IntoIterator for &Pile
The error “the lifetime parameter ’a is not constrained by the impl trait, self type, or predicates” occurs because the lifetime ’a is not used in the trait implementation. To fix this, you need to specify the lifetime parameter correctly in the
IntoIteratorimplementation.
And you can see it in action below. I was throwing lifeline’s all over the place, with no luck. I’ll be honest with you, I am grokking the logic behind their placement about as much as I was getting 11th grade Trig sitting behind Amy G. Mind you, this was the Golden age of Guess Jeans, so I am not entirely at fault here.
Here is the corrected implementation:
Source§impl IntoIterator for BasicPile
impl IntoIterator for BasicPile
Source§impl Ord for BasicPile
impl Ord for BasicPile
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for BasicPile
impl PartialOrd for BasicPile
Source§impl Ranged for BasicPile
impl Ranged for BasicPile
Source§fn my_basic_pile(&self) -> BasicPile
fn my_basic_pile(&self) -> BasicPile
Ranged trait. Since none of the
logic behind any of these methods requires the boundary provided by the generic Pile struct,
since it is based entirely on the raw data in the collection of BasicCards in a
BasicPile. Pile is very useful for getting us to where we want to be, re a specific
collection of cards, but once there we can rid ourselves of its confinements and focus on
data. Read morefn combos(&self, k: usize) -> Combos ⓘ
fn combos_with_dups(&self, k: usize) -> Combos ⓘ
fn all_of_rank(&self, rank: Pip) -> bool
fn all_of_same_rank(&self) -> bool
fn all_of_same_suit(&self) -> bool
Source§fn is_connector(&self) -> bool
fn is_connector(&self) -> bool
CoPilot can have the earlier version of the function from Pile and
completely ignore it and instead provide stuff with absolutely no rational: Read morefn of_same_or_greater_rank(&self, rank: Pip) -> bool
fn filter_cards<F>(&self, filter: F) -> BasicPile
Source§fn cards_of_rank_pip_type(&self, pip_type: PipType) -> BasicPile
fn cards_of_rank_pip_type(&self, pip_type: PipType) -> BasicPile
Source§fn cards_of_suit_pip_type(&self, pip_type: PipType) -> BasicPile
fn cards_of_suit_pip_type(&self, pip_type: PipType) -> BasicPile
Source§fn cards_with_pip_type(&self, pip_type: PipType) -> BasicPile
fn cards_with_pip_type(&self, pip_type: PipType) -> BasicPile
fn extract_pips<F>(&self, f: F) -> Vec<Pip>
fn map_by_rank(&self) -> BTreeMap<Pip, BasicPile>
fn map_by_suit(&self) -> BTreeMap<Pip, BasicPile>
Source§fn combos_by_rank(&self) -> Combos ⓘ
fn combos_by_rank(&self) -> Combos ⓘ
BasicPiles and sorts them based on their length. Read morefn combos_by_suit(&self) -> Combos ⓘ
fn combos_from_pip_map(&self, mappy: BTreeMap<Pip, BasicPile>) -> Combos ⓘ
fn pip_index<F>(&self, f: F, joiner: &str) -> String
fn ranks(&self) -> Vec<Pip>
fn ranks_index(&self, joiner: &str) -> String
Source§fn ranks_by_suit(&self, suit: Pip) -> Option<Vec<Pip>>
fn ranks_by_suit(&self, suit: Pip) -> Option<Vec<Pip>>
Pile.fn ranks_index_by_suit(&self, suit: Pip, joiner: &str) -> Option<String>
fn suits(&self) -> Vec<Pip>
fn suits_index(&self, joiner: &str) -> String
fn suit_symbol_index(&self, joiner: &str) -> String
impl StructuralPartialEq for BasicPile
Auto Trait Implementations§
impl Freeze for BasicPile
impl RefUnwindSafe for BasicPile
impl Send for BasicPile
impl Sync for BasicPile
impl Unpin for BasicPile
impl UnsafeUnpin for BasicPile
impl UnwindSafe for BasicPile
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more