diff --git a/src/azul.rs b/src/azul.rs index 18914ab..9d4ad56 100644 --- a/src/azul.rs +++ b/src/azul.rs @@ -11,14 +11,102 @@ pub enum Tile { Teal } +impl IntoIterator for Tile { + type Item = Tile; + type IntoIter = TileIter; + + fn into_iter(self) -> Self::IntoIter { + TileIter { + current: self + } + } +} + +pub struct TileIter { + current: Tile +} +impl Iterator for TileIter { + type Item = Tile; + + fn next(&mut self) -> Option{ + match self.current { + Tile::Blue => { + let next = Tile::Yellow; + self.current = next; + Some(next) + }, + Tile::Yellow => { + let next = Tile::Red; + self.current = next; + Some(next) + }, + Tile::Red => { + let next = Tile::Black; + self.current = next; + Some(next) + }, + Tile::Black => { + let next = Tile::Teal; + self.current = next; + Some(next) + }, + _ => None + } + } +} + + // factory, color, pattern line -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct GameMove (pub usize, pub Tile, pub usize); impl Default for GameMove { fn default() -> Self { GameMove(0, Tile::Blue, 1) } } +impl IntoIterator for GameMove { + type Item = GameMove; + type IntoIter = GameMoveIter; + + fn into_iter(self) -> Self::IntoIter { + GameMoveIter { + current: self + } + } +} + +pub struct GameMoveIter { + current: GameMove +} + +impl Iterator for GameMoveIter { + type Item = GameMove; + + fn next(&mut self) -> Option { + let factory = self.current.0; + let tile = self.current.1; + let pattern = self.current.2; + + if factory == 9 && tile == Tile::Teal && pattern == 0 { + return None + } + else if factory == 9 && tile == Tile::Teal { + let next = GameMove(0, Tile::Blue, (pattern + 1) % 6); + self.current = next; + return Some(next) + } + else if factory == 9 { + let next = GameMove(0, tile.into_iter().next().unwrap(), pattern); + self.current = next; + return Some(next) + } + else { + let next = GameMove(factory + 1, tile, pattern); + self.current = next; + return Some(next) + } + } +} #[derive(Debug, Clone)] struct Bag (Vec); @@ -458,6 +546,21 @@ impl Game { // Tests +pub fn complicated() -> Result { + let mut game = Game::new(2, StdRng::seed_from_u64(1))?; + + let mut tiles = Tile::Blue; + + for factory in &mut game.factories { + for _ in 0..4 { + factory.push(tiles); + tiles = tiles.into_iter().next().unwrap_or(Tile::Blue); + } + } + + Ok(game) +} + #[test] fn bag() { let game = Game::new(2, StdRng::seed_from_u64(123)).unwrap(); @@ -485,4 +588,13 @@ fn connected() -> Result<(), String> { assert_eq!(score, 7); Ok(()) +} + +#[test] +fn game_move_iter() { + let i = GameMove::default(); + println!("Original: {:?}", i); + assert_eq!(i.into_iter().next().unwrap(), GameMove(1, Tile::Blue, 1)); + + assert_eq!(i.into_iter().count(), 5) } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9eac7e7..2d1a2cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use rand::prelude::*; fn main() -> Result<(), &'static str> { let mut g_rng = StdRng::seed_from_u64(42); - for _ in 0..500000 { + for _ in 0..10000 { let rng = match StdRng::from_rng(&mut g_rng) { Ok(r) => r, Err(e) => { @@ -27,11 +27,11 @@ fn run(rng: StdRng) -> Result<(), &'static str> { //println!("{:#?}", game); all_err = true; let mut game_move:Option = Some(GameMove::default()); - while let Some(mut i) = game_move { + while let Some(i) = game_move { match game.do_move(i) { Err(e) => { //println!("{:?}: {}", i, e); - game_move = i.next(); + game_move = i.into_iter().next(); }, Ok(_) => { all_err = false; @@ -43,44 +43,46 @@ fn run(rng: StdRng) -> Result<(), &'static str> { Ok(()) } -impl Iterator for Tile { - type Item = Tile; +#[test] +fn calculate_options() -> Result<(), String> { + let game = complicated()?; + println!("{:#?}", game); - fn next(&mut self) -> Option{ - match *self { - Tile::Start => None, - Tile::Blue => Some(Tile::Yellow), - Tile::Yellow => Some(Tile::Red), - Tile::Red => Some(Tile::Black), - Tile::Black => Some(Tile::Teal), - Tile::Teal => None - } - } + println!("{}", count_options(game, 0)); + + Ok(()) } -impl Iterator for GameMove { - type Item = GameMove; - - fn next(&mut self) -> Option { - let mut factory = self.0 + 1; - let mut _tile = Some(self.1); - let mut pattern = self.2; - if factory > 9 { - factory = 0; - _tile = _tile.unwrap().next(); - }; - let tile = match _tile { - None => { - match pattern { - 6 => pattern = 0, - 0 => return None, - _ => pattern = pattern + 1 - }; - Tile::Blue - }, - Some(x) => x +fn count_options(game: Game, depth: u8) -> u128 { + let mut sum = 0; + let i = GameMove::default(); + let mut all_failed = true; + for game_move in i { + //println!("{:?}", game_move); + let mut new_game = game.clone(); + let r = new_game.do_move(game_move); + match r { + Ok(_) => sum += {/*println!("{}", depth);*/ all_failed = false; count_options(new_game, depth + 1)}, + Err(_) => continue }; + }; - Some(GameMove(factory, tile, pattern)) + if all_failed { + //println!("{}: ALL FAILED!", depth); + return 1; } + + return sum; + + /*game_move.iter_mut().map(|x| { + let mut new_game = game.clone(); + let r = new_game.do_move(*x); + println!("{:#?}", r); + match r { + Ok(_) => count_options(new_game), + Err(_) => 0 + } + }) + .sum::()*/ + } \ No newline at end of file