possible_instructions
This commit is contained in:
+2
-2
@@ -86,7 +86,7 @@ impl Card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Clone, Debug, Hash)]
|
||||||
pub struct Stack(Vec<Card>);
|
pub struct Stack(Vec<Card>);
|
||||||
impl Stack {
|
impl Stack {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@@ -120,7 +120,7 @@ impl std::ops::DerefMut for Stack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hash)]
|
#[derive(Clone, Debug, Hash)]
|
||||||
pub struct Pile {
|
pub struct Pile {
|
||||||
face_down: Stack,
|
face_down: Stack,
|
||||||
face_up: Stack,
|
face_up: Stack,
|
||||||
|
|||||||
+126
-55
@@ -7,12 +7,9 @@ impl Default for KlondikeConfig {
|
|||||||
KlondikeConfig {}
|
KlondikeConfig {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Hash)]
|
|
||||||
struct KlondikeState {
|
|
||||||
piles: [Pile; 13],
|
|
||||||
}
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
pub enum KlondikePileId {
|
pub enum KlondikePileId {
|
||||||
|
Stock,
|
||||||
Tableau0,
|
Tableau0,
|
||||||
Tableau1,
|
Tableau1,
|
||||||
Tableau2,
|
Tableau2,
|
||||||
@@ -21,71 +18,64 @@ pub enum KlondikePileId {
|
|||||||
Tableau5,
|
Tableau5,
|
||||||
Tableau6,
|
Tableau6,
|
||||||
Tableau7,
|
Tableau7,
|
||||||
Stock,
|
|
||||||
Foundation0,
|
Foundation0,
|
||||||
Foundation1,
|
Foundation1,
|
||||||
Foundation2,
|
Foundation2,
|
||||||
Foundation3,
|
Foundation3,
|
||||||
}
|
}
|
||||||
|
impl KlondikePileId {
|
||||||
|
fn next(self) -> Option<Self> {
|
||||||
|
use KlondikePileId::*;
|
||||||
|
Some(match self {
|
||||||
|
Stock => Tableau0,
|
||||||
|
Tableau0 => Tableau1,
|
||||||
|
Tableau1 => Tableau2,
|
||||||
|
Tableau2 => Tableau3,
|
||||||
|
Tableau3 => Tableau4,
|
||||||
|
Tableau4 => Tableau5,
|
||||||
|
Tableau5 => Tableau6,
|
||||||
|
Tableau6 => Tableau7,
|
||||||
|
Tableau7 => Foundation0,
|
||||||
|
Foundation0 => Foundation1,
|
||||||
|
Foundation1 => Foundation2,
|
||||||
|
Foundation2 => Foundation3,
|
||||||
|
Foundation3 => return None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
pub struct KlondikeInstruction {
|
pub struct KlondikeInstruction {
|
||||||
pub src: KlondikePileId,
|
pub src: KlondikePileId,
|
||||||
pub dst: KlondikePileId,
|
pub dst: KlondikePileId,
|
||||||
}
|
}
|
||||||
pub struct Klondike {
|
impl KlondikeInstruction {
|
||||||
config: KlondikeConfig,
|
fn next(self) -> Option<Self> {
|
||||||
state: KlondikeState,
|
let KlondikeInstruction { src, dst } = self;
|
||||||
}
|
if let Some(next_dst) = dst.next() {
|
||||||
impl Klondike {
|
return Some(Self { src, dst: next_dst });
|
||||||
pub fn new(mut seed: Rng, config: KlondikeConfig) -> Self {
|
}
|
||||||
// shuffle a new deck
|
if let Some(next_src) = src.next() {
|
||||||
let mut deck = Stack::full_deck(0);
|
return Some(Self {
|
||||||
use rand::seq::SliceRandom;
|
src: next_src,
|
||||||
deck.shuffle(&mut seed);
|
dst: KlondikePileId::Stock,
|
||||||
|
});
|
||||||
// generate tableaus
|
}
|
||||||
let [t0, t1, t2, t3, t4, t5, t6, t7] = core::array::from_fn(|i| {
|
None
|
||||||
let stack = deck.split_off(i).into();
|
|
||||||
let mut pile = Pile::new_face_down(stack);
|
|
||||||
pile.push(deck.pop().unwrap());
|
|
||||||
pile
|
|
||||||
});
|
|
||||||
|
|
||||||
// stock is remaining cards
|
|
||||||
let stock = Pile::new_face_down(deck);
|
|
||||||
|
|
||||||
let state = KlondikeState {
|
|
||||||
piles: [
|
|
||||||
t0,
|
|
||||||
t1,
|
|
||||||
t2,
|
|
||||||
t3,
|
|
||||||
t4,
|
|
||||||
t5,
|
|
||||||
t6,
|
|
||||||
t7,
|
|
||||||
stock,
|
|
||||||
Pile::new(),
|
|
||||||
Pile::new(),
|
|
||||||
Pile::new(),
|
|
||||||
Pile::new(),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
Self { config, state }
|
|
||||||
}
|
}
|
||||||
pub fn pile(&self, index: KlondikePileId) -> &Pile {
|
}
|
||||||
&self.state.piles[index as usize]
|
|
||||||
|
#[derive(Clone, Hash)]
|
||||||
|
struct KlondikeState {
|
||||||
|
piles: [Pile; 13],
|
||||||
|
}
|
||||||
|
impl KlondikeState {
|
||||||
|
fn pile(&self, index: KlondikePileId) -> &Pile {
|
||||||
|
&self.piles[index as usize]
|
||||||
}
|
}
|
||||||
fn pile_mut(&mut self, index: KlondikePileId) -> &mut Pile {
|
fn pile_mut(&mut self, index: KlondikePileId) -> &mut Pile {
|
||||||
&mut self.state.piles[index as usize]
|
&mut self.piles[index as usize]
|
||||||
}
|
}
|
||||||
}
|
fn validate_instruction(&self, instruction: KlondikeInstruction) -> bool {
|
||||||
impl Game for Klondike {
|
|
||||||
type Instruction = KlondikeInstruction;
|
|
||||||
fn possible_instructions(&self) -> impl Iterator<Item = Self::Instruction> + use<> {
|
|
||||||
vec![].into_iter()
|
|
||||||
}
|
|
||||||
fn validate_instruction(&self, instruction: Self::Instruction) -> bool {
|
|
||||||
match instruction {
|
match instruction {
|
||||||
// Stock -> Stock draws a card or resets the stock
|
// Stock -> Stock draws a card or resets the stock
|
||||||
KlondikeInstruction {
|
KlondikeInstruction {
|
||||||
@@ -142,6 +132,87 @@ impl Game for Klondike {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Klondike {
|
||||||
|
config: KlondikeConfig,
|
||||||
|
state: KlondikeState,
|
||||||
|
}
|
||||||
|
impl Klondike {
|
||||||
|
pub fn new(mut seed: Rng, config: KlondikeConfig) -> Self {
|
||||||
|
// shuffle a new deck
|
||||||
|
let mut deck = Stack::full_deck(0);
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
deck.shuffle(&mut seed);
|
||||||
|
|
||||||
|
// generate tableaus
|
||||||
|
let [t0, t1, t2, t3, t4, t5, t6, t7] = core::array::from_fn(|i| {
|
||||||
|
let stack = deck.split_off(i).into();
|
||||||
|
let mut pile = Pile::new_face_down(stack);
|
||||||
|
pile.push(deck.pop().unwrap());
|
||||||
|
pile
|
||||||
|
});
|
||||||
|
|
||||||
|
// stock is remaining cards
|
||||||
|
let stock = Pile::new_face_down(deck);
|
||||||
|
|
||||||
|
let state = KlondikeState {
|
||||||
|
piles: [
|
||||||
|
t0,
|
||||||
|
t1,
|
||||||
|
t2,
|
||||||
|
t3,
|
||||||
|
t4,
|
||||||
|
t5,
|
||||||
|
t6,
|
||||||
|
t7,
|
||||||
|
stock,
|
||||||
|
Pile::new(),
|
||||||
|
Pile::new(),
|
||||||
|
Pile::new(),
|
||||||
|
Pile::new(),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
Self { config, state }
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn pile(&self, index: KlondikePileId) -> &Pile {
|
||||||
|
self.state.pile(index)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn pile_mut(&mut self, index: KlondikePileId) -> &mut Pile {
|
||||||
|
self.state.pile_mut(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct KlondikeIter {
|
||||||
|
instruction: Option<KlondikeInstruction>,
|
||||||
|
}
|
||||||
|
impl KlondikeIter {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
instruction: Some(KlondikeInstruction {
|
||||||
|
src: KlondikePileId::Stock,
|
||||||
|
dst: KlondikePileId::Stock,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Iterator for KlondikeIter {
|
||||||
|
type Item = KlondikeInstruction;
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.instruction = self.instruction?.next();
|
||||||
|
self.instruction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Game for Klondike {
|
||||||
|
type Instruction = KlondikeInstruction;
|
||||||
|
fn possible_instructions(&self) -> impl Iterator<Item = Self::Instruction> + use<> {
|
||||||
|
let state = self.state.clone();
|
||||||
|
KlondikeIter::new().filter(move |&instruction| state.validate_instruction(instruction))
|
||||||
|
}
|
||||||
|
fn validate_instruction(&self, instruction: Self::Instruction) -> bool {
|
||||||
|
self.state.validate_instruction(instruction)
|
||||||
|
}
|
||||||
fn process_instruction(&mut self, instruction: Self::Instruction) {
|
fn process_instruction(&mut self, instruction: Self::Instruction) {
|
||||||
let card = self.pile_mut(instruction.src).pop().unwrap();
|
let card = self.pile_mut(instruction.src).pop().unwrap();
|
||||||
self.pile_mut(instruction.dst).push(card);
|
self.pile_mut(instruction.dst).push(card);
|
||||||
|
|||||||
Reference in New Issue
Block a user