mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-12 15:50:20 -08:00
rust port of craps
This commit is contained in:
9
29_Craps/rust/Cargo.toml
Normal file
9
29_Craps/rust/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "rust"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
||||
141
29_Craps/rust/src/craps_game.rs
Normal file
141
29_Craps/rust/src/craps_game.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
use crate::util;
|
||||
|
||||
enum GameState {
|
||||
ComeOut,
|
||||
PointRolls,
|
||||
GameOver,
|
||||
}
|
||||
|
||||
pub struct CrapsGame {
|
||||
wallet: usize,
|
||||
bet: usize,
|
||||
point: u8,
|
||||
state: GameState,
|
||||
}
|
||||
|
||||
impl CrapsGame {
|
||||
pub fn new() -> Self {
|
||||
let wallet = util::read_numeric("\nHow much money do you want to start with?");
|
||||
|
||||
CrapsGame {
|
||||
wallet,
|
||||
bet: 0,
|
||||
point: 0,
|
||||
state: GameState::ComeOut,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) -> bool {
|
||||
use GameState::*;
|
||||
|
||||
match self.state {
|
||||
ComeOut => self.new_round(),
|
||||
PointRolls => self.point_roll(),
|
||||
GameOver => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn point_roll(&mut self) -> bool {
|
||||
let point = self.point;
|
||||
|
||||
println!("Rolling {point} wins. 7 loses.");
|
||||
|
||||
self.prompt_roll();
|
||||
let roll = CrapsGame::roll();
|
||||
|
||||
if roll == point {
|
||||
self.player_win();
|
||||
} else if roll == 7 {
|
||||
self.player_lose();
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn new_round(&mut self) -> bool {
|
||||
println!("\nCome out roll.");
|
||||
println!("7 and 11 win. 2, 3 and 12 lose.\n");
|
||||
|
||||
loop {
|
||||
self.bet = util::read_numeric("Enter your bet:");
|
||||
|
||||
if self.bet <= self.wallet {
|
||||
break;
|
||||
} else {
|
||||
println!("You don't have that much money!");
|
||||
}
|
||||
}
|
||||
|
||||
self.prompt_roll();
|
||||
let point = CrapsGame::roll();
|
||||
|
||||
match point {
|
||||
11 | 7 => {
|
||||
self.player_win();
|
||||
}
|
||||
2 | 3 | 12 => {
|
||||
self.player_lose();
|
||||
}
|
||||
_ => {
|
||||
self.point = point;
|
||||
self.state = GameState::PointRolls
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn player_win(&mut self) {
|
||||
let bet = self.bet;
|
||||
|
||||
println!("You won ${bet}!");
|
||||
|
||||
self.wallet += bet;
|
||||
self.print_wallet();
|
||||
|
||||
self.state = GameState::ComeOut;
|
||||
}
|
||||
|
||||
fn player_lose(&mut self) {
|
||||
let bet = self.bet;
|
||||
|
||||
println!("You lost ${bet}!");
|
||||
|
||||
self.wallet -= bet;
|
||||
self.print_wallet();
|
||||
|
||||
if self.wallet == 0 {
|
||||
self.game_over();
|
||||
} else {
|
||||
self.state = GameState::ComeOut;
|
||||
}
|
||||
}
|
||||
|
||||
fn print_wallet(&self) {
|
||||
println!("\nYou have ${} in your wallet.", self.wallet);
|
||||
}
|
||||
|
||||
fn roll() -> u8 {
|
||||
use rand::Rng;
|
||||
|
||||
let roll = rand::thread_rng().gen_range(2..13);
|
||||
println!("\nYou rolled {}.", roll);
|
||||
|
||||
roll
|
||||
}
|
||||
|
||||
fn game_over(&mut self) {
|
||||
self.state = GameState::GameOver;
|
||||
}
|
||||
|
||||
fn prompt_roll(&mut self) {
|
||||
use util::Response::*;
|
||||
|
||||
let response = util::prompt("Ready to roll?");
|
||||
|
||||
match response {
|
||||
Yes => (),
|
||||
No => self.game_over(),
|
||||
}
|
||||
}
|
||||
}
|
||||
27
29_Craps/rust/src/main.rs
Normal file
27
29_Craps/rust/src/main.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
mod craps_game;
|
||||
mod util;
|
||||
use crate::craps_game::CrapsGame;
|
||||
|
||||
fn main() {
|
||||
println!("~~Craps~~");
|
||||
println!("Creative Computing Morristown, New Jersey\n");
|
||||
|
||||
let mut quit = false;
|
||||
|
||||
while !quit {
|
||||
let mut game = CrapsGame::new();
|
||||
|
||||
loop {
|
||||
if !game.tick() {
|
||||
use util::Response::*;
|
||||
|
||||
match util::prompt("New Game?") {
|
||||
Yes => (),
|
||||
No => quit = true,
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
71
29_Craps/rust/src/util.rs
Normal file
71
29_Craps/rust/src/util.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use std::io;
|
||||
|
||||
pub enum Response {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
pub fn read_line() -> String {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin()
|
||||
.read_line(&mut input)
|
||||
.expect("Error reading line.");
|
||||
|
||||
input
|
||||
}
|
||||
|
||||
pub fn read_numeric(message: &str) -> usize {
|
||||
loop {
|
||||
println!("{}", message);
|
||||
|
||||
let mut ok = true;
|
||||
|
||||
let input = read_line();
|
||||
|
||||
for c in input.trim().chars() {
|
||||
if !c.is_numeric() {
|
||||
println!("You can only enter a number!");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ok {
|
||||
let input = input.trim().parse();
|
||||
|
||||
let _ = match input {
|
||||
Ok(i) => return i,
|
||||
Err(e) => {
|
||||
println!("please input a number ({})", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prompt(msg: &str) -> Response {
|
||||
use Response::*;
|
||||
|
||||
let mut _r = Response::Yes;
|
||||
|
||||
loop {
|
||||
println!("\n{}", msg);
|
||||
|
||||
let response = read_line().trim().to_uppercase();
|
||||
|
||||
match response.as_str() {
|
||||
"YES" | "Y" => {
|
||||
_r = Yes;
|
||||
break;
|
||||
}
|
||||
"NO" | "N" => {
|
||||
_r = No;
|
||||
break;
|
||||
}
|
||||
_ => println!("Please input (Y)es or (N)o."),
|
||||
};
|
||||
}
|
||||
|
||||
_r
|
||||
}
|
||||
Reference in New Issue
Block a user