diff --git a/75_Roulette/rust/Cargo.toml b/75_Roulette/rust/Cargo.toml new file mode 100644 index 00000000..37f4add7 --- /dev/null +++ b/75_Roulette/rust/Cargo.toml @@ -0,0 +1,10 @@ +[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] +morristown = "0.1.4" +rand = "0.8.5" diff --git a/75_Roulette/rust/src/main.rs b/75_Roulette/rust/src/main.rs new file mode 100644 index 00000000..b0fd8765 --- /dev/null +++ b/75_Roulette/rust/src/main.rs @@ -0,0 +1,106 @@ +mod util; + +use morristown::{Instructions, PromptMultiOption}; +use rand::Rng; +use util::INSTRUCTIONS; + +fn main() { + morristown::print_intro("ROULETTE"); + + let date = morristown::prompt_multi_string( + "ENTER CURRENT DATE (AS IN 'JANUARY 23, 1978)", + ",", + Some(PromptMultiOption::UnitAmount(2)), + ); + + Instructions::new_multiline( + true, + false, + "DO YOU WANT INSTRUCTIONS?", + INSTRUCTIONS.to_vec(), + ) + .print(); + + let mut house: usize = 100000; + let mut player: usize = 1000; + + loop { + let bet_count = morristown::prompt_number_range::("HOW MANY BETS?", 1..=10); + let mut bets: Vec> = Vec::new(); + + for i in 1..=bet_count { + loop { + let msg = format!("NUMBER {}?", i); + let bet_input = morristown::prompt_multi_number::( + msg.as_str(), + ",", + Some(PromptMultiOption::UnitAmount(2)), + None, + ); + let (bet_num, wager) = (bet_input[0], bet_input[1]); + + if let Some(_) = bets.iter().find(|bet| bet[0] == bet_num) { + println!("YOU MADE THAT BET ONCE ALREADY, DUM-DUM"); + } else if bet_num > 0 && bet_num <= 50 && wager >= 5 && wager <= 500 { + bets.push(bet_input); + player -= wager; + house += wager; + break; + } else if wager > player { + println!("NOT ENOUGH MONEY") + } else { + println!("INVALID BET. TRY AGAIN"); + } + } + } + + println!("\nSPINNING"); + std::thread::sleep(std::time::Duration::from_secs(1)); + let spin: u8 = rand::thread_rng().gen_range(1..=38); + + let color = if util::REDS.contains(&spin) { + "RED" + } else { + "BLACK" + }; + + println!("\n{} {}\n", spin, color); + + for (i, bet) in bets.iter().enumerate() { + let (bet_num, wager) = (bet[0] as u8, bet[1]); + let (win, payoff) = util::process_bet(bet_num, spin); + + let msg = if win { + let pay = wager * payoff as usize; + player += wager + pay; + house -= pay; + "WIN" + } else { + "LOSE" + }; + + println!("YOU {msg} {wager} DOLLARS ON BET {}", i + 1); + } + + println!("\nTOTALS:\t\tME\t\tYOU"); + println!("\t\t{house}\t\t{player}"); + + if player <= 0 { + println!("OOPS! YOU JUST SPENT YOUR LAST DOLLAR"); + println!("THANKS FOR YOUR MONEY"); + println!("I'LL USE IT TO BUY A SOLID GOLD ROULETTE WHEEL"); + break; + } + + if house <= 0 { + println!("YOU BROKE THE HOUSE!"); + util::print_check(player, date); + break; + } + + if !morristown::prompt_bool("AGAIN?", false) { + util::print_check(player, date); + break; + } + } +} diff --git a/75_Roulette/rust/src/util.rs b/75_Roulette/rust/src/util.rs new file mode 100644 index 00000000..321a1416 --- /dev/null +++ b/75_Roulette/rust/src/util.rs @@ -0,0 +1,91 @@ +use std::ops::RangeInclusive; + +use rand::{thread_rng, Rng}; + +pub const INSTRUCTIONS: [&str; 38] = [ + "\nTHIS IS THE BETTING LAYOUT", + "\n(*=RED)\n", + "1*\t2\t3*", + "4\t5*\t6", + "7*\t8\t9*", + "10\t11\t12*", + "--------------------", + "13\t14*\t15", + "16*\t17\t18*", + "19*\t20\t21*", + "22\t23*\t24", + "--------------------", + "25*\t26\t27*", + "28\t29\t30*", + "31\t32*\t33", + "34*\t35\t36*", + "--------------------", + " 00 0\n", + "TYPES OF BETS\n", + "THE NUMBERS 1 TO 36 SIGNIFY A STRAIGHT BET", + "ON THAT NUMBER", + "THESE PAY OFF 35:1\n", + "THE 2:1 BETS ARE:", + "37) 1-12\t40) FIRST COLUMN", + "38) 13-24\t41) SECOND COLUMN", + "39) 25-36\t42) THIRD COLUMN\n", + "THE EVEN MONEY BETS ARE:", + "43) 1-18\t46) ODD", + "44) 19-36\t47) RED", + "45) EVEN\t48) BLACK\n", + "\n49)0 AND 50)00 PAY OFF 35:1", + "NOTE: 0 AND 00 DO NOT COUNT UNDER ANY", + "\tBETS EXCEPT THEIR OWN\n", + "WHEN I ASK FOR EACH BET,TYPE THE NUMBER", + "AND THE AMOUNT,SEPARATED BY A COMMA", + "FOR EXAMPLE:TO BET $500 ON BLACK,TYPE 48,500", + "WHEN I ASK FOR A BET\n", + "MINIMUM BET IS $5,MAXIMUM IS $500\n", +]; + +pub const REDS: [u8; 18] = [ + 1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36, +]; + +pub fn process_bet(bet_num: u8, spin: u8) -> (bool, u8) { + match bet_num { + 1..=36 => (bet_num == spin, 35), + 37 => (is_within_range(1..=12, spin), 2), + 38 => (is_within_range(13..=24, spin), 2), + 39 => (is_within_range(25..=36, spin), 2), + 40 => (spin % 3 == 1, 2), + 41 => (spin % 3 == 2, 2), + 42 => (spin % 3 == 0, 2), + 43 => (is_within_range(1..=18, spin), 1), + 44 => (is_within_range(19..=36, spin), 1), + 45 => (spin % 2 == 0, 1), + 46 => (spin % 2 == 1, 1), + 47 => (REDS.contains(&spin), 1), + 48 => (!REDS.contains(&spin), 1), + _ => { + println!("##INVALID BET##"); + return (false, 0); + } + } +} + +fn is_within_range(r: RangeInclusive, n: u8) -> bool { + r.contains(&n) +} + +pub fn print_check(money: usize, date: Vec) { + let name = morristown::prompt_string("TO WHOM SHALL I MAKE THE CHECK?"); + let check_no = thread_rng().gen_range(1..=100); + + let dashes = 60; + + println!("\n{}", "-".repeat(dashes)); + println!("CHECK NO. {}\n", check_no); + println!("{}{}, {}\n\n", "\t".repeat(4), date[0], date[1]); + println!("PAY TO THE ORDER OF-----{name}-----$ {money}\n\n"); + println!("\t\tTHE MEMORY BANK OF VIRGINIA\n"); + println!("\t\t\t\tTHE COMPUTER"); + println!("\t\t\t ----------X-----\t"); + println!("{}", "-".repeat(dashes)); + println!("COME BACK SOON!\n") +}