Use console for screen clearning and immediate single-char input

This commit is contained in:
Nick Pegg 2025-07-05 19:55:51 -07:00
parent 7229b32f03
commit 821d2114d5
3 changed files with 121 additions and 13 deletions

105
Cargo.lock generated
View file

@ -12,6 +12,7 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
name = "blackjack"
version = "0.1.0"
dependencies = [
"console",
"itertools",
"rand",
]
@ -22,12 +23,31 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "console"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width",
"windows-sys",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "getrandom"
version = "0.3.3"
@ -55,6 +75,12 @@ version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@ -134,6 +160,12 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unicode-width"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
@ -143,6 +175,79 @@ dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.53.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"

View file

@ -4,5 +4,6 @@ version = "0.1.0"
edition = "2024"
[dependencies]
console = "0.16.0"
itertools = "0.14.0"
rand = "0.9.1"

View file

@ -1,6 +1,7 @@
use blackjack::card::Card;
use blackjack::game::{Game, PlayResult, PlayerChoice};
use blackjack::hand::Hand;
use console::Term;
use std::env;
use std::fs;
use std::io;
@ -18,6 +19,7 @@ fn interactive_play() {
// TODO: Persist bank between plays
// TODO: Make a way to reset bank
//
let term = Term::stdout();
let mut bank: u32 = match load_bank() {
Some(b) => b,
None => 1_000,
@ -35,7 +37,7 @@ fn interactive_play() {
if last_bet.is_some() {
print!("Your bet [{}]? ", last_bet.unwrap());
io::stdout().flush().unwrap();
let input = read_input();
let input = term.read_line().unwrap();
if input == "" {
bet = last_bet.unwrap();
} else {
@ -47,7 +49,7 @@ fn interactive_play() {
} else {
print!("Your bet? ");
io::stdout().flush().unwrap();
match read_input().parse() {
match term.read_line().unwrap().parse() {
Ok(b) => bet = b,
Err(_) => continue,
}
@ -65,6 +67,8 @@ fn interactive_play() {
let result = game.play(&mut bank, bet, interactive_decision);
let dealer_hand = Hand::from(result.dealer_cards);
let player_hand = Hand::from(result.player_cards);
term.clear_screen().unwrap();
println!("Dealer's hand: {} = {}", dealer_hand, dealer_hand.value());
println!("Your hand: {} = {}", player_hand, player_hand.value());
@ -90,7 +94,10 @@ fn interactive_play() {
}
fn interactive_decision(hand: &Hand, dealer_showing: &Card) -> PlayerChoice {
println!("\nDealer showing: {dealer_showing}");
let term = Term::stdout();
term.clear_screen().unwrap();
println!("Dealer showing: {dealer_showing}");
println!("Your hand: {hand}\n");
if hand.value() == 21 {
@ -108,12 +115,13 @@ fn interactive_decision(hand: &Hand, dealer_showing: &Card) -> PlayerChoice {
msg += "? ";
io::stdout().write_all(msg.as_bytes()).unwrap();
io::stdout().flush().unwrap();
choice = match read_input().to_lowercase().as_ref() {
"h" => PlayerChoice::Hit,
"s" => PlayerChoice::Stand,
"d" if can_dd => PlayerChoice::DoubleDown,
choice = match term.read_char().unwrap() {
'h' => PlayerChoice::Hit,
's' => PlayerChoice::Stand,
'd' if can_dd => PlayerChoice::DoubleDown,
_ => continue,
};
println!("\n");
break;
}
choice
@ -202,12 +210,6 @@ fn old_man() {
println!("Profit/Loss: ${pl}");
}
fn read_input() -> String {
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
buf.trim().to_owned()
}
fn data_dir() -> PathBuf {
env::home_dir().unwrap().join(".local/share/blackjack")
}