mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -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