Created
August 30, 2019 22:18
-
-
Save BrandonDyer64/4699b545908470dc1950a51648bc8144 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate rand; | |
use rand::prelude::*; | |
use std::io::{self, Write}; | |
#[derive(PartialEq, Debug, Clone, Copy)] | |
enum Cell { | |
Covered(bool), | |
Revealed(u8) | |
} | |
fn main() { | |
let width = 16; | |
let height = 16; | |
let num_mines = 32; | |
let mut board = build_board(width, height, num_mines); | |
loop { | |
print_board(&board, width, false); | |
if check_win(&board) { | |
println!("WIN!"); | |
::std::process::exit(0); | |
} | |
make_move(&mut board, width as isize, height as isize); | |
} | |
} | |
fn build_board(width: usize, height: usize, num_mines: i32) -> Vec<Cell> { | |
let mut board = vec![Cell::Covered(false); width * height]; | |
let mut rng = rand::thread_rng(); | |
for _ in 0..num_mines { | |
let choice = rng.gen::<usize>() % (width * height); | |
board[choice] = Cell::Covered(true); | |
} | |
let width = width as isize; | |
let height = height as isize; | |
let x = width / 2; | |
let y = height / 2; | |
for y in y-1isize..y+2isize { | |
for x in x-1isize..x+2isize { | |
if 0 > y || y > height - 1 { continue; } | |
if 0 > x || x > width - 1 { continue; } | |
board[(x + y * width) as usize] = Cell::Covered(false); | |
} | |
} | |
apply_move(&mut board, width / 2, height / 2, width, height); | |
board | |
} | |
fn print_board(board: &Vec<Cell>, width: usize, revealed: bool) { | |
print!("\n "); | |
for x in 1 .. width + 1 { | |
print!("{:>2}", x); | |
} | |
println!(); | |
for i in 0..board.len() { | |
if (i) % width == 0 { | |
print!("{:>2} ", i / width + 1); | |
} | |
let out: String = match board[i] { | |
Cell::Covered(is_mine) if revealed && is_mine => "◉".into(), | |
Cell::Covered(is_mine) if revealed && !is_mine => "◌".into(), | |
Cell::Covered(_) => "□".into(), | |
Cell::Revealed(num) if num != 0 => num.to_string(), | |
Cell::Revealed(_) => "·".into(), | |
}; | |
print!("{} ", out); | |
if (i + 1) % width == 0 { | |
println!(); | |
} | |
} | |
println!(); | |
} | |
fn check_win(board: &Vec<Cell>) -> bool { | |
for cell in board { | |
if let Cell::Covered(is_mine) = cell { | |
if !is_mine { | |
return false; | |
} | |
} | |
} | |
true | |
} | |
fn make_move(board: &mut Vec<Cell>, width: isize, height: isize) { | |
let x = get_user_input("X".into()); | |
let y = get_user_input("Y".into()); | |
if 0 > x || x > width - 1 || 0 > y || y > height - 1 { | |
println!("out of bounds"); | |
return; | |
} | |
apply_move(board, x, y, width, height); | |
} | |
fn apply_move(board: &mut Vec<Cell>, x: isize, y: isize, width: isize, height: isize) { | |
let index = x + y * width; | |
if let Cell::Covered(is_mine) = board[index as usize] { | |
if is_mine { | |
println!("BOOM!"); | |
print_board(board, width as usize, true); | |
::std::process::exit(0); | |
} | |
let mut count = 0; | |
for y in y-1isize..y+2isize { | |
for x in x-1isize..x+2isize { | |
if 0 > y || y > height - 1 { continue; } | |
if 0 > x || x > width - 1 { continue; } | |
if let Cell::Covered(is_mine) = board[(x + y * width) as usize] { | |
if is_mine { | |
count += 1; | |
} | |
} | |
} | |
} | |
board[index as usize] = Cell::Revealed(count); | |
if count == 0 { | |
for y in y-1isize..y+2isize { | |
for x in x-1isize..x+2isize { | |
if 0 > y || y > height - 1 { continue; } | |
if 0 > x || x > width - 1 { continue; } | |
apply_move(board, x, y, width, height); | |
} | |
} | |
} | |
}; | |
} | |
fn get_user_input(name: String) -> isize { | |
let mut input = String::new(); | |
print!("{}: ", name); | |
io::stdout().flush().ok().expect("Could not flush stdout"); | |
io::stdin().read_line(&mut input).expect("failed to read"); | |
match input.trim().parse::<isize>() { | |
Ok(x) => x - 1, | |
Err(_) => { | |
println!("Please enter an integer"); | |
get_user_input(name) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment