get_good_move function

This commit is contained in:
2026-05-16 18:12:49 -07:00
parent 8eba64aecf
commit 35931fc0dc
+45 -45
View File
@@ -195,6 +195,50 @@ fn find_valid_instruction(
.then_some(instruction) .then_some(instruction)
} }
fn get_good_move(state: &Klondike) -> Option<KlondikeInstruction> {
fn useless_moves(instruction: &KlondikeInstruction) -> bool {
!matches!(
instruction,
// foundation -> foundation is a useless move
KlondikeInstruction::DstFoundation(DstFoundation {
src: KlondikePile::Foundation(_),
..
})
)
}
fn instruction_priority(state: &Klondike, instruction: &KlondikeInstruction) -> usize {
// 1 Move into foundation
// 2 T->T Move to reveal new card (moving a non-king to reveal empty tableau also counts)
// 3 Move from stock
// 4 Rotate stock
// 5 T->T Move not revealing new card
// 6 Move from foundation
match instruction {
KlondikeInstruction::DstFoundation(_) => 1,
&KlondikeInstruction::DstTableau(dst_tableau) => match dst_tableau.src {
KlondikePileStack::Tableau(TableauStack {
tableau,
skip_cards: SkipCards::Skip0,
}) if !state.state().is_tableau_face_down_empty(tableau)
|| state
.state()
.card(dst_tableau.src)
.is_some_and(|card| card.value() != CardValue::KING) =>
{
2
}
KlondikePileStack::Stock => 3,
_ => 5,
},
KlondikeInstruction::RotateStock => 4,
}
}
state
.possible_instructions()
.filter(useless_moves)
.min_by_key(|ins| instruction_priority(state, ins))
}
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());
let mut input = String::new(); let mut input = String::new();
@@ -221,51 +265,7 @@ fn main() -> Result<(), std::io::Error> {
} }
} }
SessionInstruction::Auto => { SessionInstruction::Auto => {
fn useless_moves(instruction: &KlondikeInstruction) -> bool { if let Some(instruction) = get_good_move(session.state()) {
!matches!(
instruction,
// foundation -> foundation is a useless move
KlondikeInstruction::DstFoundation(DstFoundation {
src: KlondikePile::Foundation(_),
..
})
)
}
fn instruction_priority(
state: &Klondike,
instruction: &KlondikeInstruction,
) -> usize {
// 1 Move into foundation
// 2 T->T Move to reveal new card (moving a non-king to reveal empty tableau also counts)
// 3 Move from stock
// 4 Rotate stock
// 5 T->T Move not revealing new card
// 6 Move from foundation
match instruction {
KlondikeInstruction::DstFoundation(_) => 1,
&KlondikeInstruction::DstTableau(dst_tableau) => match dst_tableau.src {
KlondikePileStack::Tableau(TableauStack {
tableau,
skip_cards: SkipCards::Skip0,
}) if !state.state().is_tableau_face_down_empty(tableau)
|| state
.state()
.card(dst_tableau.src)
.is_some_and(|card| card.value() != CardValue::KING) =>
{
2
}
KlondikePileStack::Stock => 3,
_ => 5,
},
KlondikeInstruction::RotateStock => 4,
}
}
if let Some(instruction) = session
.possible_instructions()
.filter(useless_moves)
.min_by_key(|ins| instruction_priority(session.state(), ins))
{
session.process_instruction(instruction); session.process_instruction(instruction);
} else { } else {
println!("No valid moves!"); println!("No valid moves!");