mirror of https://github.com/dnomd343/klotski.git
7 changed files with 345 additions and 18 deletions
@ -0,0 +1,153 @@ |
|||
use crate::ffi; |
|||
use crate::ShortCode; |
|||
|
|||
/// Layout represents a valid klotski situation, which fills single `2x2` block
|
|||
/// and any number of `1x1` / `1x2` / `2x1` blocks without overlapping within
|
|||
/// the range of `5x4`, and ensures that at least two spaces need to remain.
|
|||
/// These layout information will be stored in a 36-bit value (u64), which can
|
|||
/// uniquely mark a valid klotski situation, and any valid situation can also
|
|||
/// be represented by a unique value.
|
|||
#[derive(Debug)] |
|||
pub struct Layout { |
|||
value: u64 |
|||
} |
|||
|
|||
impl Layout { |
|||
/// Check whether the klotski layout value is a valid.
|
|||
pub fn check(val: u64) -> bool { |
|||
ffi::layout_check(val) |
|||
} |
|||
|
|||
/// Create klotski layout without any check. Note that if an invalid value
|
|||
/// is passed, unpredictable behavior may occur.
|
|||
pub fn unsafe_new(val: u64) -> Self { |
|||
Self { value: val } |
|||
} |
|||
|
|||
/// Create klotski layout with validity check.
|
|||
pub fn new(val: u64) -> Option<Self> { |
|||
if !Self::check(val) { |
|||
return None |
|||
} |
|||
Some(Self::unsafe_new(val)) |
|||
} |
|||
|
|||
/// Create klotski layout from string form.
|
|||
pub fn from_str(msg: &str) -> Option<Self> { |
|||
let val = ffi::layout_from_str(msg); |
|||
if val == 0x10_FFFF_FFFF { |
|||
return None; |
|||
} |
|||
Some(Self::unsafe_new(val)) |
|||
} |
|||
} |
|||
|
|||
impl Layout { |
|||
/// Get the original value of klotski layout.
|
|||
pub fn unwrap(&self) -> u64 { |
|||
self.value |
|||
} |
|||
|
|||
pub fn to_string(&self) -> String { |
|||
ffi::layout_to_str(self.value) |
|||
} |
|||
|
|||
pub fn to_shorten_string(&self) -> String { |
|||
ffi::layout_to_shorten_str(self.value) |
|||
} |
|||
|
|||
pub fn to_short_code(&self) -> ShortCode { |
|||
ShortCode::unsafe_new(ffi::layout_to_short_code(self.value)) |
|||
} |
|||
} |
|||
|
|||
impl Into<u64> for Layout { |
|||
fn into(self) -> u64 { |
|||
self.unwrap() |
|||
} |
|||
} |
|||
|
|||
impl Into<String> for Layout { |
|||
fn into(self) -> String { |
|||
self.to_string() |
|||
} |
|||
} |
|||
|
|||
impl Into<ShortCode> for Layout { |
|||
fn into(self) -> ShortCode { |
|||
self.to_short_code() |
|||
} |
|||
} |
|||
|
|||
impl Layout { |
|||
pub fn is_horizontal_mirror(&self) -> bool { |
|||
ffi::layout_is_horizontal_mirror(self.value) |
|||
} |
|||
|
|||
pub fn is_vertical_mirror(&self) -> bool { |
|||
ffi::layout_is_vertical_mirror(self.value) |
|||
} |
|||
|
|||
pub fn to_vertical_mirror(&self) -> Layout { |
|||
let val = ffi::layout_to_vertical_mirror(self.value); |
|||
Layout::unsafe_new(val) |
|||
} |
|||
|
|||
pub fn to_horizontal_mirror(&self) -> Layout { |
|||
let val = ffi::layout_to_horizontal_mirror(self.value); |
|||
Layout::unsafe_new(val) |
|||
} |
|||
} |
|||
|
|||
impl Layout { |
|||
pub fn n_1x1(&self) -> u8 { |
|||
ffi::layout_n_1x1(self.value) |
|||
} |
|||
|
|||
pub fn n_1x2(&self) -> u8 { |
|||
ffi::layout_n_1x2(self.value) |
|||
} |
|||
|
|||
pub fn n_2x1(&self) -> u8 { |
|||
ffi::layout_n_2x1(self.value) |
|||
} |
|||
|
|||
pub fn n_2x2(&self) -> u8 { |
|||
1 |
|||
} |
|||
} |
|||
|
|||
impl Layout { |
|||
pub fn type_id(&self) -> u8 { |
|||
ffi::layout_type_id(self.value) |
|||
} |
|||
|
|||
pub fn pattern_id(&self) -> u16 { |
|||
ffi::layout_pattern_id(self.value) |
|||
} |
|||
|
|||
pub fn toward_char(&self) -> u8 { |
|||
ffi::layout_toward_char(self.value) |
|||
} |
|||
|
|||
pub fn case_id(&self) -> u32 { |
|||
ffi::layout_case_id(self.value) |
|||
} |
|||
} |
|||
|
|||
impl Layout { |
|||
pub fn next_cases(&self) -> Vec<Layout> { |
|||
ffi::layout_next_cases(self.value) |
|||
.iter() |
|||
.map(|val| Layout::unsafe_new(*val)) |
|||
.collect() |
|||
} |
|||
} |
|||
|
|||
impl PartialEq for Layout { |
|||
fn eq(&self, other: &Self) -> bool { |
|||
self.value == other.value |
|||
} |
|||
} |
|||
|
|||
// TODO: add `Display` trait support
|
@ -1,4 +1,11 @@ |
|||
mod bridge; |
|||
mod layout; |
|||
mod short_code; |
|||
|
|||
pub use bridge::Layout; |
|||
pub use bridge::ShortCode; |
|||
// pub use bridge::Layout;
|
|||
// pub use bridge::ShortCode;
|
|||
|
|||
use bridge::ffi; |
|||
|
|||
pub use layout::Layout; |
|||
pub use short_code::ShortCode; |
|||
|
@ -0,0 +1,23 @@ |
|||
use crate::ffi; |
|||
|
|||
#[derive(Debug)] |
|||
pub struct ShortCode { |
|||
code: u32 |
|||
} |
|||
|
|||
impl ShortCode { |
|||
// fn new(code: u32) -> Option<ShortCode> {
|
|||
// if !Self::check(code) {
|
|||
// return None
|
|||
// }
|
|||
// Some(Self::unsafe_new(code))
|
|||
// }
|
|||
|
|||
pub fn unsafe_new(code: u32) -> ShortCode { |
|||
Self {code} |
|||
} |
|||
|
|||
fn check(code: u32) -> bool { |
|||
ffi::short_code_check(code) |
|||
} |
|||
} |
Loading…
Reference in new issue