diff --git a/62_Mugwump/rust/src/coordinate.rs b/62_Mugwump/rust/src/coordinate.rs index f44a289f..f13eb240 100644 --- a/62_Mugwump/rust/src/coordinate.rs +++ b/62_Mugwump/rust/src/coordinate.rs @@ -1,13 +1,19 @@ +#![allow(dead_code)] + #[derive(Debug)] pub struct Coordinate { - x: usize, - y: usize, + x: u8, + y: u8, pub state: CoordState, + pub mugwump_number: u8, } impl Coordinate { - pub fn new(pos: (usize, usize), has_mugwump: bool) -> Self { + pub fn new(pos: (u8, u8), has_mugwump: bool, mugwump_number: i32) -> Self { + let mut mug_no = 0; + let state = if has_mugwump { + mug_no = mugwump_number; CoordState::HasMugwump } else { CoordState::Normal @@ -17,8 +23,13 @@ impl Coordinate { x: pos.0, y: pos.1, state, + mugwump_number: mug_no as u8, } } + + pub fn get_pos(&self) -> (u8, u8) { + (self.x, self.y) + } } #[derive(Debug, PartialEq)] @@ -26,4 +37,5 @@ pub enum CoordState { Normal, HasMugwump, Checked, + FoundMugwump, } diff --git a/62_Mugwump/rust/src/draw.rs b/62_Mugwump/rust/src/draw.rs index 5b0e7af0..66de993a 100644 --- a/62_Mugwump/rust/src/draw.rs +++ b/62_Mugwump/rust/src/draw.rs @@ -1,6 +1,6 @@ use crate::coordinate::{CoordState, Coordinate}; -pub fn draw_board(coords: Vec) { +pub fn draw_board(coords: &Vec) { let draw_top_bottom = |is_top: bool| { let (mut left, mut right) = ("β•”", "β•—"); @@ -26,16 +26,21 @@ pub fn draw_board(coords: Vec) { print!("β•‘ {} ", y); for (i, c) in coords.iter().enumerate() { - let mut _char = ' '; + { + use CoordState::*; - match c.state { - CoordState::Normal => _char = '-', - CoordState::HasMugwump => _char = 'π‘—Œ', - CoordState::Checked => _char = '*', + let mut _char = ' '; + + match c.state { + Normal => _char = '-', + HasMugwump => _char = 'ΓΌ', + Checked => _char = '*', + FoundMugwump => _char = 'π‘—Œ', + } + + print!("{} ", _char); } - print!("{} ", _char); - if ((i + 1) % 10) == 0 { y -= 1; @@ -48,7 +53,7 @@ pub fn draw_board(coords: Vec) { } } - print!("β•‘ π‘—Œ "); + print!("β•‘ β™₯︎ "); for i in 0..10 { print!("{} ", i); diff --git a/62_Mugwump/rust/src/game.rs b/62_Mugwump/rust/src/game.rs index 1b45bab8..f47848c0 100644 --- a/62_Mugwump/rust/src/game.rs +++ b/62_Mugwump/rust/src/game.rs @@ -1,11 +1,14 @@ use rand::Rng; -use crate::coordinate::Coordinate; +use crate::{ + coordinate::{CoordState, Coordinate}, + draw::draw_board, + util, +}; pub struct Game { pub coords: Vec, tries: u8, - pub state: GameState, } impl Game { @@ -25,13 +28,17 @@ impl Game { let mut x = 0; let mut y: i8 = 9; + let mut mugwump_number = 0; + for i in 0..100 { let mut has_mugwump = false; + if random_indexes.contains(&i) { has_mugwump = true; + mugwump_number += 1; } - coords.push(Coordinate::new((x, y as usize), has_mugwump)); + coords.push(Coordinate::new((x, y as u8), has_mugwump, mugwump_number)); x += 1; @@ -41,16 +48,91 @@ impl Game { } } - Game { - coords, - tries: 0, - state: GameState::Playing, + Game { coords, tries: 0 } + } + + pub fn tick(&mut self) -> bool { + if self.tries >= 10 { + return false; + } + + if self.get_mugwumps().len() == 0 { + return false; + } + + // ASK FOR PLAY AGAIN! + + self.tries += 1; + + draw_board(&self.coords); + + let entered_position = self.input_coordinate(); + self.check_position(entered_position); + + true + } + + fn check_position(&mut self, pos: (u8, u8)) { + if let Some(coord) = self.coords.iter_mut().find(|c| c.get_pos() == pos) { + use CoordState::*; + + match coord.state { + Normal => self.print_distances(pos), + HasMugwump => { + coord.state = FoundMugwump; + println!("YOU FOUND MUGWUMP {}", coord.mugwump_number); + self.print_distances(pos); + } + Checked | FoundMugwump => println!("YOU ALREADY LOOKED HERE!"), + } } } -} -pub enum GameState { - Playing, - Win, - Lose, + fn print_distances(&self, (x, y): (u8, u8)) { + println!("\n"); + + let print = |m: &Coordinate| { + let (mx, my) = m.get_pos(); + let (x, y, mx, my) = (x as i32, y as i32, mx as i32, my as i32); + let distance = (((x - mx).pow(2) + (y - my).pow(2)) as f32).sqrt(); + + println!( + "YOU ARE {} UNITS FROM MUGWUMP {}", + distance, m.mugwump_number + ); + }; + + for m in self.get_mugwumps() { + print(m); + } + } + + fn input_coordinate(&self) -> (u8, u8) { + let msg = format!("TURN NO. {} WHAT IS YOUR GUESS?", self.tries); + let input = util::prompt(msg.as_str()); + + if !input.contains(",") { + println!("YOU MUST ENTER A COORDINATE: #,#"); + return (0, 0); + } + + let axes: Vec<&str> = input.split(",").collect(); + let mut pos = [0; 2]; + + for (i, a) in axes.iter().enumerate() { + match a.parse::() { + Ok(p) => pos[i] = p as u8, + Err(_) => println!("YOU MUST ENTER A COORDINATE: #,#"), + } + } + + (pos[0], pos[1]) + } + + fn get_mugwumps(&self) -> Vec<&Coordinate> { + self.coords + .iter() + .filter(|c| c.state == CoordState::HasMugwump) + .collect() + } } diff --git a/62_Mugwump/rust/src/main.rs b/62_Mugwump/rust/src/main.rs index 8ed8d292..b0a03829 100644 --- a/62_Mugwump/rust/src/main.rs +++ b/62_Mugwump/rust/src/main.rs @@ -1,10 +1,9 @@ -#![allow(dead_code)] - mod coordinate; mod draw; mod game; +pub mod util; -use crate::{draw::draw_board, game::Game}; +use crate::game::Game; fn main() { println!("\n\nMUGWUMP"); @@ -15,10 +14,21 @@ fn main() { println!("ANY GUESS YOU MAKE MUST BE TWO NUMBERS WITH EACH"); println!("NUMBER BETWEEN 0 AND 9, INCLUSIVE. FIRST NUMBER"); println!("IS DISTANCE TO RIGHT OF HOMEBASE AND SECOND NUMBER"); - println!("IS DISTANCE ABOVE HOMEBASE!"); + println!("IS DISTANCE ABOVE HOMEBASE!\n"); + println!("YOU GET 10 TRIES. AFTER EACH TRY, I WILL TELL"); println!("YOU HOW FAR YOU ARE FROM EACH MUGWUMP.\n"); - let game = Game::new(); - draw_board(game.coords); + let mut _quit = false; + + while !_quit { + let mut game = Game::new(); + + loop { + if !game.tick() { + _quit = true; + break; + } + } + } } diff --git a/62_Mugwump/rust/src/util.rs b/62_Mugwump/rust/src/util.rs new file mode 100644 index 00000000..1ce2e1d5 --- /dev/null +++ b/62_Mugwump/rust/src/util.rs @@ -0,0 +1,13 @@ +use std::io; + +pub fn prompt(msg: &str) -> String { + println!("\n{}", msg); + + let mut input = String::new(); + + io::stdin() + .read_line(&mut input) + .expect("Failed to read line."); + + input.trim().to_string() +}