rust port of craps

This commit is contained in:
Uğur Küpeli
2022-05-03 14:53:29 +03:00
parent e513b77ac5
commit af910ac126
4 changed files with 248 additions and 0 deletions

9
29_Craps/rust/Cargo.toml Normal file
View 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"

View 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
View 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
View 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
}