Skip to content

Instantly share code, notes, and snippets.

@tim54000
Created February 3, 2019 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tim54000/a8b43a1fa73dc38e8952e696a420e189 to your computer and use it in GitHub Desktop.
Save tim54000/a8b43a1fa73dc38e8952e696a420e189 to your computer and use it in GitHub Desktop.
A cool Mine Sweeper grid generator for Discord !
[package]
name = "mine_sweeper"
version = "0.1.0"
authors = ["Tim54000 <tim54000@gmx.com>"]
edition = "2018"
[dependencies]
rand = "*"
structopt = "*"
exitfailure = "*"
failure = "*"
extern crate structopt;
extern crate exitfailure;
extern crate failure;
extern crate rand;
use failure::ResultExt;
use structopt::StructOpt;
use exitfailure::ExitFailure;
use rand::Rng;
#[derive(StructOpt)]
#[structopt(name = "Mine Sweeper", about = "A Mine Sweeper grid generator for Discord!", author = "by Tim54000 <tim54000@gmx.com>", rename_all = "kebab-case")]
/// A cool Mine Sweeper grid generator for Discord !
struct Cli {
#[structopt(short, long)]
/// Get the output without spoilers
solution: bool,
/// The Grid size (size > 3)
///
/// If size is n, the grid will be n*n
size: i32,
/// The Mine Sweeper difficulty (range: 1-5)
///
/// Difficulty levels:
/// 1 - EASY |
/// 2 - MEDIUM |
/// 3 - HARD |
/// 4 - EXTREME |
/// 5 - JUST IMPOSSIBLE
difficulty: i32,
}
impl Cli {
fn format(&self, text: &str) -> String {
match self.solution {
false => format!("||{}||", text),
true => format!("{}", text),
}
}
}
fn main() -> Result<(), ExitFailure> {
let args = Cli::from_args();
if !(args.size > 3) {
let err = Err(failure::err_msg("an off-range grid size. Must be greater than 3 !"));
return Ok(err.context("Invalid grid size !".to_string())?);
}
let bombs: Result<f32, ExitFailure> = match args.difficulty {
1 => Ok(((args.size * args.size) as f32 / 16.0).ceil()),
2 => Ok(((args.size * args.size) as f32 / 11.0).ceil()),
3 => Ok(((args.size * args.size) as f32 / 9.0).ceil()),
4 => Ok(((args.size * args.size) as f32 / 6.0).ceil()),
5 => Ok(((args.size * args.size) as f32 / 3.0).ceil()),
_ => {
let err = Err(failure::err_msg("an off-range difficulty. The difficulty must be included in 1-5"));
return Ok(err.context("Invalid difficulty !".to_string())?);
}
};
let bombs = bombs.unwrap() as i32;
let mut rng = rand::thread_rng();
let mut grid: Vec<Vec<i32>> = vec![vec![0; args.size as usize]; args.size as usize]; // A n*n matrix of 0
for _ in 0..bombs {
let (mut x,mut y) = (0,0);
while { // Randomly choose a box at least once, if it's a bomb, do it again!
x = rng.gen_range(0, args.size - 1) as usize;
y = rng.gen_range(0, args.size - 1) as usize;
grid[x][y] == -1
} {}
// Placing the bomb
grid[x][y] = -1; // A bomb = -1
// Increase the number of bombs in the boxes around
for x in (if x == 0 { 0 } else { x - 1 })..=(if x == (args.size - 1) as usize { x } else { x + 1 }) {
for y in (if y == 0 { 0 } else { y - 1 })..=(if y == (args.size - 1) as usize { y } else { y + 1 }) {
// Of course, we don't change a bomb to box 0.
if grid[x][y] != -1 {
grid[x][y] = grid[x][y] + 1;
}
}
}
}
// We're now formatting the game area for Discord
'print_lines: for x in grid {
let mut line = String::new();
'print_boxes: for y in x {
let case = match y {
-1 => args.format("💣"),
0 => args.format("▫"),
1 => args.format(":one:"),
2 => args.format(":two:"),
3 => args.format(":three:"),
4 => args.format(":four:"),
5 => args.format(":five:"),
6 => args.format(":six:"),
7 => args.format(":seven:"),
8 => args.format(":eight:"),
_ => args.format("🔴"),
};
line += &case;
}
println!("{}", line);
}
Ok(())
}
@tim54000
Copy link
Author

tim54000 commented Feb 3, 2019

Comments on my Framagit snippet are preferred => https://framagit.org/snippets/3160

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment