30_Cube/rust

This commit is contained in:
Uğur Küpeli
2022-05-07 13:31:55 +03:00
parent e9366d3c0c
commit 1d551f420b
3 changed files with 228 additions and 12 deletions

View File

@@ -1,17 +1,106 @@
use crate::util;
pub type Position = (u8, u8, u8);
pub struct Game {
wallet: u8,
bet: u8,
wallet: usize,
bet: Option<usize>,
landmines: Vec<Position>,
player: Position,
}
impl Game {
pub fn new() -> Self {
let mut landmines = Vec::new();
Game {
wallet: 500,
bet: None,
landmines: util::get_landmines(),
player: (1, 1, 1),
}
}
let mut m: Position = (0, 0, 0);
while !landmines.contains(&m) {}
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();
}
}

View File

@@ -1,6 +1,39 @@
use crate::game::Game;
mod game;
mod util;
fn main() {
println!("Hello, world!");
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;
}
}
}

View File

@@ -1,4 +1,8 @@
pub fn get_random_position() -> crate::game::Position {
use std::num::ParseIntError;
use crate::game::Position;
pub fn get_random_position() -> Position {
(get_random_axis(), get_random_axis(), get_random_axis())
}
@@ -6,17 +10,107 @@ fn get_random_axis() -> u8 {
rand::Rng::gen_range(&mut rand::thread_rng(), 1..=3)
}
pub fn prompt(yes_no: bool, msg: &str) -> (u8, bool) {
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 = input.trim();
if yes_no {
if let Ok(n) = input.parse::<u8>(){
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);
}
}
}