use std::collections::HashMap;
use crate::gameplay::types::IBoard;
use crate::gameplay::constants::INITIAL_BOARD;
pub fn string_from_board(board: IBoard, code_chars: &str) -> String {
let board: Vec<u8> = board
.iter()
.flatten()
.map(|&i| i)
.collect();
let joined_board =
board
.iter()
.map(|&i| i.to_string())
.collect::<String>() + "22";
let mut chunks = Vec::new();
let mut i = 0;
while i < joined_board.len() {
let end = std::cmp::min(i + 3, joined_board.len());
chunks.push(&joined_board[i..end]);
i += 3;
}
chunks
.iter()
.map(|x| {
let index = u8::from_str_radix(x, 3).unwrap() as usize;
code_chars.chars().nth(index).unwrap()
})
.collect()
}
pub fn board_from_string(s: &str, code_char_hash: &HashMap<char, u8>) -> IBoard {
let mut board: Vec<u8> = s
.chars()
.flat_map(|x| {
let sum = 27 + *code_char_hash.get(&x).unwrap();
let mut base_3_string = format_radix(sum as u32, 3);
base_3_string.retain(|c| !c.is_whitespace());
base_3_string = base_3_string[base_3_string.len() - 3..].to_string();
base_3_string
.chars()
.map(|c| c.to_digit(10).unwrap() as u8)
.collect::<Vec<_>>()
})
.collect();
board.truncate(64);
let mut board_formatted: IBoard = INITIAL_BOARD;
for (i, &x) in board.iter().enumerate() {
board_formatted[i / 8][i % 8] = x;
}
board_formatted
}
pub fn create_code_char_hash(code_chars: &str) -> HashMap<char, u8> {
let mut code_char_hash = HashMap::new();
for (i, c) in code_chars.chars().enumerate() {
code_char_hash.insert(c, i as u8);
}
code_char_hash
}
fn format_radix(mut x: u32, radix: u32) -> String {
let mut result = vec![];
loop {
let m = x % radix;
x = x / radix;
result.push(std::char::from_digit(m, radix).unwrap());
if x == 0 {
break;
}
}
result.into_iter().rev().collect()
}
#[cfg(test)]
mod tests {
use crate::gameplay::{
constants::{ INITIAL_BOARD, CODE_CHARS },
encoding::{ create_code_char_hash, board_from_string },
};
use super::string_from_board;
#[test]
fn it_works() {
let board_str = string_from_board(INITIAL_BOARD, CODE_CHARS);
assert_eq!(board_str, "---------h-yq---------")
}
#[test]
fn can_encode_and_decode() {
let board_str = string_from_board(INITIAL_BOARD, CODE_CHARS);
let hashmap_chars = create_code_char_hash(CODE_CHARS);
let board_decoded = board_from_string(&board_str, &hashmap_chars);
assert_eq!(INITIAL_BOARD, board_decoded);
}
}