mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-23 07:29:02 -08:00
enterprise now starts in a random quadrant and empty sector
This commit is contained in:
@@ -6,3 +6,4 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::io::stdin;
|
||||
use std::io::{stdin, stdout, Write};
|
||||
|
||||
use model::{Galaxy, GameStatus};
|
||||
use update::Message;
|
||||
@@ -18,10 +18,13 @@ fn main() {
|
||||
|
||||
fn wait_for_command(game_status: &GameStatus) -> Message {
|
||||
let stdin = stdin();
|
||||
let mut stdout = stdout();
|
||||
loop {
|
||||
match game_status {
|
||||
_ => {
|
||||
println!("Command?");
|
||||
print!("Command? ");
|
||||
let _ = stdout.flush();
|
||||
|
||||
let mut buffer = String::new();
|
||||
if let Ok(_) = stdin.read_line(&mut buffer) {
|
||||
let text = buffer.trim_end();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use rand::Rng;
|
||||
|
||||
pub struct Galaxy {
|
||||
pub quadrants: Vec<Quadrant>,
|
||||
@@ -14,9 +15,14 @@ impl Pos {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum SectorStatus {
|
||||
Empty, Star, StarBase, Klingon
|
||||
}
|
||||
|
||||
pub struct Quadrant {
|
||||
pub stars: Vec<Pos>,
|
||||
pub star_bases: Vec<Pos>,
|
||||
pub star_base: Option<Pos>,
|
||||
pub klingons: Vec<Klingon>
|
||||
}
|
||||
|
||||
@@ -35,10 +41,83 @@ pub enum GameStatus {
|
||||
|
||||
impl Galaxy {
|
||||
pub fn generate_new() -> Self {
|
||||
let quadrants = Self::generate_quadrants();
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let enterprise_quadrant = Pos(rng.gen_range(0..8), rng.gen_range(0..8));
|
||||
let enterprise_sector = quadrants[enterprise_quadrant.as_index()].find_empty_sector();
|
||||
|
||||
Galaxy {
|
||||
quadrants: Vec::new(),
|
||||
enterprise: Enterprise { quadrant: Pos(0,0), sector: Pos(0,0) },
|
||||
quadrants: quadrants,
|
||||
enterprise: Enterprise { quadrant: enterprise_quadrant, sector: enterprise_sector },
|
||||
game_status: GameStatus::ShortRangeScan
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_quadrants() -> Vec<Quadrant> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut result = Vec::new();
|
||||
for _ in 0..64 {
|
||||
|
||||
let mut quadrant = Quadrant { stars: Vec::new(), star_base: None, klingons: Vec::new() };
|
||||
let star_count = rng.gen_range(0..=7);
|
||||
for _ in 0..star_count {
|
||||
quadrant.stars.push(quadrant.find_empty_sector());
|
||||
}
|
||||
|
||||
if rng.gen::<f64>() > 0.96 {
|
||||
quadrant.star_base = Some(quadrant.find_empty_sector());
|
||||
}
|
||||
|
||||
let klingon_count =
|
||||
match rng.gen::<f64>() {
|
||||
n if n > 0.98 => 3,
|
||||
n if n > 0.95 => 2,
|
||||
n if n > 0.8 => 1,
|
||||
_ => 0
|
||||
};
|
||||
for _ in 0..klingon_count {
|
||||
quadrant.klingons.push(Klingon { sector: quadrant.find_empty_sector() });
|
||||
}
|
||||
|
||||
result.push(quadrant);
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Quadrant {
|
||||
pub fn sector_status(&self, sector: &Pos) -> SectorStatus {
|
||||
if self.stars.contains(§or) {
|
||||
SectorStatus::Star
|
||||
} else if self.is_starbase(§or) {
|
||||
SectorStatus::StarBase
|
||||
} else if self.has_klingon(§or) {
|
||||
SectorStatus::Klingon
|
||||
} else {
|
||||
SectorStatus::Empty
|
||||
}
|
||||
}
|
||||
|
||||
fn is_starbase(&self, sector: &Pos) -> bool {
|
||||
match &self.star_base {
|
||||
None => false,
|
||||
Some(p) => p == sector
|
||||
}
|
||||
}
|
||||
|
||||
fn has_klingon(&self, sector: &Pos) -> bool {
|
||||
let klingons = &self.klingons;
|
||||
klingons.into_iter().find(|k| &k.sector == sector).is_some()
|
||||
}
|
||||
|
||||
fn find_empty_sector(&self) -> Pos {
|
||||
let mut rng = rand::thread_rng();
|
||||
loop {
|
||||
let pos = Pos(rng.gen_range(0..8), rng.gen_range(0..8));
|
||||
if self.sector_status(&pos) == SectorStatus::Empty {
|
||||
return pos
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::model::{Galaxy, GameStatus, Quadrant, Pos, Klingon};
|
||||
use crate::model::{Galaxy, GameStatus, Quadrant, Pos, SectorStatus};
|
||||
|
||||
|
||||
pub fn view(model: &Galaxy) {
|
||||
@@ -17,19 +17,16 @@ fn render_quadrant(enterprise_sector: &Pos, quadrant: &Quadrant) {
|
||||
let pos = Pos(x, y);
|
||||
if &pos == enterprise_sector {
|
||||
print!("<*> ")
|
||||
} else if quadrant.stars.contains(&pos) {
|
||||
print!(" * ")
|
||||
} else if quadrant.star_bases.contains(&pos) {
|
||||
print!(">!< ")
|
||||
} else if let Some(_) = find_klingon(&pos, &quadrant.klingons) {
|
||||
print!("+K+ ")
|
||||
}
|
||||
} else {
|
||||
match quadrant.sector_status(&pos) {
|
||||
SectorStatus::Star => print!(" * "),
|
||||
SectorStatus::StarBase => print!(">!< "),
|
||||
SectorStatus::Klingon => print!("+K+ "),
|
||||
_ => print!(" "),
|
||||
}
|
||||
}
|
||||
}
|
||||
print!("\n")
|
||||
}
|
||||
println!("{:-^33}", "");
|
||||
}
|
||||
|
||||
fn find_klingon<'a>(sector: &Pos, klingons: &'a Vec<Klingon>) -> Option<&'a Klingon> {
|
||||
klingons.into_iter().find(|k| &k.sector == sector)
|
||||
}
|
||||
Reference in New Issue
Block a user