extern crate piston_window;
#[macro_use]
extern crate clap;
extern crate chrono;
extern crate rand;
extern crate find_folder;
mod game;
mod field;
mod ui;
mod common;
use piston_window::*;
use clap::{Arg, App};
fn main() {
let matches = App::new("Minesweeper")
.author("Alexander Kuvaev <alexander@kuvaev.me>")
.version(&*format!("v{}", crate_version!()))
.about("Simple minesweeper in Rust ")
.arg(Arg::from_usage("-s, --size [size] 'window size \"width\"x\"height\"'")
.validator(|val| {
let mut s = val.split("x");
match s.next() {
Some(w) => {
match w.parse::<u32>() {
Ok(r) => {
if (r < 100) || (r > 4096) {
return Err(format!("window width must be between 100 and 4096"))
}
},
Err(e) => return Err(format!("window width arg error: {}", e))
}
}
None => return Err(format!("window size expected \"width\"x\"height\", got {}", val))
}
match s.next() {
Some(h) => {
match h.parse::<u32>() {
Ok(r) => {
if (r < 100) || (r > 3072) {
return Err(format!("window height must be between 100 and 3072"))
}
},
Err(e) => return Err(format!("window height arg error: {}", e))
}
}
None => return Err(format!("window size expected \"width\"x\"height\", got {}", val))
}
match s.next() {
Some(_r) => Err(format!("window size arg expected \"width\"x\"height\", got {}", val)),
None => Ok(())
}
}))
.arg(Arg::from_usage("-f, --field [field] 'field size \"width\"x\"height\"'")
.validator(|val| {
let mut s = val.split("x");
match s.next() {
Some(w) => {
match w.parse::<u32>() {
Ok(r) => {
if (r < 5) || (r > 100) {
return Err(format!("field width must be between 5 and 100"))
}
},
Err(e) => return Err(format!("field width arg error: {}", e))
}
}
None => return Err(format!("field size expected \"width\"x\"height\", got {}", val))
}
match s.next() {
Some(h) => {
match h.parse::<u32>() {
Ok(r) => {
if (r < 5) || (r > 100) {
return Err(format!("field height must be between 5 and 100"))
}
},
Err(e) => return Err(format!("field height arg error: {}", e))
}
}
None => return Err(format!("field size expected \"width\"x\"height\", got {}", val))
}
match s.next() {
Some(_r) => Err(format!("field size arg expected \"width\"x\"height\", got {}", val)),
None => Ok(())
}
}))
.arg(Arg::from_usage("-m, --mines [mines] 'max mines'"))
.arg(Arg::from_usage("--oldOGL 'set OpenGL version to 2.1'"))
.arg(Arg::from_usage("--maxFPS [max_fps] 'set max fps'"))
.get_matches();
let mut width = 1024;
let mut height = 768;
let mut f_width = 20;
let mut f_height = 20;
let mut mines = 50;
let mut max_fps = 60;
let mut opengl = OpenGL::V3_2;
if let Some(size) = matches.value_of("size") {
let mut s = size.split("x");
width = s.next().unwrap().parse().unwrap_or(width);
height = s.next().unwrap().parse().unwrap_or(height);
}
if let Some(field) = matches.value_of("field") {
let mut s = field.split("x");
f_width = s.next().unwrap().parse().unwrap_or(f_width);
f_height = s.next().unwrap().parse().unwrap_or(f_height);
}
if let Some(m) = matches.value_of("mines") {
mines = m.parse().unwrap_or(mines);
}
if let Some(m) = matches.value_of("max_fps") {
max_fps = m.parse().unwrap_or(max_fps);
}
if matches.is_present("oldOGL") {
opengl = OpenGL::V2_1;
}
let mut window: PistonWindow = WindowSettings::new("Minesweeper", [width, height])
.opengl(opengl)
.exit_on_esc(true)
.build()
.expect("Try running with --oldOGL");
let assets = find_folder::Search::ParentsThenKids(3, 3)
.for_folder("assets")
.unwrap();
let ref font = assets.join("FiraSans-Regular.ttf");
let factory = window.factory.clone();
let glyphs = Glyphs::new(font, factory).unwrap();
let mut game = game::Game::new(glyphs, f_width, f_height, mines);
window.set_max_fps(max_fps);
while let Some(e) = window.next() {
game.update_state();
if let Some(_) = e.render_args() {
game.render(&mut window, &e);
}
if let Some(_) = e.resize_args() {
game.resize()
}
if let Some(mouse_rel) = e.mouse_cursor_args() {
game.mouse_move(mouse_rel);
}
if let Some(button) = e.press_args() {
game.proc_key(button, &window);
}
}
}