diff --git a/Cargo.lock b/Cargo.lock index accd7ed..e126b0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "coz" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef55b3fe2f5477d59e12bc792e8b3c95a25bd099eadcfae006ecea136de76e2" +dependencies = [ + "libc", + "once_cell", +] + [[package]] name = "getrandom" version = "0.2.0" @@ -27,9 +37,16 @@ checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" name = "mercury" version = "0.1.0" dependencies = [ + "coz", "rand", ] +[[package]] +name = "once_cell" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" + [[package]] name = "ppv-lite86" version = "0.2.10" diff --git a/Cargo.toml b/Cargo.toml index d1d14c8..41c3a67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rand = "0.8.0" \ No newline at end of file +rand = "0.8.0" +coz = "0.1" + +[profile.release] +debug = 1 \ No newline at end of file diff --git a/profile.coz b/profile.coz new file mode 100644 index 0000000..9fdc54d --- /dev/null +++ b/profile.coz @@ -0,0 +1,4 @@ +startup time=1609744772805409109 +runtime time=10083706 +startup time=1609744984945886640 +runtime time=10097224 diff --git a/shell.nix b/shell.nix index 58ab405..adf88b8 100644 --- a/shell.nix +++ b/shell.nix @@ -30,5 +30,6 @@ with nixpkgs; matklad.rust-analyzer ]; }) + coz ]; } diff --git a/src/azul.rs b/src/azul.rs index d033d6d..a9486dc 100644 --- a/src/azul.rs +++ b/src/azul.rs @@ -14,6 +14,11 @@ pub enum Tile { // factory, color, pattern line #[derive(Debug, Clone, Copy)] pub struct GameMove (pub usize, pub Tile, pub usize); +impl Default for GameMove { + fn default() -> Self { + GameMove(0, Tile::Blue, 0) + } +} #[derive(Debug, Clone)] struct Bag (Vec); @@ -170,6 +175,7 @@ impl Board { } } fn connected(&self, coordinate: (usize, usize)) -> u8 { + coz::scope!("connected tiles"); let wall = self.wall; let mut sum = 0; @@ -222,7 +228,7 @@ impl Default for Board { #[derive(Default, Debug, Clone)] pub struct Game { - turn: u8, + turn: u32, player: usize, box_top: Bag, bag: Bag, @@ -232,6 +238,7 @@ pub struct Game { } impl Game { pub fn new(players: usize) -> Result { + coz::scope!("create game"); let n_factories = match players { 2 => 5, 3 => 7, @@ -261,6 +268,7 @@ impl Game { Ok(game) } pub fn fill(&mut self) -> Result<(), &'static str> { + coz::scope!("fill factories from bag"); for factory in &self.factories { if factory.len() != 0 { return Err("Cannot fill, factories are not empty") @@ -284,6 +292,7 @@ impl Game { Ok(()) } fn score(&mut self) -> Result<(), &'static str> { + coz::scope!("score boards"); for board in &mut self.boards { for row in 0..4 { if board.patterns[row].len() == (row + 1) { @@ -310,7 +319,7 @@ impl Game { Ok(()) } pub fn do_move(&self, game_move: GameMove) -> Result { - + coz::scope!("do a move"); if game_move.1 == Tile::Start { return Err("You can't take the start tile alone") } @@ -325,7 +334,7 @@ impl Game { if self.market.contains(&game_move.1) { let mut hand = self.market.deref().clone(); hand.retain(|&x| x == Tile::Start || x == game_move.1); - game.market.retain(|&x| x != Tile::Start || x != game_move.1); + game.market.retain(|x| *x != Tile::Start && *x != game_move.1); board.floor.append(&mut hand) } @@ -333,7 +342,7 @@ impl Game { return Err("Market does not contain selected tile") } }, - GameMove(0, _, 1..=9) => { + GameMove(0, _, 1..=6) => { if self.market.len() == 0 { return Err("Market is empty"); } @@ -347,7 +356,7 @@ impl Game { let mut hand = self.market.deref().clone(); hand.retain(|&x| x == Tile::Start || x == game_move.1); - game.market.retain(|&x| x != Tile::Start || x != game_move.1); + game.market.retain(|x| *x != Tile::Start && *x != game_move.1); for tile in hand.drain(..) { let empty = game_move.2 - &target.len(); @@ -369,6 +378,10 @@ impl Game { } }, GameMove(1..=9, _, _) => { + if game_move.0 > self.factories.len() - 1 { + return Err("That factory is out of bounds"); + } + let old_factory = &self.factories[game_move.0 - 1]; if old_factory.contains(&game_move.1) { diff --git a/src/main.rs b/src/main.rs index 7be2fab..a4aad9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,70 @@ fn main() -> Result<(), &'static str>{ let mut game = Game::new(2)?; game.fill()?; - println!("{:#?}", game); + + let mut all_err = false; + while !all_err { + println!("{:#?}", game); + all_err = true; + let mut game_move:Option = Some(GameMove::default()); + while let Some(mut i) = game_move { + match game.do_move(i) { + Err(e) => { + println!("{:?}: {}", i, e); + game_move = i.next(); + }, + Ok(g) => { + println!("{:?}", i); + game = g; + all_err = false; + break; + } + } + } + } + let game2 = game.do_move(GameMove(1, Tile::Red, 1))?; - let game2 = game2.do_move(GameMove(0, Tile::Blue, 1))?; println!("{:#?}", game2); Ok(()) } + +impl Iterator for Tile { + type Item = Tile; + + 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 + } + } +} + +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 => { + pattern += 1; + Tile::Blue + }, + Some(x) => x + }; + if pattern > 6 { + return None + } + + Some(GameMove(factory, tile, pattern)) + } +} \ No newline at end of file