mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-13 00:00:25 -08:00
30_Cube/rust
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user