initial commit
This commit is contained in:
commit
7b597748bb
|
@ -0,0 +1 @@
|
|||
target
|
|
@ -0,0 +1,11 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "sycamore"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "sycamore-harness"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,5 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"sycamore",
|
||||
"sycamore-harness"
|
||||
]
|
|
@ -0,0 +1,3 @@
|
|||
# Sycamore: Speedrunning Minesweeper
|
||||
|
||||
Sycamore is a Rust minesweeper bot, intenting to solve any board permutation as quickly as possible.
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "sycamore-harness"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "sycamore-harness"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "sycamore"
|
||||
version = "0.1.0"
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "sycamore"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Board representation
|
||||
|
||||
Sycamore uses a bytefield representation of the board, enabling arbitrary sized boards to be indexed extremely quickly.
|
||||
|
||||
There are 10 states a square can be in:
|
||||
- 0000 empty
|
||||
- 0001 revealed, 1
|
||||
- 0010 revealed, 2
|
||||
- 0011 revealed, 3
|
||||
- 0100 revealed, 4
|
||||
- 0101 revealed, 5
|
||||
- 0110 revealed, 6
|
||||
- 0111 revealed, 7
|
||||
- 1000 revealed, 8
|
||||
- 1001 flagged
|
||||
- 1010 hidden
|
||||
These numbers have been picked to allow easily performing calculations when solving - 0-8 adjacent mines per square can be represented by immediately doing arithmetic with this value.
|
||||
|
||||
To represent this, at minimum 4 bits are needed, however for fast and easy access, an entire byte is used.
|
||||
|
||||
This allows us to represent the entire board with a simple WIDTH*HEIGHT-length array, and easily access
|
||||
the value of a specific coordinate with bytefield[WIDTH * row + col].
|
||||
|
||||
*/
|
||||
|
||||
pub const SQUARESTATE_EMPTY: u8 = 0;
|
||||
pub const SQUARESTATE_FLAGGED: u8 = 9;
|
||||
pub const SQUARESTATE_HIDDEN: u8 = 10;
|
||||
pub const SQUARESTATE_MAX_VAL: u8 = SQUARESTATE_HIDDEN;
|
||||
|
||||
pub struct Board {
|
||||
field: Vec<u8>,
|
||||
width: usize,
|
||||
height: usize
|
||||
}
|
||||
|
||||
impl Board {
|
||||
pub fn new(width: usize, height: usize, pre_allocate: bool) -> Self {
|
||||
let mut vec = if pre_allocate {
|
||||
Vec::with_capacity(width * height)
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
for i in 0..width * height {
|
||||
vec.insert(i, SQUARESTATE_HIDDEN);
|
||||
}
|
||||
Self {
|
||||
field: vec,
|
||||
width,
|
||||
height
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, row: usize, col: usize) -> &u8 {
|
||||
if col > self.width { panic!("board access out of bounds (width is {} but col is {})", self.width, col); }
|
||||
if row > self.height { panic!("board access out of bounds (height is {} but row is {})", self.height, row); }
|
||||
|
||||
&self.field[row * self.width + col]
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, row: usize, col: usize) -> &mut u8 {
|
||||
if col > self.width { panic!("board access out of bounds (width is {} but col is {})", self.width, col); }
|
||||
if row > self.height { panic!("board access out of bounds (height is {} but row is {})", self.height, row); }
|
||||
|
||||
&mut self.field[row * self.width + col]
|
||||
}
|
||||
|
||||
pub fn set(&mut self, row: usize, col: usize, to: u8) {
|
||||
if col > self.width { panic!("board access out of bounds (width is {} but col is {})", self.width, col); }
|
||||
if row > self.height { panic!("board access out of bounds (height is {} but row is {})", self.height, row); }
|
||||
if to > SQUARESTATE_MAX_VAL { panic!("board set to invalid state (max allowed state is {} but 'to' is {})", SQUARESTATE_MAX_VAL, to); }
|
||||
|
||||
self.field[row * self.width + col] = to;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod board;
|
Loading…
Reference in New Issue