find valid instruction
This commit is contained in:
+114
-30
@@ -5,7 +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, SkipCards,
|
InstructionSrc, Klondike, KlondikeInstruction, KlondikePileId, KlondikePileStack,
|
||||||
|
KlondikeState, SkipCards,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
@@ -89,32 +90,16 @@ impl Display for Klondike {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Invalid;
|
struct Invalid;
|
||||||
struct Parsed<T>(T);
|
struct Parsed<T>(T);
|
||||||
impl core::str::FromStr for Parsed<KlondikeInstruction> {
|
struct NaiveInstruction {
|
||||||
|
src: KlondikePileId,
|
||||||
|
dst: KlondikePileId,
|
||||||
|
}
|
||||||
|
impl core::str::FromStr for NaiveInstruction {
|
||||||
type Err = Invalid;
|
type Err = Invalid;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let Parsed(src) = s.get(0..2).ok_or(Invalid)?.parse()?;
|
let Parsed(src) = s.get(0..2).ok_or(Invalid)?.parse()?;
|
||||||
let Parsed(dst) = s.get(3..5).ok_or(Invalid)?.parse()?;
|
let Parsed(dst) = s.get(3..5).ok_or(Invalid)?.parse()?;
|
||||||
Ok(Parsed(KlondikeInstruction { src, dst }))
|
Ok(NaiveInstruction { src, dst })
|
||||||
}
|
|
||||||
}
|
|
||||||
impl core::str::FromStr for Parsed<InstructionSrc> {
|
|
||||||
type Err = Invalid;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
Ok(Parsed(match s {
|
|
||||||
"st" => InstructionSrc::new(KlondikePileStack::Stock),
|
|
||||||
"t1" => InstructionSrc::new(KlondikePileStack::Tableau1(SkipCards::Zero)),
|
|
||||||
"t2" => InstructionSrc::new(KlondikePileStack::Tableau2(SkipCards::Zero)),
|
|
||||||
"t3" => InstructionSrc::new(KlondikePileStack::Tableau3(SkipCards::Zero)),
|
|
||||||
"t4" => InstructionSrc::new(KlondikePileStack::Tableau4(SkipCards::Zero)),
|
|
||||||
"t5" => InstructionSrc::new(KlondikePileStack::Tableau5(SkipCards::Zero)),
|
|
||||||
"t6" => InstructionSrc::new(KlondikePileStack::Tableau6(SkipCards::Zero)),
|
|
||||||
"t7" => InstructionSrc::new(KlondikePileStack::Tableau7(SkipCards::Zero)),
|
|
||||||
"f1" => InstructionSrc::new(KlondikePileStack::Foundation1),
|
|
||||||
"f2" => InstructionSrc::new(KlondikePileStack::Foundation2),
|
|
||||||
"f3" => InstructionSrc::new(KlondikePileStack::Foundation3),
|
|
||||||
"f4" => InstructionSrc::new(KlondikePileStack::Foundation4),
|
|
||||||
_ => return Err(Invalid),
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl core::str::FromStr for Parsed<KlondikePileId> {
|
impl core::str::FromStr for Parsed<KlondikePileId> {
|
||||||
@@ -145,7 +130,7 @@ enum SessionInstruction {
|
|||||||
Auto,
|
Auto,
|
||||||
Stock,
|
Stock,
|
||||||
Exit,
|
Exit,
|
||||||
Klondike(KlondikeInstruction),
|
Klondike(NaiveInstruction),
|
||||||
}
|
}
|
||||||
impl core::str::FromStr for SessionInstruction {
|
impl core::str::FromStr for SessionInstruction {
|
||||||
type Err = Invalid;
|
type Err = Invalid;
|
||||||
@@ -157,14 +142,111 @@ impl core::str::FromStr for SessionInstruction {
|
|||||||
"auto" | "a" => Self::Auto,
|
"auto" | "a" => Self::Auto,
|
||||||
"exit" => Self::Exit,
|
"exit" => Self::Exit,
|
||||||
"s" => Self::Stock,
|
"s" => Self::Stock,
|
||||||
other => {
|
other => Self::Klondike(other.parse()?),
|
||||||
let Parsed(ki) = other.parse()?;
|
|
||||||
Self::Klondike(ki)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_valid_instruction(
|
||||||
|
state: &Klondike,
|
||||||
|
naive_instruction: NaiveInstruction,
|
||||||
|
) -> Option<KlondikeInstruction> {
|
||||||
|
const SKIP_LIST: [SkipCards; 13] = [
|
||||||
|
SkipCards::Zero,
|
||||||
|
SkipCards::One,
|
||||||
|
SkipCards::Two,
|
||||||
|
SkipCards::Three,
|
||||||
|
SkipCards::Four,
|
||||||
|
SkipCards::Five,
|
||||||
|
SkipCards::Six,
|
||||||
|
SkipCards::Seven,
|
||||||
|
SkipCards::Eight,
|
||||||
|
SkipCards::Nine,
|
||||||
|
SkipCards::Ten,
|
||||||
|
SkipCards::Eleven,
|
||||||
|
SkipCards::Twelve,
|
||||||
|
];
|
||||||
|
let dst = naive_instruction.dst;
|
||||||
|
let src = match naive_instruction.src {
|
||||||
|
KlondikePileId::Tableau1 => {
|
||||||
|
for skip in SKIP_LIST {
|
||||||
|
let src = InstructionSrc::new(KlondikePileStack::Tableau1(skip));
|
||||||
|
let instruction = KlondikeInstruction { src, dst };
|
||||||
|
if state.is_instruction_valid(instruction) {
|
||||||
|
return Some(instruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
KlondikePileId::Tableau2 => {
|
||||||
|
for skip in SKIP_LIST {
|
||||||
|
let src = InstructionSrc::new(KlondikePileStack::Tableau2(skip));
|
||||||
|
let instruction = KlondikeInstruction { src, dst };
|
||||||
|
if state.is_instruction_valid(instruction) {
|
||||||
|
return Some(instruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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),
|
||||||
|
};
|
||||||
|
return Some(KlondikeInstruction { src, dst });
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn main() -> Result<(), std::io::Error> {
|
||||||
let mut session = Session::new(Klondike::new_random_default());
|
let mut session = Session::new(Klondike::new_random_default());
|
||||||
loop {
|
loop {
|
||||||
@@ -197,8 +279,10 @@ fn main() -> Result<(), std::io::Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SessionInstruction::Stock => session.process_instruction(KlondikeInstruction::stock()),
|
SessionInstruction::Stock => session.process_instruction(KlondikeInstruction::stock()),
|
||||||
SessionInstruction::Klondike(instruction) => {
|
SessionInstruction::Klondike(naive_instruction) => {
|
||||||
if session.is_instruction_valid(instruction) {
|
if let Some(instruction) =
|
||||||
|
find_valid_instruction(session.state(), naive_instruction)
|
||||||
|
{
|
||||||
session.process_instruction(instruction);
|
session.process_instruction(instruction);
|
||||||
} else {
|
} else {
|
||||||
println!("Invalid move!");
|
println!("Invalid move!");
|
||||||
|
|||||||
Reference in New Issue
Block a user