improved game & console
This commit is contained in:
parent
1982d27c4f
commit
782b52ca6c
128
src/blackjack.rs
128
src/blackjack.rs
@ -4,25 +4,33 @@ pub struct BlackjackGame {
|
|||||||
shoe: Hand,
|
shoe: Hand,
|
||||||
player_hand: Hand,
|
player_hand: Hand,
|
||||||
dealer_hand: Hand,
|
dealer_hand: Hand,
|
||||||
|
state: GameState,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum DealResult {
|
pub enum PlayResult {
|
||||||
DealerBlackJack, // Dealer has a blackjack. Player does not.
|
DealerBlackJack, // Dealer has a blackjack. Player does not
|
||||||
|
PlayerBlackJack, // Player has a blackjack. Dealer does not
|
||||||
|
PushBlackjack, // Player and dealer have a blockjack
|
||||||
Push, // Dealer has a Blackjack and so does the Player
|
Push, // Dealer has a Blackjack and so does the Player
|
||||||
PlayerBlackJack, // Player has a blackjack. Dealer does not.
|
Bust, // Player bust
|
||||||
Continue, // Game continues
|
DealerBust, // Dealer bust
|
||||||
}
|
|
||||||
|
|
||||||
pub enum HitResult {
|
|
||||||
Bust,
|
|
||||||
Continue,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum DealerPlayResult {
|
|
||||||
Bust,
|
|
||||||
Push, // Player and dealer have the same value
|
|
||||||
StandPlayerLose, // Dealer stands and wins
|
StandPlayerLose, // Dealer stands and wins
|
||||||
StandPlayerWin, // Dealer stands and loses
|
StandPlayerWin, // Dealer stands and loses
|
||||||
|
Continue, // Game goes on as normal
|
||||||
|
InvalidMove,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy,Debug)]
|
||||||
|
pub enum PlayMoves {
|
||||||
|
Hit,
|
||||||
|
Stand,
|
||||||
|
Bet, // At the Start of the game
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum GameState {
|
||||||
|
Empty, // No cards have been dealt
|
||||||
|
Over, // Game is over
|
||||||
|
PlayerTurn, // Its the turn of the player
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlackjackGame {
|
impl BlackjackGame {
|
||||||
@ -31,6 +39,7 @@ impl BlackjackGame {
|
|||||||
shoe: new_blackjack_shoe(6),
|
shoe: new_blackjack_shoe(6),
|
||||||
player_hand: Hand::new(),
|
player_hand: Hand::new(),
|
||||||
dealer_hand: Hand::new(),
|
dealer_hand: Hand::new(),
|
||||||
|
state: GameState::Empty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,43 +51,66 @@ impl BlackjackGame {
|
|||||||
&self.player_hand
|
&self.player_hand
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deal(&mut self) -> DealResult {
|
pub fn get_state(&self) -> &GameState {
|
||||||
self.player_hand.add_card(self.shoe.pop_card().unwrap());
|
&self.state
|
||||||
self.dealer_hand.add_card(self.shoe.pop_card().unwrap());
|
}
|
||||||
|
|
||||||
self.player_hand.add_card(self.shoe.pop_card().unwrap());
|
pub fn play(&mut self, action: PlayMoves) -> PlayResult {
|
||||||
self.dealer_hand.add_card(self.shoe.pop_card().unwrap());
|
match (&self.state, action) {
|
||||||
|
(GameState::Empty, PlayMoves::Bet) => {
|
||||||
|
self.player_hand.add_card(self.shoe.pop_card().unwrap());
|
||||||
|
self.dealer_hand.add_card(self.shoe.pop_card().unwrap());
|
||||||
|
|
||||||
if self.dealer_hand.is_backjack() {
|
self.player_hand.add_card(self.shoe.pop_card().unwrap());
|
||||||
if self.player_hand.is_backjack() {
|
self.dealer_hand.add_card(self.shoe.pop_card().unwrap());
|
||||||
return DealResult::Push;
|
|
||||||
|
match (self.dealer_hand.is_backjack(),self.player_hand.is_backjack()) {
|
||||||
|
(true,true) => {
|
||||||
|
self.state = GameState::Over;
|
||||||
|
PlayResult::PushBlackjack
|
||||||
|
},
|
||||||
|
(true,false) => {
|
||||||
|
self.state = GameState::Over;
|
||||||
|
PlayResult::DealerBlackJack
|
||||||
|
},
|
||||||
|
(false,true) => {
|
||||||
|
self.state = GameState::Over;
|
||||||
|
PlayResult::PlayerBlackJack
|
||||||
|
},
|
||||||
|
(false,false) => {
|
||||||
|
self.state = GameState::PlayerTurn;
|
||||||
|
PlayResult::Continue
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
(GameState::PlayerTurn, PlayMoves::Hit) => {
|
||||||
|
self.player_hand.add_card(self.shoe.pop_card().unwrap());
|
||||||
|
|
||||||
return DealResult::DealerBlackJack;
|
return match self.player_hand.get_blackjack_value().cmp(&21) {
|
||||||
|
std::cmp::Ordering::Equal => {
|
||||||
|
self.state = GameState::Over;
|
||||||
|
self.dealer_play()
|
||||||
|
}
|
||||||
|
std::cmp::Ordering::Greater => {
|
||||||
|
self.state = GameState::Over;
|
||||||
|
PlayResult::Bust
|
||||||
|
}
|
||||||
|
std::cmp::Ordering::Less => PlayResult::Continue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(GameState::PlayerTurn, PlayMoves::Stand) => {
|
||||||
|
self.state = GameState::Over;
|
||||||
|
return self.dealer_play();
|
||||||
|
}
|
||||||
|
(GameState::Over, _)
|
||||||
|
| (GameState::Empty, _)
|
||||||
|
| (GameState::PlayerTurn, PlayMoves::Bet) => {
|
||||||
|
return PlayResult::InvalidMove;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.player_hand.is_backjack() {
|
|
||||||
return DealResult::PlayerBlackJack;
|
|
||||||
}
|
|
||||||
|
|
||||||
DealResult::Continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hit(&mut self) -> HitResult {
|
fn dealer_play(&mut self) -> PlayResult {
|
||||||
self.player_hand.add_card(self.shoe.pop_card().unwrap());
|
|
||||||
|
|
||||||
if self.player_hand.get_blackjack_value() > 21 {
|
|
||||||
return HitResult::Bust;
|
|
||||||
}
|
|
||||||
|
|
||||||
HitResult::Continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stand(&mut self) {
|
|
||||||
// ???
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dealer_play(&mut self) -> DealerPlayResult {
|
|
||||||
// Stand on 17 or above
|
// Stand on 17 or above
|
||||||
// Hit on 16 and below
|
// Hit on 16 and below
|
||||||
|
|
||||||
@ -88,16 +120,16 @@ impl BlackjackGame {
|
|||||||
let player_value = self.player_hand.get_blackjack_value();
|
let player_value = self.player_hand.get_blackjack_value();
|
||||||
|
|
||||||
return match dealer_value.cmp(&player_value) {
|
return match dealer_value.cmp(&player_value) {
|
||||||
std::cmp::Ordering::Equal => DealerPlayResult::Push,
|
std::cmp::Ordering::Equal => PlayResult::Push,
|
||||||
std::cmp::Ordering::Greater => DealerPlayResult::StandPlayerLose,
|
std::cmp::Ordering::Greater => PlayResult::StandPlayerLose,
|
||||||
std::cmp::Ordering::Less => DealerPlayResult::StandPlayerWin,
|
std::cmp::Ordering::Less => PlayResult::StandPlayerWin,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
self.dealer_hand.add_card(self.shoe.pop_card().unwrap());
|
self.dealer_hand.add_card(self.shoe.pop_card().unwrap());
|
||||||
|
|
||||||
if self.dealer_hand.get_blackjack_value() > 21 {
|
if self.dealer_hand.get_blackjack_value() > 21 {
|
||||||
return DealerPlayResult::Bust;
|
return PlayResult::DealerBust;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,100 +1,93 @@
|
|||||||
use std::io::stdin;
|
use std::io::{self, stdin};
|
||||||
|
|
||||||
use crate::blackjack::BlackjackGame;
|
use crate::blackjack::{BlackjackGame, GameState, PlayMoves};
|
||||||
|
|
||||||
pub fn play() -> Result<(), Box<dyn std::error::Error>> {
|
pub fn play() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut game = BlackjackGame::new();
|
let mut game = BlackjackGame::new();
|
||||||
|
let mut play_move = PlayMoves::Bet;
|
||||||
|
|
||||||
let deal = game.deal();
|
while !matches!(game.get_state(), GameState::Over) {
|
||||||
|
match game.play(play_move) {
|
||||||
println!(
|
crate::blackjack::PlayResult::DealerBlackJack => {
|
||||||
"Dealer hand: {} ?",
|
print_full_state(&game);
|
||||||
game.get_dealer_hand().get_card(0).unwrap()
|
println!("Dealer wins with blackjack!");
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"Player hand: {} ({})",
|
|
||||||
game.get_player_hand(),
|
|
||||||
game.get_player_hand().get_blackjack_value()
|
|
||||||
);
|
|
||||||
|
|
||||||
match deal {
|
|
||||||
crate::blackjack::DealResult::DealerBlackJack => {
|
|
||||||
println!("Dealer has a blackjack!");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
crate::blackjack::DealResult::PlayerBlackJack => {
|
|
||||||
println!("Player has a blackjack!");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
crate::blackjack::DealResult::Push => {
|
|
||||||
println!("Both Player and dealer have a blackjack!");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
crate::blackjack::DealResult::Continue => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {
|
|
||||||
println!("(H)it (S)tand");
|
|
||||||
|
|
||||||
let mut buffer = String::new();
|
|
||||||
stdin().read_line(&mut buffer)?;
|
|
||||||
|
|
||||||
let hit = buffer.trim() == "h";
|
|
||||||
|
|
||||||
if hit {
|
|
||||||
let hit_result = game.hit();
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"Dealer hand: {} ?",
|
|
||||||
game.get_dealer_hand().get_card(0).unwrap()
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"Player hand: {} ({})",
|
|
||||||
game.get_player_hand(),
|
|
||||||
game.get_player_hand().get_blackjack_value()
|
|
||||||
);
|
|
||||||
|
|
||||||
match hit_result {
|
|
||||||
crate::blackjack::HitResult::Bust => {
|
|
||||||
println!("Player busts");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
crate::blackjack::HitResult::Continue => {}
|
|
||||||
}
|
}
|
||||||
} else {
|
crate::blackjack::PlayResult::PlayerBlackJack => println!("Player has a blackjack!"),
|
||||||
game.stand();
|
crate::blackjack::PlayResult::PushBlackjack => {
|
||||||
|
print_full_state(&game);
|
||||||
let dealer_play = game.dealer_play();
|
println!("Player and Dealer have a blackjack!");
|
||||||
|
}
|
||||||
println!(
|
crate::blackjack::PlayResult::DealerBust => {
|
||||||
"Dealer hand: {} ({})",
|
println!("Dealer busts. Player wins!");
|
||||||
game.get_dealer_hand(),
|
}
|
||||||
game.get_dealer_hand().get_blackjack_value()
|
crate::blackjack::PlayResult::StandPlayerLose => {
|
||||||
);
|
print_full_state(&game);
|
||||||
println!(
|
println!(
|
||||||
"Player hand: {} ({})",
|
"Dealer wins with {}",
|
||||||
game.get_player_hand(),
|
game.get_dealer_hand().get_blackjack_value()
|
||||||
game.get_player_hand().get_blackjack_value()
|
);
|
||||||
);
|
}
|
||||||
|
crate::blackjack::PlayResult::StandPlayerWin => {
|
||||||
match dealer_play {
|
print_full_state(&game);
|
||||||
crate::blackjack::DealerPlayResult::Bust => {
|
println!(
|
||||||
println!("Dealer bust. Player wins.");
|
"Player wins with {}",
|
||||||
}
|
game.get_player_hand().get_blackjack_value()
|
||||||
crate::blackjack::DealerPlayResult::Push => {
|
);
|
||||||
println!("Player and dealer have same value. Push.");
|
}
|
||||||
}
|
crate::blackjack::PlayResult::Push => {
|
||||||
crate::blackjack::DealerPlayResult::StandPlayerLose => {
|
print_full_state(&game);
|
||||||
println!("Dealer wins");
|
println!("Player and dealer have the same value");
|
||||||
}
|
}
|
||||||
crate::blackjack::DealerPlayResult::StandPlayerWin => {
|
crate::blackjack::PlayResult::Bust => {
|
||||||
println!("Player wins");
|
print_full_state(&game);
|
||||||
}
|
println!(
|
||||||
|
"Player busts with {}",
|
||||||
|
game.get_player_hand().get_blackjack_value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
crate::blackjack::PlayResult::InvalidMove => {
|
||||||
|
println!("You cannot do that!");
|
||||||
|
play_move = get_move()?;
|
||||||
|
}
|
||||||
|
crate::blackjack::PlayResult::Continue => {
|
||||||
|
println!("Dealer: {} ?", game.get_dealer_hand().get_card(0).unwrap());
|
||||||
|
println!(
|
||||||
|
"Player: {} ({})",
|
||||||
|
game.get_player_hand(),
|
||||||
|
game.get_player_hand().get_blackjack_value()
|
||||||
|
);
|
||||||
|
play_move = get_move()?
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_move() -> Result<PlayMoves, io::Error> {
|
||||||
|
loop {
|
||||||
|
println!("(H)it (S)tand");
|
||||||
|
let mut buffer = String::new();
|
||||||
|
|
||||||
|
stdin().read_line(&mut buffer)?;
|
||||||
|
|
||||||
|
match buffer.trim() {
|
||||||
|
"h" | "H" => return Ok(PlayMoves::Hit),
|
||||||
|
"s" | "S" => return Ok(PlayMoves::Stand),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_full_state(game: &BlackjackGame) {
|
||||||
|
println!(
|
||||||
|
"Dealer: {} ({})",
|
||||||
|
game.get_dealer_hand(),
|
||||||
|
game.get_dealer_hand().get_blackjack_value()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"Player: {} ({})",
|
||||||
|
game.get_player_hand(),
|
||||||
|
game.get_player_hand().get_blackjack_value()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user