Skip to content

Commit

Permalink
Merge pull request #736 from ugurkupeli/29_Craps/rust
Browse files Browse the repository at this point in the history
rust port of craps
  • Loading branch information
coding-horror committed May 5, 2022
2 parents 6dd3521 + af910ac commit 3e8b390
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 0 deletions.
9 changes: 9 additions & 0 deletions 29_Craps/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 changes: 141 additions & 0 deletions 29_Craps/rust/src/craps_game.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 27 additions & 0 deletions 29_Craps/rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 71 additions & 0 deletions 29_Craps/rust/src/util.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 3e8b390

Please sign in to comment.