3 Commits

Author SHA1 Message Date
Quaternions d1df1c2eb3 separate klondike 2026-05-16 16:56:55 -07:00
Quaternions fe2530bfc8 separate klondike-cli 2026-05-16 16:56:43 -07:00
Quaternions bfb3d28e1b move into folder 2026-05-16 16:39:59 -07:00
13 changed files with 86 additions and 52 deletions
Generated
+16
View File
@@ -125,6 +125,22 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "klondike"
version = "0.1.0"
dependencies = [
"card_game",
"rand",
]
[[package]]
name = "klondike-cli"
version = "0.1.0"
dependencies = [
"card_game",
"klondike",
]
[[package]] [[package]]
name = "leb128fmt" name = "leb128fmt"
version = "0.1.0" version = "0.1.0"
+7 -13
View File
@@ -1,13 +1,7 @@
[package] [workspace]
name = "card_game" members = [
version = "0.1.0" "card_game",
edition = "2024" "klondike",
repository = "https://git.aleshym.co/Quaternions/card_game" "klondike-cli",
license = "MIT OR Apache-2.0" ]
description = "Card game library." resolver = "3"
authors = ["Rhys Lloyd <krakow20@gmail.com>"]
keywords = ["card", "cards", "solitaire", "klondike"]
[dependencies]
arrayvec = "0.7.6"
rand = { version = "0.10.1", default-features = false, features = ["thread_rng"] }
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "card_game"
version = "0.1.0"
edition = "2024"
repository = "https://git.aleshym.co/Quaternions/card_game"
license = "MIT OR Apache-2.0"
description = "Card game library."
authors = ["Rhys Lloyd <krakow20@gmail.com>"]
keywords = ["card", "cards", "solitaire", "klondike"]
[dependencies]
arrayvec = "0.7.6"
rand = { version = "0.10.1", default-features = false, features = ["thread_rng"] }
View File
+2 -7
View File
@@ -1,10 +1,5 @@
pub mod card_game; mod card_game;
pub mod klondike; pub use card_game::*;
#[cfg(test)]
mod test;
pub type Rng = rand::rngs::ThreadRng;
// // test readme // // test readme
// #[doc = include_str!("../README.md")] // #[doc = include_str!("../README.md")]
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "klondike-cli"
version = "0.1.0"
edition = "2024"
[dependencies]
card_game = { version = "0.1.0", path = "../card_game" }
klondike = { version = "0.1.0", path = "../klondike" }
+21 -25
View File
@@ -1,8 +1,3 @@
mod card_game;
mod klondike;
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::{
DstFoundation, DstTableau, Foundation, Klondike, KlondikeInstruction, KlondikePile, DstFoundation, DstTableau, Foundation, Klondike, KlondikeInstruction, KlondikePile,
@@ -10,17 +5,18 @@ use klondike::{
}; };
use std::fmt::Display; use std::fmt::Display;
struct Displayed<T>(T);
impl Display for Card { impl Display for Displayed<&Card> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.value().get() { match self.0.value().get() {
1 => write!(f, "A"), 1 => write!(f, "A"),
11 => write!(f, "J"), 11 => write!(f, "J"),
12 => write!(f, "Q"), 12 => write!(f, "Q"),
13 => write!(f, "K"), 13 => write!(f, "K"),
other => write!(f, "{other}"), other => write!(f, "{other}"),
}?; }?;
match self.suit() { match self.0.suit() {
Suit::Spades => write!(f, ""), Suit::Spades => write!(f, ""),
Suit::Hearts => write!(f, ""), Suit::Hearts => write!(f, ""),
Suit::Clubs => write!(f, ""), Suit::Clubs => write!(f, ""),
@@ -33,30 +29,30 @@ struct OptionalCard<'a>(Option<&'a Card>);
impl Display for OptionalCard<'_> { impl Display for OptionalCard<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
OptionalCard(Some(card)) => write!(f, "{card}"), &OptionalCard(Some(card)) => write!(f, "{}", Displayed(card)),
OptionalCard(None) => write!(f, "None"), OptionalCard(None) => write!(f, "None"),
} }
} }
} }
impl Display for Klondike { impl Display for Displayed<&Klondike> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Stock // Stock
let stock_count = self.state().stock().face_down().len(); let stock_count = self.0.state().stock().face_down().len();
writeln!(f, "Stock: {stock_count}")?; writeln!(f, "Stock: {stock_count}")?;
// Hand // Hand
let hand = self.state().stock().face_up().last(); let hand = self.0.state().stock().face_up().last();
writeln!(f, "Hand: {}", OptionalCard(hand))?; writeln!(f, "Hand: {}", OptionalCard(hand))?;
// Foundations // Foundations
write!( write!(
f, f,
"Foundations: {} {} {} {}", "Foundations: {} {} {} {}",
OptionalCard(self.state().foundation1().last()), OptionalCard(self.0.state().foundation1().last()),
OptionalCard(self.state().foundation2().last()), OptionalCard(self.0.state().foundation2().last()),
OptionalCard(self.state().foundation3().last()), OptionalCard(self.0.state().foundation3().last()),
OptionalCard(self.state().foundation4().last()), OptionalCard(self.0.state().foundation4().last()),
)?; )?;
writeln!(f)?; writeln!(f)?;
@@ -70,18 +66,18 @@ impl Display for Klondike {
write!(f, "]")?; write!(f, "]")?;
} }
for card in pile.face_up() { for card in pile.face_up() {
write!(f, "{card}")?; write!(f, "{}", Displayed(card))?;
} }
writeln!(f)?; writeln!(f)?;
Ok(()) Ok(())
} }
write_pile(f, self.state().tableau1(), 1)?; write_pile(f, self.0.state().tableau1(), 1)?;
write_pile(f, self.state().tableau2(), 2)?; write_pile(f, self.0.state().tableau2(), 2)?;
write_pile(f, self.state().tableau3(), 3)?; write_pile(f, self.0.state().tableau3(), 3)?;
write_pile(f, self.state().tableau4(), 4)?; write_pile(f, self.0.state().tableau4(), 4)?;
write_pile(f, self.state().tableau5(), 5)?; write_pile(f, self.0.state().tableau5(), 5)?;
write_pile(f, self.state().tableau6(), 6)?; write_pile(f, self.0.state().tableau6(), 6)?;
write_pile(f, self.state().tableau7(), 7)?; write_pile(f, self.0.state().tableau7(), 7)?;
Ok(()) Ok(())
} }
@@ -203,7 +199,7 @@ 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 {
// display game // display game
println!("{}", session.state()); println!("{}", Displayed(session.state()));
// parse input // parse input
let mut input = String::new(); let mut input = String::new();
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "klondike"
version = "0.1.0"
edition = "2024"
[dependencies]
card_game = { version = "0.1.0", path = "../card_game" }
rand = { version = "0.10.1", default-features = false, features = ["thread_rng"] }
+9 -5
View File
@@ -1,5 +1,9 @@
use crate::Rng; pub type Rng = rand::rngs::ThreadRng;
use crate::card_game::{Card, CardValue, Game, Pile, Stack};
use card_game::{Card, CardValue, Game, Pile, Stack};
#[cfg(test)]
mod test;
#[derive(Clone, Debug, Eq, Hash, PartialEq)] #[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct KlondikeConfig {} pub struct KlondikeConfig {}
@@ -480,8 +484,8 @@ impl Klondike {
let mut deck = deck.into_iter(); let mut deck = deck.into_iter();
// generate tableaus // generate tableaus
fn pile<const DN: usize>(deck: &mut arrayvec::IntoIter<Card, 52>) -> Pile<DN, 13> { fn pile<const DN: usize>(deck: &mut <Stack<52> as IntoIterator>::IntoIter) -> Pile<DN, 13> {
let stack = arrayvec::ArrayVec::from_iter(deck.take(DN)).into(); let stack = Stack::from_iter(deck.take(DN));
let mut pile = Pile::new_face_down(stack); let mut pile = Pile::new_face_down(stack);
pile.push(deck.next().unwrap()); pile.push(deck.next().unwrap());
pile pile
@@ -495,7 +499,7 @@ impl Klondike {
let tableau7 = pile(&mut deck); let tableau7 = pile(&mut deck);
// stock is remaining cards // stock is remaining cards
let stock = Pile::new_face_down(arrayvec::ArrayVec::from_iter(deck).into()); let stock = Pile::new_face_down(Stack::from_iter(deck));
let state = KlondikeState { let state = KlondikeState {
stock, stock,
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::card_game::{Game, Session}; use crate::Klondike;
use crate::klondike::Klondike; use card_game::{Game, Session};
#[test] #[test]
fn test_is_winnable() { fn test_is_winnable() {
// is winnable // is winnable