othello_agent/gameplay/
encoding.rs1use std::collections::HashMap;
2
3use crate::gameplay::types::IBoard;
4
5use crate::gameplay::constants::INITIAL_BOARD;
6
7pub fn string_from_board(board: IBoard, code_chars: &str) -> String {
20 let board: Vec<u8> = board
22 .iter()
23 .flatten()
24 .map(|&i| i)
25 .collect();
26 let joined_board =
28 board
29 .iter()
30 .map(|&i| i.to_string())
31 .collect::<String>() + "22";
32 let mut chunks = Vec::new();
33 let mut i = 0;
34 while i < joined_board.len() {
36 let end = std::cmp::min(i + 3, joined_board.len());
37 chunks.push(&joined_board[i..end]);
38 i += 3;
39 }
40 chunks
42 .iter()
43 .map(|x| {
44 let index = u8::from_str_radix(x, 3).unwrap() as usize;
45 code_chars.chars().nth(index).unwrap()
46 })
47 .collect()
48}
49
50pub fn board_from_string(s: &str, code_char_hash: &HashMap<char, u8>) -> IBoard {
62 let mut board: Vec<u8> = s
63 .chars()
64 .flat_map(|x| {
65 let sum = 27 + *code_char_hash.get(&x).unwrap();
66 let mut base_3_string = format_radix(sum as u32, 3);
67 base_3_string.retain(|c| !c.is_whitespace());
69 base_3_string = base_3_string[base_3_string.len() - 3..].to_string();
71 base_3_string
72 .chars()
73 .map(|c| c.to_digit(10).unwrap() as u8)
74 .collect::<Vec<_>>()
75 })
76 .collect();
77 board.truncate(64);
78 let mut board_formatted: IBoard = INITIAL_BOARD;
80 for (i, &x) in board.iter().enumerate() {
81 board_formatted[i / 8][i % 8] = x;
82 }
83 board_formatted
84}
85
86pub fn create_code_char_hash(code_chars: &str) -> HashMap<char, u8> {
87 let mut code_char_hash = HashMap::new();
88 for (i, c) in code_chars.chars().enumerate() {
89 code_char_hash.insert(c, i as u8);
90 }
91 code_char_hash
92}
93
94fn format_radix(mut x: u32, radix: u32) -> String {
95 let mut result = vec![];
96
97 loop {
98 let m = x % radix;
99 x = x / radix;
100
101 result.push(std::char::from_digit(m, radix).unwrap());
103 if x == 0 {
104 break;
105 }
106 }
107 result.into_iter().rev().collect()
108}
109
110#[cfg(test)]
111mod tests {
112 use crate::gameplay::{
113 constants::{ INITIAL_BOARD, CODE_CHARS },
114 encoding::{ create_code_char_hash, board_from_string },
115 };
116
117 use super::string_from_board;
118
119 #[test]
120 fn it_works() {
121 let board_str = string_from_board(INITIAL_BOARD, CODE_CHARS);
122 assert_eq!(board_str, "---------h-yq---------")
123 }
124 #[test]
125 fn can_encode_and_decode() {
126 let board_str = string_from_board(INITIAL_BOARD, CODE_CHARS);
127 let hashmap_chars = create_code_char_hash(CODE_CHARS);
128 let board_decoded = board_from_string(&board_str, &hashmap_chars);
129 assert_eq!(INITIAL_BOARD, board_decoded);
130 }
131}