mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2026-01-04 00:57:13 -08:00
game loop almost done
todo: play again prompts and exit
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::coordinate::{CoordState, Coordinate};
|
||||
|
||||
pub fn draw_board(coords: Vec<Coordinate>) {
|
||||
pub fn draw_board(coords: &Vec<Coordinate>) {
|
||||
let draw_top_bottom = |is_top: bool| {
|
||||
let (mut left, mut right) = ("╔", "╗");
|
||||
|
||||
@@ -26,16 +26,21 @@ pub fn draw_board(coords: Vec<Coordinate>) {
|
||||
|
||||
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<Coordinate>) {
|
||||
}
|
||||
}
|
||||
|
||||
print!("║ 𑗌 ");
|
||||
print!("║ ♥︎ ");
|
||||
for i in 0..10 {
|
||||
print!("{} ", i);
|
||||
|
||||
|
||||
@@ -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<Coordinate>,
|
||||
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::<usize>() {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
62_Mugwump/rust/src/util.rs
Normal file
13
62_Mugwump/rust/src/util.rs
Normal file
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user