card game stuff

This commit is contained in:
2026-05-15 07:35:31 -07:00
parent 1f820e4cad
commit 9dd379cb1b
2 changed files with 18 additions and 4 deletions
+13 -3
View File
@@ -3,9 +3,10 @@ use crate::Rng;
// TODO: pub struct ValidInstruction<I>(I); // TODO: pub struct ValidInstruction<I>(I);
pub trait Game { pub trait Game {
type Instruction; type Instruction;
fn enumerate_instructions(&self) -> impl Iterator<Item = Self::Instruction>; fn possible_instructions(&self) -> impl Iterator<Item = Self::Instruction>;
fn validate_instruction(&self, instruction: Self::Instruction) -> bool; fn validate_instruction(&self, instruction: Self::Instruction) -> bool;
fn process_instruction(&mut self, instruction: Self::Instruction); fn process_instruction(&mut self, instruction: Self::Instruction);
fn is_win(&self) -> bool;
} }
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -118,6 +119,9 @@ impl Pile {
pub fn make_face_down(&mut self) { pub fn make_face_down(&mut self) {
self.face_down.extend(self.face_up.drain(..)); self.face_down.extend(self.face_up.drain(..));
} }
pub fn is_empty(&self) -> bool {
self.face_down.is_empty() && self.face_up.is_empty()
}
pub fn pop(&mut self) -> Option<Card> { pub fn pop(&mut self) -> Option<Card> {
let card = self.face_up.pop()?; let card = self.face_up.pop()?;
if self.face_up.is_empty() { if self.face_up.is_empty() {
@@ -148,14 +152,17 @@ impl<G: Game> Session<G> {
pub fn history(&self) -> &[G::Instruction] { pub fn history(&self) -> &[G::Instruction] {
&self.history &self.history
} }
pub fn is_winnable(&self) -> Option<Vec<G::Instruction>> {
None
}
} }
impl<G: Game> Game for Session<G> impl<G: Game> Game for Session<G>
where where
G::Instruction: Clone, G::Instruction: Clone,
{ {
type Instruction = G::Instruction; type Instruction = G::Instruction;
fn enumerate_instructions(&self) -> impl Iterator<Item = Self::Instruction> { fn possible_instructions(&self) -> impl Iterator<Item = Self::Instruction> {
self.state.enumerate_instructions() self.state.possible_instructions()
} }
fn validate_instruction(&self, instruction: Self::Instruction) -> bool { fn validate_instruction(&self, instruction: Self::Instruction) -> bool {
self.state.validate_instruction(instruction) self.state.validate_instruction(instruction)
@@ -164,4 +171,7 @@ where
self.history.push(instruction.clone()); self.history.push(instruction.clone());
self.state.process_instruction(instruction); self.state.process_instruction(instruction);
} }
fn is_win(&self) -> bool {
self.state.is_win()
}
} }
+5 -1
View File
@@ -85,7 +85,7 @@ impl Klondike {
} }
impl Game for Klondike { impl Game for Klondike {
type Instruction = KlondikeInstruction; type Instruction = KlondikeInstruction;
fn enumerate_instructions(&self) -> impl Iterator<Item = Self::Instruction> { fn possible_instructions(&self) -> impl Iterator<Item = Self::Instruction> {
vec![].into_iter() vec![].into_iter()
} }
fn validate_instruction(&self, instruction: Self::Instruction) -> bool { fn validate_instruction(&self, instruction: Self::Instruction) -> bool {
@@ -95,4 +95,8 @@ impl Game for Klondike {
let card = self.state[instruction.src].pop().unwrap(); let card = self.state[instruction.src].pop().unwrap();
self.state[instruction.dst].push(card); self.state[instruction.dst].push(card);
} }
fn is_win(&self) -> bool {
// assuming only valid moves, tableau empty and stock empty means win
self.state.piles[0..9].iter().all(|pile| pile.is_empty())
}
} }