base64 encode id
This commit is contained in:
+2
-2
@@ -29,7 +29,7 @@ fn main() {
|
||||
let board = if let Some(board_string) = args.solve_board {
|
||||
Board::from_string(board_string)
|
||||
} else if let Some(board_id) = args.solve {
|
||||
Board::from_id(board_id)
|
||||
Board::from_id(&board_id)
|
||||
} else {
|
||||
println!("Use --help to see available options");
|
||||
return;
|
||||
@@ -106,7 +106,7 @@ struct Args {
|
||||
|
||||
#[argh(option, short = 's')]
|
||||
/// the id of the board to solve
|
||||
solve: Option<u128>,
|
||||
solve: Option<String>,
|
||||
|
||||
#[argh(option)]
|
||||
/// the board to solve in board representation
|
||||
|
||||
+21
-8
@@ -17,6 +17,8 @@ use errors::SError;
|
||||
use piece::Piece;
|
||||
use square::{Square, SquarePair};
|
||||
|
||||
use crate::util;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Board {
|
||||
pub cells: [[Option<Piece>; BOARD_SIZE]; BOARD_SIZE],
|
||||
@@ -43,12 +45,20 @@ impl Board {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_id(board_id: u128) -> Result<Self, SError> {
|
||||
pub fn from_id(board_id: &str) -> Result<Self, SError> {
|
||||
let mut board_id_bytes = [0; 8];
|
||||
board_id_bytes.copy_from_slice(board_id.as_bytes());
|
||||
let mut working_bytes_slice = [0; 6];
|
||||
util::b64_decode_48(&board_id_bytes, &mut working_bytes_slice);
|
||||
|
||||
let mut working_bytes = [0; 8];
|
||||
working_bytes[2..].copy_from_slice(&working_bytes_slice);
|
||||
let mut working = u64::from_be_bytes(working_bytes);
|
||||
|
||||
let mut board = Board::new();
|
||||
let mut working = board_id;
|
||||
let mask = 0b111;
|
||||
for i in (0..BOARD_SIZE).rev() {
|
||||
for j in (0..BOARD_SIZE).rev() {
|
||||
let mask = 0b111;
|
||||
let piece = Board::get_piece_from_encoding((working & mask) as u8);
|
||||
working = working >> 3;
|
||||
let piece = piece?;
|
||||
@@ -136,21 +146,24 @@ impl Board {
|
||||
|
||||
pub fn pretty_print(&self) {
|
||||
println!("{}", self.print(true));
|
||||
// println!("{:^40}\n", format!("id: {:#018x}", self.id()));
|
||||
println!("{:^40}\n", format!("id: {}", self.id()));
|
||||
}
|
||||
|
||||
pub fn id(&self) -> u128 {
|
||||
let mut res: u128 = 0;
|
||||
pub fn id(&self) -> String {
|
||||
let mut res: u64 = 0;
|
||||
|
||||
for i in 0..BOARD_SIZE {
|
||||
for j in 0..BOARD_SIZE {
|
||||
res = res << 3;
|
||||
let byte = Board::get_piece_encoding(self.cells[i][j]);
|
||||
res = res | byte as u128
|
||||
res = res | byte as u64
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
let mut id_bytes = [0; 6];
|
||||
id_bytes.copy_from_slice(&res.to_be_bytes()[2..]);
|
||||
util::b64_encode_48(&id_bytes)
|
||||
}
|
||||
|
||||
fn print(&self, pretty: bool) -> String {
|
||||
@@ -585,7 +598,7 @@ mod tests {
|
||||
board.set(sq!("Nc4"));
|
||||
|
||||
let id = board.id();
|
||||
let board2 = Board::from_id(id);
|
||||
let board2 = Board::from_id(&id);
|
||||
let board2 = board2.unwrap();
|
||||
|
||||
validate_board!(board2, "..NB", "....", "RQ.K", "P...");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod board;
|
||||
pub mod generator;
|
||||
pub mod solver;
|
||||
pub mod util;
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
pub(crate) fn b64_encode_48(input: &[u8; 6]) -> String {
|
||||
let mut output = [0 as char; 8];
|
||||
for (byte_chunk, output_slice) in input.chunks_exact(3).zip(output.chunks_exact_mut(4)) {
|
||||
let byte1 = byte_chunk[0];
|
||||
let byte2 = byte_chunk[1];
|
||||
let byte3 = byte_chunk[2];
|
||||
|
||||
output_slice[0] = lookup((byte1 & 0b1111_1100) >> 2);
|
||||
output_slice[1] = lookup((byte1 & 0b0000_0011) << 4 | (byte2 & 0b1111_0000) >> 4);
|
||||
output_slice[2] = lookup((byte2 & 0b0000_1111) << 2 | (byte3 & 0b1100_0000) >> 6);
|
||||
output_slice[3] = lookup(byte3 & 0b0011_1111);
|
||||
}
|
||||
|
||||
output.iter().collect()
|
||||
}
|
||||
|
||||
pub(crate) fn b64_decode_48(input: &[u8; 8], output: &mut [u8; 6]) {
|
||||
for (char_chunk, output_slice) in input.chunks_exact(4).zip(output.chunks_exact_mut(3)) {
|
||||
let char_1 = reverse_lookup(char_chunk[0] as char);
|
||||
let char_2 = reverse_lookup(char_chunk[1] as char);
|
||||
let char_3 = reverse_lookup(char_chunk[2] as char);
|
||||
let char_4 = reverse_lookup(char_chunk[3] as char);
|
||||
|
||||
output_slice[0] = (char_1 << 2) | (char_2 >> 4);
|
||||
output_slice[1] = (char_2 << 4) | (char_3 >> 2);
|
||||
output_slice[2] = (char_3 << 6) | char_4;
|
||||
}
|
||||
}
|
||||
|
||||
const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
||||
|
||||
fn lookup(idx: u8) -> char {
|
||||
ALPHABET
|
||||
.chars()
|
||||
.nth(idx as usize)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn reverse_lookup(c: char) -> u8 {
|
||||
ALPHABET
|
||||
.chars()
|
||||
.position(|x| x == c)
|
||||
.unwrap() as u8
|
||||
}
|
||||
Reference in New Issue
Block a user