diff --git a/Cargo.lock b/Cargo.lock index 1a27bcb..853330e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,26 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "alloc_counter" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8c3a0a472b3a556e269be64dc65a5c013ba85e940d089367eb8c88f3fdfda9" +dependencies = [ + "alloc_counter_macro", + "pin-utils", +] + +[[package]] +name = "alloc_counter_macro" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a52f81f9add01deacdc1fcb05ba09523a8faefdec6c3f69cb752b9fa9c22e5a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -37,6 +58,7 @@ checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" name = "mercury" version = "0.1.0" dependencies = [ + "alloc_counter", "coz", "rand", "smallvec", @@ -48,12 +70,36 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" version = "0.8.0" @@ -100,6 +146,23 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a55ca5f3b68e41c979bf8c46a6f1da892ca4db8f94023ce0bd32407573b1ac0" +[[package]] +name = "syn" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index a305397..b6ea149 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,5 +11,13 @@ rand = "0.8.0" coz = "0.1" smallvec = "1.6.0" +#jemallocator = "0.3.2" +#mimalloc = { version = "0.1.22", default-features = false } + +alloc_counter = "0.0.4" + [profile.release] -debug = 1 \ No newline at end of file +debug = 1 +lto = "fat" +codegen-units = 1 +panic = "abort" diff --git a/shell.nix b/shell.nix index 25b0de9..a51c134 100644 --- a/shell.nix +++ b/shell.nix @@ -32,5 +32,8 @@ with nixpkgs; }) coz cargo-flamegraph + cmake + gcc + llvm_11 ]; } diff --git a/src/azul.rs b/src/azul.rs index aeb66f3..d48ec0f 100644 --- a/src/azul.rs +++ b/src/azul.rs @@ -2,6 +2,10 @@ use std::ops::{Deref, DerefMut}; use rand::prelude::*; use smallvec::{SmallVec, smallvec}; +use alloc_counter::{AllocCounterSystem, no_alloc}; +#[global_allocator] +static A: AllocCounterSystem = AllocCounterSystem; + #[derive(Debug, Clone, Copy, PartialEq)] pub enum Tile { Start, @@ -109,7 +113,7 @@ impl Iterator for GameMoveIter { } } -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] struct Bag (SmallVec<[Tile; 128]>); impl Default for Bag { fn default() -> Self { @@ -154,9 +158,14 @@ impl From> for Bag { } -#[derive(Default, Debug, Clone)] +#[derive(Default, Debug)] struct Factory (SmallVec<[Tile; 4]>); - +impl Clone for Factory { + #[no_alloc] + fn clone(&self) -> Self { + Factory(self.0.clone()) + } +} impl Deref for Factory { type Target = SmallVec<[Tile; 4]>; @@ -263,7 +272,6 @@ impl Board { } } fn connected(&self, coordinate: (usize, usize)) -> u8 { - coz::scope!("connected tiles"); let wall = self.wall; let mut sum = 0; @@ -312,24 +320,23 @@ pub struct Game { box_top: Bag, bag: Bag, market: Market, - factories: Vec, - boards: Vec + factories: SmallVec<[Factory; 5]>, // TODO set to 9? + boards: SmallVec<[Board; 2]> // TODO set to 4? } impl Game { pub fn new(players: usize, random: StdRng) -> Result { - coz::scope!("create game"); let n_factories = match players { 2 => 5, 3 => 7, 4 => 9, _ => return Err("Not a valid amount of players") }; - let mut factories = Vec::::with_capacity(n_factories); + let mut factories = SmallVec::<[Factory; 5]>::new(); for _ in 0..n_factories { factories.push(Factory::default()) } - let mut boards = Vec::::with_capacity(players); + let mut boards = SmallVec::<[Board; 2]>::new(); for _ in 0..players { boards.push(Board::default()); } @@ -348,7 +355,6 @@ 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") @@ -372,7 +378,6 @@ 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) { @@ -398,9 +403,8 @@ impl Game { } Ok(()) } + // #[no_alloc(forbid)] pub fn do_move(&mut self, game_move: GameMove) -> Result<(), &'static str> { - coz::scope!("do a move"); - let board = &mut self.boards[self.player]; match game_move { GameMove(_, Tile::Start, _) => return Err("You can't take the start tile specifically"), @@ -410,7 +414,7 @@ impl Game { hand.retain(|x| *x == Tile::Start || *x == game_move.1); self.market.retain(|x| *x != Tile::Start && *x != game_move.1); - board.floor.append(&mut hand) + board.floor.append(&mut hand); } else { return Err("Market does not contain selected tile") @@ -436,7 +440,7 @@ impl Game { self.market.retain(|x| *x != Tile::Start && *x != game_move.1); for tile in hand.drain(..) { - let empty = game_move.2 - &target.len(); + let empty = game_move.2 - target.len(); if tile == Tile::Start { board.floor.push(tile); } diff --git a/src/main.rs b/src/main.rs index fc4e991..a9164bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,29 @@ mod azul; use azul::*; use rand::prelude::*; +//#[global_allocator] +//static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; + +//#[global_allocator] +//static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; + + fn main() -> Result<(), &'static str> { + let rng = StdRng::seed_from_u64(42); - let game = Game::new(2, rng)?; + let mut game = Game::new(2, rng)?; + game.fill()?; println!("{:#?}", game); - println!("{}", count_options(game, 0)); + + game.do_move(GameMove(1, Tile::Red, 2))?; + game.do_move(GameMove(4, Tile::Red, 2))?; + + game.do_move(GameMove(2, Tile::Red, 1))?; + + println!("{}", count_options(game, 0, 2)); + + + // calculate_options()?; Ok(()) } @@ -37,17 +55,21 @@ fn run(rng: StdRng) -> Result<(), &'static str> { Ok(()) } -#[test] -fn calculate_options() -> Result<(), String> { - let game = complicated()?; +fn calculate_options() -> Result<(), &'static str> { + let mut game = complicated()?; println!("{:#?}", game); - println!("{}", count_options(game, 0)); + // We know how many possibilities there are the first round... + game.do_move(GameMove(1, Tile::Blue, 0))?; + + let options = count_options(game, 0, 4); + println!("{}", options * 20 * 6); Ok(()) } -fn count_options(game: Game, depth: u8) -> u128 { +fn count_options(game: Game, depth: u8, treshold: u8) -> u128 { + coz::scope!("count option"); let mut sum = 0; let i = GameMove::default(); let mut all_failed = true; @@ -56,16 +78,21 @@ fn count_options(game: Game, depth: u8) -> u128 { 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)}, + Ok(_) => sum += {/*println!("{}", depth);*/ all_failed = false; coz::progress!("OK"); count_options(new_game, depth + 1, treshold)}, Err(_) => continue }; }; if all_failed { - //println!("{}: ALL FAILED!", depth); + if depth <= treshold { + println!("{}: ALL FAILED!", depth); + } return 1; } + if depth <= treshold { + println!("{}: sum: {}", depth, sum); + } return sum; /*game_move.iter_mut().map(|x| {