Skip to content

Commit

Permalink
Merge pull request coding-horror#744 from ugurkupeli/30_Cube/rust
Browse files Browse the repository at this point in the history
30 cube/rust
  • Loading branch information
coding-horror committed May 7, 2022
2 parents 926607c + 9c73c6a commit a617a02
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 0 deletions.
9 changes: 9 additions & 0 deletions 30_Cube/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"
106 changes: 106 additions & 0 deletions 30_Cube/rust/src/game.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::util;

pub type Position = (u8, u8, u8);

pub struct Game {
wallet: usize,
bet: Option<usize>,
landmines: Vec<Position>,
player: Position,
}

impl Game {
pub fn new() -> Self {
Game {
wallet: 500,
bet: None,
landmines: util::get_landmines(),
player: (1, 1, 1),
}
}

pub fn play(&mut self) -> bool {
self.bet = self.get_bet();

let mut first_move = true;
let mut result = (false, "******BANG!******\nYOU LOSE");

loop {
let msg = if first_move {
first_move = false;
"ITS YOUR MOVE"
} else {
"NEXT MOVE"
};

let (ok, p) = self.ask_position(msg);

if ok {
if p == (3, 3, 3) {
result.0 = true;
result.1 = "CONGRATULATIONS!";
break;
} else if self.landmines.contains(&p) {
break;
} else {
self.player = p;
}
} else {
result.1 = "ILLEGAL MOVE\nYOU LOSE.";
break;
}
}

println!("{}", result.1);
self.calculate_wallet(result.0);
self.reset_game();

if self.wallet <= 0 {
println!("YOU ARE BROKE!");
return false;
}

return util::prompt_bool("DO YOU WANT TO TRY AGAIN?");
}

fn get_bet(&self) -> Option<usize> {
loop {
if util::prompt_bool("WANT TO MAKE A WAGER?") {
let b = util::prompt_number("HOW MUCH?");

if b != 0 && b <= self.wallet {
return Some(b);
} else {
println!("YOU CAN'T BET THAT!");
}
} else {
return None;
};
}
}

fn ask_position(&self, msg: &str) -> (bool, Position) {
if let Some(p) = util::prompt_position(msg, self.player) {
return (true, p);
}
return (false, (0, 0, 0));
}

fn calculate_wallet(&mut self, win: bool) {
if let Some(b) = self.bet {
if win {
self.wallet += b;
} else {
self.wallet -= b;
}
self.bet = None;
println!("YOU NOW HAVE {} DOLLARS", self.wallet);
}
}

fn reset_game(&mut self) {
self.player = (1, 1, 1);
self.landmines.clear();
self.landmines = util::get_landmines();
}
}
39 changes: 39 additions & 0 deletions 30_Cube/rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::game::Game;

mod game;
mod util;

fn main() {
println!("\n\n\t\tCUBE");
println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");

if util::prompt_bool("DO YOU WANT TO SEE THE INSTRUCTIONS? (YES--1,NO--0)") {
println!("\nThis is a game in which you will be playing against the");
println!("random decisions of the computer. The field of play is a");
println!("cube of side 3. Any of the 27 locations can be designated");
println!("by inputing three numbers such as 2,3,1. At the start,");
println!("you are automatically at location 1,1,1. The object of");
println!("the game is to get to location 3,3,3. One minor detail:");
println!("the computer will pick, at random, 5 locations at which");
println!("it will plant land mines. If you hit one of these locations");
println!("you lose. One other detail: You may move only one space");
println!("in one direction each move. For example: From 1,1,2 you");
println!("may move to 2,1,2 or 1,1,3. You may not change");
println!("two of the numbers on the same move. If you make an illegal");
println!("move, you lose and the computer takes the money you may");
println!("have bet on that round.\n");
println!("When stating the amount of a wager, print only the number");
println!("of dollars (example: 250) you are automatically started with");
println!("500 dollars in your account.\n");
println!("Good luck!\n");
}

let mut game = Game::new();

loop {
if !game.play() {
println!("\nTOUGH LUCK\n\nGOODBYE!\n");
break;
}
}
}
117 changes: 117 additions & 0 deletions 30_Cube/rust/src/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use std::num::ParseIntError;

use crate::game::Position;

pub fn get_random_position() -> Position {
(get_random_axis(), get_random_axis(), get_random_axis())
}

fn get_random_axis() -> u8 {
rand::Rng::gen_range(&mut rand::thread_rng(), 1..=3)
}

pub fn get_landmines() -> Vec<Position> {
let mut landmines = Vec::new();

for _ in 0..5 {
let mut m = get_random_position();
while landmines.contains(&m) {
m = get_random_position();
}
landmines.push(m);
}

landmines
}

fn read_line() -> Result<usize, ParseIntError> {
let mut input = String::new();
std::io::stdin()
.read_line(&mut input)
.expect("~~Failed reading line!~~");
input.trim().parse::<usize>()
}

pub fn prompt_bool(msg: &str) -> bool {
loop {
println!("{}", msg);

if let Ok(n) = read_line() {
if n == 1 {
return true;
} else if n == 0 {
return false;
}
}
println!("ENTER YES--1 OR NO--0\n");
}
}

pub fn prompt_number(msg: &str) -> usize {
loop {
println!("{}", msg);

if let Ok(n) = read_line() {
return n;
}
println!("ENTER A NUMBER\n");
}
}

pub fn prompt_position(msg: &str, prev_pos: Position) -> Option<Position> {
loop {
println!("{}", msg);

let mut input = String::new();
std::io::stdin()
.read_line(&mut input)
.expect("~~Failed reading line!~~");

let input: Vec<&str> = input.trim().split(",").collect();

let pp = [prev_pos.0, prev_pos.1, prev_pos.2];
let mut pos = Vec::new();

if input.len() != 3 {
println!("YOU MUST ENTER 3 AXES!");
} else {
for a in input {
if let Ok(n) = a.parse::<u8>() {
if n == 0 || n > 3 {
println!("YOU MUST ENTER AN AXIS BETWEEN 1 AND 3!");
} else {
pos.push(n);
}
} else {
println!("INVALID LOCATION.");
}
}

let mut moved = false;
for (i, p) in pos.iter().enumerate() {
let dt = ((*p as isize) - (pp[i] as isize)).abs();

if dt > 1 {
return None;
}

if dt == 1 {
if moved {
return None;
} else {
moved = true;
}
}
}
}

if pos.len() == 3 {
let pos = (pos[0], pos[1], pos[2]);
if pos == prev_pos {
println!("YOU ARE ALREADY THERE!");
} else {
return Some(pos);
}
}
}
}

0 comments on commit a617a02

Please sign in to comment.