Add color and winning / losing
This commit is contained in:
parent
003757b36c
commit
33d97cd311
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -6,6 +6,12 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorful"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0bca1619ff57dd7a56b58a8e25ef4199f123e78e503fe1653410350a1b98ae65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
@ -74,6 +80,7 @@ dependencies = [
|
|||||||
name = "rustsweeper"
|
name = "rustsweeper"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"colorful",
|
||||||
"rand",
|
"rand",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -8,3 +8,4 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
|
colorful = "0.2.1"
|
||||||
|
118
src/lib.rs
118
src/lib.rs
@ -1,8 +1,14 @@
|
|||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
extern crate colorful;
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use colorful::Color;
|
||||||
|
use colorful::Colorful;
|
||||||
|
use colorful::HSL;
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
println!("Welcome to Rustsweeper!");
|
println!("{}", "Welcome to Rustsweeper!".color(Color::Yellow));
|
||||||
|
|
||||||
let mut width = 10;
|
let mut width = 10;
|
||||||
let mut height = 10;
|
let mut height = 10;
|
||||||
match prompt("\nChoose your size:\n1. 10 x 10\n2. 20 x 10\n3. 20 x 20\n4. 40 x 20\n> ", 1, 4) {
|
match prompt("\nChoose your size:\n1. 10 x 10\n2. 20 x 10\n3. 20 x 20\n4. 40 x 20\n> ", 1, 4) {
|
||||||
@ -24,6 +30,7 @@ pub fn run() {
|
|||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut difficulty = Difficulty::Easy;
|
let mut difficulty = Difficulty::Easy;
|
||||||
match prompt("\nChoose your difficulty:\n1. Easy - 10% bombs\n2. Medium - 20% bombs\n3. Hard - 40% bombs\n> ", 1, 3) {
|
match prompt("\nChoose your difficulty:\n1. Easy - 10% bombs\n2. Medium - 20% bombs\n3. Hard - 40% bombs\n> ", 1, 3) {
|
||||||
1 => {
|
1 => {
|
||||||
@ -42,7 +49,7 @@ pub fn run() {
|
|||||||
let mut game = Game::new(width, height, difficulty);
|
let mut game = Game::new(width, height, difficulty);
|
||||||
while game.running {
|
while game.running {
|
||||||
println!("{}", game.get_board());
|
println!("{}", game.get_board());
|
||||||
match prompt("\nWhat would you like to do?\n1. Uncover a tile\n2. Flag a tile\n> ", 1, 2) {
|
match prompt("\nWhat would you like to do?\n1. Uncover a tile\n2. Flag a tile\n3. Give up\n> ", 1, 3) {
|
||||||
1 => {
|
1 => {
|
||||||
let pos = prompt_coords(0, game.board.width - 1, 0, game.board.height - 1);
|
let pos = prompt_coords(0, game.board.width - 1, 0, game.board.height - 1);
|
||||||
println!("Uncovering ({}, {})", pos.x, pos.y);
|
println!("Uncovering ({}, {})", pos.x, pos.y);
|
||||||
@ -53,9 +60,14 @@ pub fn run() {
|
|||||||
println!("Flagging ({}, {})", pos.x, pos.y);
|
println!("Flagging ({}, {})", pos.x, pos.y);
|
||||||
game.flag(pos.x as usize, pos.y as usize);
|
game.flag(pos.x as usize, pos.y as usize);
|
||||||
},
|
},
|
||||||
|
3 => {
|
||||||
|
game.end();
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
game.check_win();
|
||||||
}
|
}
|
||||||
|
println!("\nThanks for playing!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -72,7 +84,7 @@ pub enum Difficulty {
|
|||||||
Hard,
|
Hard,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub struct Coord {
|
pub struct Coord {
|
||||||
pub x: isize,
|
pub x: isize,
|
||||||
pub y: isize,
|
pub y: isize,
|
||||||
@ -125,7 +137,8 @@ pub struct Game {
|
|||||||
pub board: Board,
|
pub board: Board,
|
||||||
pub difficulty: Difficulty,
|
pub difficulty: Difficulty,
|
||||||
pub uncovered: Vec<Vec<bool>>,
|
pub uncovered: Vec<Vec<bool>>,
|
||||||
pub flags: Vec<(usize, usize)>
|
pub flags: Vec<Coord>,
|
||||||
|
pub num_bombs: usize,
|
||||||
}
|
}
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn new(width: usize, height: usize, difficulty: Difficulty) -> Game {
|
pub fn new(width: usize, height: usize, difficulty: Difficulty) -> Game {
|
||||||
@ -154,7 +167,8 @@ impl Game {
|
|||||||
board,
|
board,
|
||||||
difficulty,
|
difficulty,
|
||||||
uncovered,
|
uncovered,
|
||||||
flags: Vec::new()
|
flags: Vec::new(),
|
||||||
|
num_bombs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_valid_neighbors(&self, x: usize, y: usize) -> Vec<Coord> {
|
pub fn get_valid_neighbors(&self, x: usize, y: usize) -> Vec<Coord> {
|
||||||
@ -208,10 +222,9 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.board.get(x, y) == &Cell::Bomb {
|
if self.board.get(x, y) == &Cell::Bomb {
|
||||||
println!("Uncovered a bomb!");
|
self.lose();
|
||||||
self.uncover_all();
|
// println!("{}", "You uncovered a bomb!".color(Color::LightRed));
|
||||||
println!("{}", self.get_board());
|
// self.end();
|
||||||
self.running = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,10 +238,11 @@ impl Game {
|
|||||||
uncovered.push(row);
|
uncovered.push(row);
|
||||||
}
|
}
|
||||||
self.uncovered = uncovered;
|
self.uncovered = uncovered;
|
||||||
|
self.running = false;
|
||||||
}
|
}
|
||||||
pub fn check_flagged(&self, x: usize, y: usize) -> bool {
|
pub fn check_flagged(&self, x: usize, y: usize) -> bool {
|
||||||
for flag in &self.flags {
|
for flag in &self.flags {
|
||||||
if *flag == (x, y) {
|
if flag == &Coord::new(x as isize, y as isize) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,10 +250,10 @@ impl Game {
|
|||||||
}
|
}
|
||||||
pub fn flag(&mut self, x: usize, y: usize) {
|
pub fn flag(&mut self, x: usize, y: usize) {
|
||||||
if !self.check_flagged(x, y) {
|
if !self.check_flagged(x, y) {
|
||||||
self.flags.push((x, y));
|
self.flags.push(Coord::new(x as isize, y as isize));
|
||||||
} else {
|
} else {
|
||||||
for i in 0..self.flags.len() {
|
for i in 0..self.flags.len() {
|
||||||
if self.flags[i] == (x, y) {
|
if self.flags[i] == Coord::new(x as isize, y as isize) {
|
||||||
self.flags.remove(i);
|
self.flags.remove(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -277,15 +291,29 @@ impl Game {
|
|||||||
out.push_str(&temp);
|
out.push_str(&temp);
|
||||||
for x in 0..self.board.width {
|
for x in 0..self.board.width {
|
||||||
if self.check_uncovered(x, y) {
|
if self.check_uncovered(x, y) {
|
||||||
let bomb_count = self.get_bomb_count(x, y);
|
let count = self.get_bomb_count(x, y);
|
||||||
let count = &format!("{}", bomb_count);
|
|
||||||
out.push_str(match self.board.get(x, y) {
|
match self.board.get(x, y) {// ▓▒░
|
||||||
Cell::Empty => if bomb_count == 0 { "." } else { count },
|
Cell::Empty => {
|
||||||
Cell::Bomb => "@",
|
out = format!("{}{}", out, match count {
|
||||||
});
|
1 => "1".color(Color::Blue),
|
||||||
|
2 => "2".color(Color::Green),
|
||||||
|
3 => "3".color(Color::Red),
|
||||||
|
4 => "4".color(Color::DarkBlue),
|
||||||
|
5 => "5".color(Color::DarkRed1),
|
||||||
|
6 => "6".color(Color::LightBlue),
|
||||||
|
7 => "7".color(Color::Black),
|
||||||
|
8 => "8".color(Color::White),
|
||||||
|
_ => ".".color(Color::White),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Cell::Bomb => {
|
||||||
|
out = format!("{}{}", out, "@".color(Color::Red));
|
||||||
|
},
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
if self.check_flagged(x, y) {
|
if self.check_flagged(x, y) {
|
||||||
out.push_str("F");
|
out = format!("{}{}", out, "F".color(Color::Yellow));
|
||||||
} else {
|
} else {
|
||||||
out.push_str("_");
|
out.push_str("_");
|
||||||
}
|
}
|
||||||
@ -297,6 +325,43 @@ impl Game {
|
|||||||
out.pop(); // Remove trailing newline.
|
out.pop(); // Remove trailing newline.
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
pub fn end(&mut self) {
|
||||||
|
self.uncover_all();
|
||||||
|
println!("{}", self.get_board());
|
||||||
|
}
|
||||||
|
pub fn check_win(&mut self) {
|
||||||
|
if self.flags.len() == self.num_bombs {
|
||||||
|
let mut all_bombs = true;
|
||||||
|
for flag in &self.flags {
|
||||||
|
if self.board.get(flag.x as usize, flag.y as usize) != &Cell::Bomb {
|
||||||
|
all_bombs = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if all_bombs {
|
||||||
|
self.win();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn win(&mut self) {
|
||||||
|
print!("\n");
|
||||||
|
println!("{}", "__ __ _ __ __".gradient_with_color(HSL::new(0.0, 1.0, 0.5), HSL::new(0.833, 1.0, 0.5)));
|
||||||
|
println!("{}", "\\ \\/ /___ __ __ | | / /___ ____ / /".gradient_with_color(HSL::new(0.0, 1.0, 0.5), HSL::new(0.833, 1.0, 0.5)));
|
||||||
|
println!("{}", " \\ / __ \\/ / / / | | /| / / __ \\/ __ \\/ / ".gradient_with_color(HSL::new(0.0, 1.0, 0.5), HSL::new(0.833, 1.0, 0.5)));
|
||||||
|
println!("{}", " / / /_/ / /_/ / | |/ |/ / /_/ / / / /_/ ".gradient_with_color(HSL::new(0.0, 1.0, 0.5), HSL::new(0.833, 1.0, 0.5)));
|
||||||
|
println!("{}", "/_/\\____/\\__,_/ |__/|__/\\____/_/ /_(_) ".gradient_with_color(HSL::new(0.0, 1.0, 0.5), HSL::new(0.833, 1.0, 0.5)));
|
||||||
|
print!("\n");
|
||||||
|
self.end();
|
||||||
|
}
|
||||||
|
pub fn lose(&mut self) {
|
||||||
|
print!("\n");
|
||||||
|
println!("{}", "__ __ __ __" .color(Color::LightRed));
|
||||||
|
println!("{}", "\\ \\/ /___ __ __ / / ____ ________ / /" .color(Color::LightRed));
|
||||||
|
println!("{}", " \\ / __ \\/ / / / / / / __ \\/ ___/ _ \\/ / ".color(Color::LightRed));
|
||||||
|
println!("{}", " / / /_/ / /_/ / / /___/ /_/ (__ ) __/_/ " .color(Color::LightRed));
|
||||||
|
println!("{}", "/_/\\____/\\__,_/ /_____/\\____/____/\\___(_) ".color(Color::LightRed));
|
||||||
|
print!("\n");
|
||||||
|
self.end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn difficulty_lookup(width: usize, height: usize, difficulty: Difficulty) -> usize {
|
pub fn difficulty_lookup(width: usize, height: usize, difficulty: Difficulty) -> usize {
|
||||||
@ -313,17 +378,10 @@ pub fn random(max: usize) -> usize {
|
|||||||
((max as f64) * rand_amt) as usize
|
((max as f64) * rand_amt) as usize
|
||||||
}
|
}
|
||||||
pub fn read_num() -> isize {
|
pub fn read_num() -> isize {
|
||||||
std::io::stdout().flush().unwrap();
|
loop {
|
||||||
let mut input = String::new();
|
let num = read();
|
||||||
match std::io::stdin().read_line(&mut input) {
|
if str_len(&num) != 0 {
|
||||||
Ok(_bytes_read) => {
|
return num.parse::<isize>().expect("input was not isize");
|
||||||
input.pop(); // Remove trailing newline
|
|
||||||
std::io::stdout().flush().unwrap();
|
|
||||||
return input.parse::<isize>().expect("input was not isize");
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
eprintln!("Error reading input: {}", err);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user