Skip to content

Instantly share code, notes, and snippets.

@divi255
Last active October 12, 2021 05:21
Show Gist options
  • Save divi255/e734704e137d02b2ee0ebe92e5f52774 to your computer and use it in GitHub Desktop.
Save divi255/e734704e137d02b2ee0ebe92e5f52774 to your computer and use it in GitHub Desktop.
Mine field generator for Minesweeper game
use rand::{thread_rng, Rng};
use std::fmt;
struct MineField {
field: Vec<u16>,
x: usize,
y: usize,
}
impl MineField {
fn generate(x: usize, y: usize, mines: usize) -> Option<Self> {
let mut rng = thread_rng();
let mine_field_square = x * y;
let mut cap = mine_field_square / 16;
if mine_field_square % 16 > 0 {
cap += 1;
}
let mut field: Vec<u16> = vec![0; cap];
let mut coords: Vec<usize> = (0..mine_field_square).collect();
for _ in 0..mines {
if coords.is_empty() {
return None;
}
let coord = coords.remove(rng.gen_range(0..coords.len()));
field[coord / 16] |= 1 << (coord % 16);
}
Some(Self { field, x, y })
}
}
impl fmt::Display for MineField {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut result = String::new();
for y in 0..self.y {
for x in 0..self.x {
let coord = x + y * self.x;
result += if self.field[coord / 16] & 1 << (coord % 16) > 0 {
"X"
} else {
"0"
}
}
result += "\n";
}
write!(f, "{}", result)
}
}
fn main() {
let x = 5;
let y = 5;
let mines = 5;
let mine_field = MineField::generate(x, y, mines).unwrap();
println!("{}", mine_field);
}
mod test {
#[test]
fn test_minefield() {
use super::MineField;
fn calculate_mines(mine_field: &MineField) -> usize {
let mut count = 0;
for f in mine_field.field.iter() {
for bit in 0..16 {
if f & 1 << bit > 0 {
count += 1;
}
}
}
count
}
for x in 10..100 {
for y in 10..100 {
for mines in 10..20 {
let mine_field = MineField::generate(x, y, mines).unwrap();
assert_eq!(calculate_mines(&mine_field), mines);
assert_eq!(mine_field.to_string().matches('X').count(), mines);
assert_eq!(mine_field.to_string().matches('0').count(), x * y - mines);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment