Refactor KlondikeInstruction #4

Merged
Quaternions merged 4 commits from dst-ins-enum into master 2026-05-16 19:09:11 +00:00
Showing only changes of commit dc186483c5 - Show all commits
+41 -90
View File
@@ -5,8 +5,8 @@ pub type Rng = rand::rngs::ThreadRng;
use card_game::{Card, Game, Pile, Session, Suit}; use card_game::{Card, Game, Pile, Session, Suit};
use klondike::{ use klondike::{
InstructionSrc, Klondike, KlondikeInstruction, KlondikePileId, KlondikePileStack, DstFoundation, DstTableau, Foundation, Klondike, KlondikeInstruction, KlondikePile,
KlondikeState, SkipCards, KlondikePileStack, SkipCards, Tableau, TableauStack,
}; };
use std::fmt::Display; use std::fmt::Display;
@@ -91,8 +91,8 @@ impl Display for Klondike {
struct Invalid; struct Invalid;
struct Parsed<T>(T); struct Parsed<T>(T);
struct NaiveInstruction { struct NaiveInstruction {
src: KlondikePileId, src: KlondikePile,
dst: KlondikePileId, dst: KlondikePile,
} }
impl core::str::FromStr for NaiveInstruction { impl core::str::FromStr for NaiveInstruction {
type Err = Invalid; type Err = Invalid;
@@ -102,22 +102,22 @@ impl core::str::FromStr for NaiveInstruction {
Ok(NaiveInstruction { src, dst }) Ok(NaiveInstruction { src, dst })
} }
} }
impl core::str::FromStr for Parsed<KlondikePileId> { impl core::str::FromStr for Parsed<KlondikePile> {
type Err = Invalid; type Err = Invalid;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Parsed(match s { Ok(Parsed(match s {
"st" => KlondikePileId::Stock, "st" => KlondikePile::Stock,
"t1" => KlondikePileId::Tableau1, "t1" => KlondikePile::Tableau(Tableau::Tableau1),
"t2" => KlondikePileId::Tableau2, "t2" => KlondikePile::Tableau(Tableau::Tableau2),
"t3" => KlondikePileId::Tableau3, "t3" => KlondikePile::Tableau(Tableau::Tableau3),
"t4" => KlondikePileId::Tableau4, "t4" => KlondikePile::Tableau(Tableau::Tableau4),
"t5" => KlondikePileId::Tableau5, "t5" => KlondikePile::Tableau(Tableau::Tableau5),
"t6" => KlondikePileId::Tableau6, "t6" => KlondikePile::Tableau(Tableau::Tableau6),
"t7" => KlondikePileId::Tableau7, "t7" => KlondikePile::Tableau(Tableau::Tableau7),
"f1" => KlondikePileId::Foundation1, "f1" => KlondikePile::Foundation(Foundation::Foundation1),
"f2" => KlondikePileId::Foundation2, "f2" => KlondikePile::Foundation(Foundation::Foundation2),
"f3" => KlondikePileId::Foundation3, "f3" => KlondikePile::Foundation(Foundation::Foundation3),
"f4" => KlondikePileId::Foundation4, "f4" => KlondikePile::Foundation(Foundation::Foundation4),
_ => return Err(Invalid), _ => return Err(Invalid),
})) }))
} }
@@ -166,85 +166,34 @@ fn find_valid_instruction(
SkipCards::Skip11, SkipCards::Skip11,
SkipCards::Skip12, SkipCards::Skip12,
]; ];
let dst = naive_instruction.dst; let instruction = match (naive_instruction.dst, naive_instruction.src) {
let src = match naive_instruction.src { (KlondikePile::Tableau(tableau), src) => {
KlondikePileId::Tableau1 => { let src = match src {
for skip in SKIP_LIST { KlondikePile::Tableau(src_tableau) => {
let src = InstructionSrc::new(KlondikePileStack::Tableau1(skip)); for skip_cards in SKIP_LIST {
let instruction = KlondikeInstruction { src, dst }; let src = KlondikePileStack::Tableau(TableauStack {
tableau: src_tableau,
skip_cards,
});
let instruction =
KlondikeInstruction::DstTableau(DstTableau { tableau, src });
if state.is_instruction_valid(instruction) { if state.is_instruction_valid(instruction) {
return Some(instruction); return Some(instruction);
} }
} }
return None; return None;
} }
KlondikePileId::Tableau2 => { KlondikePile::Stock => KlondikePileStack::Stock,
for skip in SKIP_LIST { KlondikePile::Foundation(foundation) => KlondikePileStack::Foundation(foundation),
let src = InstructionSrc::new(KlondikePileStack::Tableau2(skip)); };
let instruction = KlondikeInstruction { src, dst }; KlondikeInstruction::DstTableau(DstTableau { tableau, src })
if state.is_instruction_valid(instruction) { }
return Some(instruction); (KlondikePile::Stock, KlondikePile::Stock) => KlondikeInstruction::RotateStock,
} (KlondikePile::Foundation(foundation), src) => {
} KlondikeInstruction::DstFoundation(DstFoundation { foundation, src })
return None; }
} _ => return None,
KlondikePileId::Tableau3 => {
for skip in SKIP_LIST {
let src = InstructionSrc::new(KlondikePileStack::Tableau3(skip));
let instruction = KlondikeInstruction { src, dst };
if state.is_instruction_valid(instruction) {
return Some(instruction);
}
}
return None;
}
KlondikePileId::Tableau4 => {
for skip in SKIP_LIST {
let src = InstructionSrc::new(KlondikePileStack::Tableau4(skip));
let instruction = KlondikeInstruction { src, dst };
if state.is_instruction_valid(instruction) {
return Some(instruction);
}
}
return None;
}
KlondikePileId::Tableau5 => {
for skip in SKIP_LIST {
let src = InstructionSrc::new(KlondikePileStack::Tableau5(skip));
let instruction = KlondikeInstruction { src, dst };
if state.is_instruction_valid(instruction) {
return Some(instruction);
}
}
return None;
}
KlondikePileId::Tableau6 => {
for skip in SKIP_LIST {
let src = InstructionSrc::new(KlondikePileStack::Tableau6(skip));
let instruction = KlondikeInstruction { src, dst };
if state.is_instruction_valid(instruction) {
return Some(instruction);
}
}
return None;
}
KlondikePileId::Tableau7 => {
for skip in SKIP_LIST {
let src = InstructionSrc::new(KlondikePileStack::Tableau7(skip));
let instruction = KlondikeInstruction { src, dst };
if state.is_instruction_valid(instruction) {
return Some(instruction);
}
}
return None;
}
KlondikePileId::Foundation1 => InstructionSrc::new(KlondikePileStack::Foundation1),
KlondikePileId::Foundation2 => InstructionSrc::new(KlondikePileStack::Foundation2),
KlondikePileId::Foundation3 => InstructionSrc::new(KlondikePileStack::Foundation3),
KlondikePileId::Foundation4 => InstructionSrc::new(KlondikePileStack::Foundation4),
KlondikePileId::Stock => InstructionSrc::new(KlondikePileStack::Stock),
}; };
let instruction = KlondikeInstruction { src, dst };
state state
.is_instruction_valid(instruction) .is_instruction_valid(instruction)
.then_some(instruction) .then_some(instruction)
@@ -281,7 +230,9 @@ fn main() -> Result<(), std::io::Error> {
println!("No valid moves!"); println!("No valid moves!");
} }
} }
SessionInstruction::Stock => session.process_instruction(KlondikeInstruction::stock()), SessionInstruction::Stock => {
session.process_instruction(KlondikeInstruction::RotateStock)
}
SessionInstruction::Klondike(naive_instruction) => { SessionInstruction::Klondike(naive_instruction) => {
if let Some(instruction) = if let Some(instruction) =
find_valid_instruction(session.state(), naive_instruction) find_valid_instruction(session.state(), naive_instruction)