use rand::random; use std::str::FromStr; use crate::cubie::CubieCube; use crate::facelet::FaceCube; use crate::{error::Error, Move}; pub fn scramble_from_str(s: &str) -> Result, Error> { s.split_whitespace() .map(|word| Move::from_str(word.trim())) .collect() } pub fn scramble_to_str(s: &Vec) -> Result { let result: String = s .iter() .map(|m| Move::to_string(m)) .fold("".to_string(), |acc, x| format!("{} {}", acc, x)); Ok(result.trim_start().to_string()) } pub fn gen_scramble(length: usize) -> Result, Error> { let mut cc = CubieCube::default(); cc.randomize(); let fc = FaceCube::try_from(&cc)?; let mut ss = "".to_string(); let mut ps = ' '; for s in fc.to_string().chars() { if s != ps { if ps == ' ' { ps = s; continue; } let suffix = match random::() % 3 { 0 => "", 1 => "2", _ => "'", }; ss = ss + ps.to_string().as_str() + suffix.to_string().as_str() + " "; } ps = s; } let mut scramble = scramble_from_str(&ss)?; scramble.truncate(length); Ok(scramble) } #[cfg(test)] mod test { use super::*; use crate::moves::Move::*; #[test] fn test_scramble_from_str() { let m = vec![R, U, R3, U3, F, L3, D3, B2, R3, U3]; assert_eq!(scramble_from_str("R U R' U' F L' D' B2 R' U'").unwrap(), m); } #[test] fn test_scramble_to_str() { let m = vec![R, U, R3, U3, F, L3, D3, B2, R3, U3]; assert_eq!(scramble_to_str(&m).unwrap(), "R U R' U' F L' D' B2 R' U'"); } #[test] fn test_gen_scramble() { let ss = gen_scramble(25).unwrap(); assert_eq!(ss.len(), 25); } } pub fn generate(length: usize) -> Result, Error> { gen_scramble(length) } pub fn generate_string(length: usize) -> Result { Ok(crate::notation::format_moves(&generate(length)?)) }