initial commit

This commit is contained in:
core 2023-06-27 22:42:48 -04:00
commit 7b597748bb
Signed by: core
GPG Key ID: FDBF740DADDCEECF
11 changed files with 130 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target

11
Cargo.lock generated Normal file
View File

@ -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"

5
Cargo.toml Normal file
View File

@ -0,0 +1,5 @@
[workspace]
members = [
"sycamore",
"sycamore-harness"
]

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Sycamore: Speedrunning Minesweeper
Sycamore is a Rust minesweeper bot, intenting to solve any board permutation as quickly as possible.

7
sycamore-harness/Cargo.lock generated Normal file
View File

@ -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"

View File

@ -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]

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

7
sycamore/Cargo.lock generated Normal file
View File

@ -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"

8
sycamore/Cargo.toml Normal file
View File

@ -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]

76
sycamore/src/board.rs Normal file
View File

@ -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;
}
}

1
sycamore/src/lib.rs Normal file
View File

@ -0,0 +1 @@
pub mod board;