diff --git a/src/klondike.rs b/src/klondike.rs index 351054c..4c4e807 100644 --- a/src/klondike.rs +++ b/src/klondike.rs @@ -77,6 +77,16 @@ impl KlondikePile { }) } } +impl From for KlondikePile { + fn from(value: Tableau) -> Self { + KlondikePile::Tableau(value) + } +} +impl From for KlondikePile { + fn from(value: Foundation) -> Self { + KlondikePile::Foundation(value) + } +} #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] @@ -119,8 +129,8 @@ impl SkipCards { #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct TableauStack { - tableau: Tableau, - skip_cards: SkipCards, + pub tableau: Tableau, + pub skip_cards: SkipCards, } impl TableauStack { @@ -175,8 +185,8 @@ impl KlondikePileStack { #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct DstFoundation { - src: KlondikePile, - foundation: Foundation, + pub src: KlondikePile, + pub foundation: Foundation, } impl DstFoundation { const ITER_BEGIN: Self = Self { @@ -198,8 +208,8 @@ impl DstFoundation { #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct DstTableau { - src: KlondikePileStack, - tableau: Tableau, + pub src: KlondikePileStack, + pub tableau: Tableau, } impl DstTableau { const ITER_BEGIN: Self = Self { @@ -297,96 +307,91 @@ impl KlondikeState { pub const fn tableau7(&self) -> &Pile<6, 13> { &self.tableau7 } - fn src_card(&self, src: InstructionSrc) -> Option<&Card> { - match src.into_spec() { - KlondikePileStack::Tableau1(skip_cards) => { - self.tableau1.face_up().get(skip_cards as usize) + fn card(&self, src: KlondikePileStack) -> Option<&Card> { + match src { + KlondikePileStack::Tableau(TableauStack { + tableau, + skip_cards, + }) => match tableau { + Tableau::Tableau1 => self.tableau1.face_up().get(skip_cards as usize), + Tableau::Tableau2 => self.tableau2.face_up().get(skip_cards as usize), + Tableau::Tableau3 => self.tableau3.face_up().get(skip_cards as usize), + Tableau::Tableau4 => self.tableau4.face_up().get(skip_cards as usize), + Tableau::Tableau5 => self.tableau5.face_up().get(skip_cards as usize), + Tableau::Tableau6 => self.tableau6.face_up().get(skip_cards as usize), + Tableau::Tableau7 => self.tableau7.face_up().get(skip_cards as usize), + }, + KlondikePileStack::Foundation(foundation) => { + self.foundations[foundation as usize].last() } - KlondikePileStack::Tableau2(skip_cards) => { - self.tableau2.face_up().get(skip_cards as usize) - } - KlondikePileStack::Tableau3(skip_cards) => { - self.tableau3.face_up().get(skip_cards as usize) - } - KlondikePileStack::Tableau4(skip_cards) => { - self.tableau4.face_up().get(skip_cards as usize) - } - KlondikePileStack::Tableau5(skip_cards) => { - self.tableau5.face_up().get(skip_cards as usize) - } - KlondikePileStack::Tableau6(skip_cards) => { - self.tableau6.face_up().get(skip_cards as usize) - } - KlondikePileStack::Tableau7(skip_cards) => { - self.tableau7.face_up().get(skip_cards as usize) - } - KlondikePileStack::Foundation1 => self.foundations[1 - 1].last(), - KlondikePileStack::Foundation2 => self.foundations[2 - 1].last(), - KlondikePileStack::Foundation3 => self.foundations[3 - 1].last(), - KlondikePileStack::Foundation4 => self.foundations[4 - 1].last(), KlondikePileStack::Stock => self.stock.face_up().last(), } } - fn take_src_cards(&mut self, src: InstructionSrc) -> Stack<13> { - match src.into_spec() { - KlondikePileStack::Tableau1(skip_cards) => { - self.tableau1.take_range_flip_up(skip_cards as usize..) + fn top_card(&self, src: KlondikePile) -> Option<&Card> { + match src { + KlondikePile::Tableau(tableau) => match tableau { + Tableau::Tableau1 => self.tableau1.face_up().last(), + Tableau::Tableau2 => self.tableau2.face_up().last(), + Tableau::Tableau3 => self.tableau3.face_up().last(), + Tableau::Tableau4 => self.tableau4.face_up().last(), + Tableau::Tableau5 => self.tableau5.face_up().last(), + Tableau::Tableau6 => self.tableau6.face_up().last(), + Tableau::Tableau7 => self.tableau7.face_up().last(), + }, + KlondikePile::Foundation(foundation) => self.foundations[foundation as usize].last(), + KlondikePile::Stock => self.stock.face_up().last(), + } + } + fn take_cards(&mut self, src: KlondikePileStack) -> Stack<13> { + match src { + KlondikePileStack::Tableau(TableauStack { + tableau, + skip_cards, + }) => match tableau { + Tableau::Tableau1 => self.tableau1.take_range_flip_up(skip_cards as usize..), + Tableau::Tableau2 => self.tableau2.take_range_flip_up(skip_cards as usize..), + Tableau::Tableau3 => self.tableau3.take_range_flip_up(skip_cards as usize..), + Tableau::Tableau4 => self.tableau4.take_range_flip_up(skip_cards as usize..), + Tableau::Tableau5 => self.tableau5.take_range_flip_up(skip_cards as usize..), + Tableau::Tableau6 => self.tableau6.take_range_flip_up(skip_cards as usize..), + Tableau::Tableau7 => self.tableau7.take_range_flip_up(skip_cards as usize..), + }, + KlondikePileStack::Foundation(foundation) => { + Stack::from_iter(self.foundations[foundation as usize].pop()) } - KlondikePileStack::Tableau2(skip_cards) => { - self.tableau2.take_range_flip_up(skip_cards as usize..) - } - KlondikePileStack::Tableau3(skip_cards) => { - self.tableau3.take_range_flip_up(skip_cards as usize..) - } - KlondikePileStack::Tableau4(skip_cards) => { - self.tableau4.take_range_flip_up(skip_cards as usize..) - } - KlondikePileStack::Tableau5(skip_cards) => { - self.tableau5.take_range_flip_up(skip_cards as usize..) - } - KlondikePileStack::Tableau6(skip_cards) => { - self.tableau6.take_range_flip_up(skip_cards as usize..) - } - KlondikePileStack::Tableau7(skip_cards) => { - self.tableau7.take_range_flip_up(skip_cards as usize..) - } - KlondikePileStack::Foundation1 => Stack::from_iter(self.foundations[1 - 1].pop()), - KlondikePileStack::Foundation2 => Stack::from_iter(self.foundations[2 - 1].pop()), - KlondikePileStack::Foundation3 => Stack::from_iter(self.foundations[3 - 1].pop()), - KlondikePileStack::Foundation4 => Stack::from_iter(self.foundations[4 - 1].pop()), KlondikePileStack::Stock => Stack::from_iter(self.stock.pop()), } } - fn dst_card(&self, dst: KlondikePileId) -> Option<&Card> { - match dst { - KlondikePileId::Tableau1 => self.tableau1.face_up().last(), - KlondikePileId::Tableau2 => self.tableau2.face_up().last(), - KlondikePileId::Tableau3 => self.tableau3.face_up().last(), - KlondikePileId::Tableau4 => self.tableau4.face_up().last(), - KlondikePileId::Tableau5 => self.tableau5.face_up().last(), - KlondikePileId::Tableau6 => self.tableau6.face_up().last(), - KlondikePileId::Tableau7 => self.tableau7.face_up().last(), - KlondikePileId::Foundation1 => self.foundations[1 - 1].last(), - KlondikePileId::Foundation2 => self.foundations[2 - 1].last(), - KlondikePileId::Foundation3 => self.foundations[3 - 1].last(), - KlondikePileId::Foundation4 => self.foundations[4 - 1].last(), - KlondikePileId::Stock => None, + fn take_top_card(&mut self, src: KlondikePile) -> Option { + match src { + KlondikePile::Tableau(tableau) => match tableau { + Tableau::Tableau1 => self.tableau1.pop(), + Tableau::Tableau2 => self.tableau2.pop(), + Tableau::Tableau3 => self.tableau3.pop(), + Tableau::Tableau4 => self.tableau4.pop(), + Tableau::Tableau5 => self.tableau5.pop(), + Tableau::Tableau6 => self.tableau6.pop(), + Tableau::Tableau7 => self.tableau7.pop(), + }, + KlondikePile::Foundation(foundation) => self.foundations[foundation as usize].pop(), + KlondikePile::Stock => self.stock.pop(), } } - fn extend_dst_pile(&mut self, dst: KlondikePileId, cards: Stack<13>) { + fn extend>(&mut self, dst: KlondikePile, cards: I) { match dst { - KlondikePileId::Tableau1 => self.tableau1.extend(cards), - KlondikePileId::Tableau2 => self.tableau2.extend(cards), - KlondikePileId::Tableau3 => self.tableau3.extend(cards), - KlondikePileId::Tableau4 => self.tableau4.extend(cards), - KlondikePileId::Tableau5 => self.tableau5.extend(cards), - KlondikePileId::Tableau6 => self.tableau6.extend(cards), - KlondikePileId::Tableau7 => self.tableau7.extend(cards), - KlondikePileId::Foundation1 => self.foundations[1 - 1].extend(cards), - KlondikePileId::Foundation2 => self.foundations[2 - 1].extend(cards), - KlondikePileId::Foundation3 => self.foundations[3 - 1].extend(cards), - KlondikePileId::Foundation4 => self.foundations[4 - 1].extend(cards), - KlondikePileId::Stock => (), + KlondikePile::Tableau(tableau) => match tableau { + Tableau::Tableau1 => self.tableau1.extend(cards), + Tableau::Tableau2 => self.tableau2.extend(cards), + Tableau::Tableau3 => self.tableau3.extend(cards), + Tableau::Tableau4 => self.tableau4.extend(cards), + Tableau::Tableau5 => self.tableau5.extend(cards), + Tableau::Tableau6 => self.tableau6.extend(cards), + Tableau::Tableau7 => self.tableau7.extend(cards), + }, + KlondikePile::Foundation(foundation) => { + self.foundations[foundation as usize].extend(cards) + } + KlondikePile::Stock => self.stock.extend(cards), } } fn is_instruction_valid(&self, instruction: KlondikeInstruction) -> bool { @@ -400,8 +405,8 @@ impl KlondikeState { // moving to foundation has special rules KlondikeInstruction::DstFoundation(dst_foundation) => { // get the top cards - if let Some(src_card) = self.src_card(dst_foundation.src) { - match self.dst_card(dst_foundation.foundation) { + if let Some(src_card) = self.top_card(dst_foundation.src) { + match self.top_card(dst_foundation.foundation.into()) { // destination card exists Some(dst_card) => { // suit matches? @@ -418,9 +423,9 @@ impl KlondikeState { } // other = move to tableau KlondikeInstruction::DstTableau(dst_tableau) => { - // get the top cards - if let Some(src_card) = self.src_card(dst_tableau.src) { - match self.dst_card(dst_tableau.tableau) { + // get the cards + if let Some(src_card) = self.card(dst_tableau.src) { + match self.top_card(dst_tableau.tableau.into()) { // destination card exists Some(dst_card) => { // red-ness is opposite? @@ -522,19 +527,20 @@ impl Game for Klondike { fn process_instruction(&mut self, instruction: Self::Instruction) { match instruction { // Reset the stock if it's empty - KlondikeInstruction { - src: InstructionSrc::STOCK, - dst: KlondikePileId::Stock, - } => { + KlondikeInstruction::RotateStock => { if self.state.stock.face_down().is_empty() { self.state.stock.flip_it_and_reverse_it(); } else { self.state.stock.flip_up(); } } - KlondikeInstruction { src, dst } => { - let cards = self.state.take_src_cards(src); - self.state.extend_dst_pile(dst, cards); + KlondikeInstruction::DstFoundation(DstFoundation { src, foundation }) => { + let cards = self.state.take_top_card(src); + self.state.extend(foundation.into(), cards); + } + KlondikeInstruction::DstTableau(DstTableau { src, tableau }) => { + let cards = self.state.take_cards(src); + self.state.extend(tableau.into(), cards); } } }