Skip to content

Commit

Permalink
Merge pull request #749 from ugurkupeli/11_Bombardment/rust
Browse files Browse the repository at this point in the history
11_Bombardment/rust
  • Loading branch information
coding-horror committed May 13, 2022
2 parents 1ed0738 + 8780a6c commit 9cd4dd3
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 0 deletions.
10 changes: 10 additions & 0 deletions 11_Bombardment/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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]
rand = "0.8.5"
morristown = "0.1.4"
134 changes: 134 additions & 0 deletions 11_Bombardment/rust/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use morristown::PromptMultiOption;
use rand::{prelude::SliceRandom, thread_rng};
use std::time::Duration;

fn main() {
morristown::print_intro("BOMBARDMENT");

println!(
r#"
YOU ARE ON A BATTLEFIELD WITH 4 PLATOONS AND YOU
HAVE 25 OUTPOSTS AVAILABLE WHERE THEY MAY BE PLACED.
YOU CAN ONLY PLACE ONE PLATOON AT ANY ONE OUTPOST.
THE COMPUTER DOES THE SAME WITH ITS FOUR PLATOONS.
THE OBJECT OF THE GAME IS TO FIRE MISSLES AT THE
OUTPOSTS OF THE COMPUTER. IT WILL DO THE SAME TO YOU.
THE ONE WHO DESTROYS ALL FOUR OF THE ENEMY'S PLATOONS
FIRST IS THE WINNER.
GOOD LUCK... AND TELL US WHERE YOU WANT THE BODIES SENT!
TEAR OFF MATRIX AND USE IT TO CHECK OFF THE NUMBERS.
"#
);

let mut all_positions = Vec::with_capacity(25);

for i in 1u8..=25 {
all_positions.push(i);

print!("{i}\t");
if (i % 5) == 0 {
println!();
}
}

let mut player_positions = morristown::prompt_multi_number::<u8>(
"WHAT ARE YOUR FOUR POSITIONS?\n",
",",
Some(PromptMultiOption::UnitAmount(4)),
Some(1..=25),
);

let mut rng = thread_rng();

let ai_positions = rand::seq::index::sample(&mut rng, 24, 4).into_vec();
let mut ai_positions: Vec<u8> = ai_positions.iter().map(|i| (i + 1) as u8).collect();

loop {
if !player_turn(&mut ai_positions) {
break;
} else if !ai_turn(&mut all_positions, &mut player_positions) {
break;
}
}
}

fn player_turn(ai_positions: &mut Vec<u8>) -> bool {
let player_missile =
morristown::prompt_number_range::<u8>("WHERE DO YOU WISH TO FIRE YOUR MISSILE?", 1..=25);

if let Some(index) = ai_positions.iter().position(|p| *p == player_missile) {
ai_positions.remove(index);

let remaining = ai_positions.len();

if remaining > 0 {
let down = 4 - remaining;

println!(
"YOU GOT ONE OF MY OUTPOSTS.\n{} DOWN, {} TO GO\n",
get_text_from_number(down),
get_text_from_number(remaining)
);
} else {
println!(
"YOU GOT ME, I'M GOING FAST. BUT I'LL GET YOU WHEN MY TRANSISTO&S RECUP%RA*E!\n\n"
);
return false;
}
} else {
println!("HA, HA YOU MISSED. MY TURN NOW\n");
}
true
}

fn ai_turn(all_positions: &mut Vec<u8>, player_positions: &mut Vec<u8>) -> bool {
std::thread::sleep(Duration::from_secs(1));

let ai_missile = *all_positions
.choose(&mut rand::thread_rng())
.expect("AI RAN OUT OF OPTIONS!");

let index = all_positions
.iter()
.position(|p| p == &ai_missile)
.expect("AI CHOOSE AN INVALID POSITION!");

all_positions.remove(index);

if let Some(index) = player_positions.iter().position(|p| p == &ai_missile) {
player_positions.remove(index);

let remaining = player_positions.len();

if remaining > 0 {
println!("I GOT YOU. IT WON'T BE LONG NOW. POST {ai_missile} WAS HIT.");
println!(
"YOU HAVE ONLY {} OUTPOST LEFT.\n",
get_text_from_number(remaining)
);
} else {
println!("YOU'RE DEAD. YOUR LAST OUTPOST WAS AT {ai_missile} . HA, HA, HA.");
println!("BETTER LUCK NEXT TIME.");
return false;
}
} else {
println!("I MISSED YOU, YOU DIRTY RAT. I PICKED {ai_missile} . YOUR TURN.\n")
}

true
}

fn get_text_from_number(n: usize) -> &'static str {
match n {
1 => "ONE",
2 => "TWO",
3 => "THREE",
_ => panic!("INVALID INDEX!"),
}
}

0 comments on commit 9cd4dd3

Please sign in to comment.