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