Skip to main content

gin_rummy_engine/
action.rs

1//! The decisions a [`Strategy`](crate::Strategy) can make
2//!
3//! Each phase of a round has its own action type, so an action that is
4//! structurally illegal for its decision point cannot be expressed.
5
6use gin_rummy::{Card, Melds};
7
8/// Response to the initial upcard offer
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum UpcardAction {
11    /// Take the upcard into hand
12    Take,
13    /// Decline the upcard, passing the offer on
14    Pass,
15}
16
17/// Where to draw at the start of a normal turn
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum DrawAction {
20    /// Draw the hidden top of the stock
21    Stock,
22    /// Take the top of the discard pile
23    TakeDiscard,
24}
25
26/// How to end a turn from an 11-card hand
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub enum TurnAction {
29    /// Shed a card and pass the turn
30    Discard(Card),
31    /// Shed a card and knock, spreading the given arrangement
32    ///
33    /// The arrangement decides what the defender may lay off, so it is
34    /// chosen explicitly; `best_melds(hand - discard.into())` recovers the
35    /// deadwood-minimizing choice.
36    Knock {
37        /// The card to shed
38        discard: Card,
39        /// The arrangement of the remaining ten cards to spread
40        melds: Melds,
41    },
42    /// Declare big gin with all 11 cards arranged and no discard
43    BigGin(Melds),
44}
45
46/// One layoff onto the knocker's spread
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48pub struct Layoff {
49    /// The card to lay off
50    pub card: Card,
51    /// The index of the target meld in [`View::spread`](crate::View::spread)
52    /// enumeration order
53    ///
54    /// Indices are stable across layoffs, so chained run extensions address
55    /// the same meld.
56    pub meld: usize,
57}