From 654469bb4a92e0c226b7373472244cb0d5652800 Mon Sep 17 00:00:00 2001 From: cool-mist Date: Sun, 11 May 2025 23:10:02 +0530 Subject: [PATCH] enable tests --- Cargo.lock | 107 +++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 3 ++ src/bin/sol_cli.rs | 12 ++++- src/game.rs | 13 ++++-- src/generator.rs | 54 ++++++++++------------- src/main.rs | 4 +- 6 files changed, 153 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a251e9c..7a59f33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -64,6 +64,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + [[package]] name = "bytemuck" version = "1.21.0" @@ -126,6 +132,18 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi", +] + [[package]] name = "glam" version = "0.27.0" @@ -248,13 +266,22 @@ version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", "miniz_oxide", ] +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy 0.8.25", +] + [[package]] name = "proc-macro2" version = "1.0.92" @@ -279,6 +306,41 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + [[package]] name = "rust-fuzzy-search" version = "0.1.1" @@ -326,6 +388,7 @@ version = "0.1.1" dependencies = [ "argh", "macroquad", + "rand", ] [[package]] @@ -357,6 +420,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "winapi" version = "0.3.9" @@ -379,13 +451,31 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive 0.8.25", ] [[package]] @@ -398,3 +488,14 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 299b132..bcb16e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,9 @@ default-run = "sol_chess" argh = "0.1.13" macroquad = "0.4.13" +[dev-dependencies] +rand = "0.9.1" + [profile.release] opt-level = 's' lto = true diff --git a/src/bin/sol_cli.rs b/src/bin/sol_cli.rs index 4742c9e..45435d9 100644 --- a/src/bin/sol_cli.rs +++ b/src/bin/sol_cli.rs @@ -1,9 +1,17 @@ use argh::FromArgs; use sol_chess::board::Board; -use sol_chess::generator; +use sol_chess::generator::{self, RandomRange}; use sol_chess::solver::Solver; +// Learn how to specify a different dependency for this binary +struct MacroquadRngTodo; +impl RandomRange for MacroquadRngTodo { + fn gen_range(&self, min: usize, max: usize) -> usize { + macroquad::rand::gen_range(min, max) + } +} + fn main() { let args: Args = argh::from_env(); @@ -65,7 +73,7 @@ fn generate_puzzle(num_pieces: Option, num_solutions: Option) -> Optio "Generating a puzzle with {} pieces with a maximum of {} solutions", num_pieces, num_solutions ); - let gen = generator::generate(num_pieces, num_solutions); + let gen = generator::generate(num_pieces, num_solutions, &MacroquadRngTodo); gen.print_stats(); let Some(board) = gen.board() else { diff --git a/src/game.rs b/src/game.rs index a51540e..cdae3c9 100644 --- a/src/game.rs +++ b/src/game.rs @@ -4,16 +4,23 @@ use std::{ }; use button::Button; -use macroquad::{math, prelude::*}; +use macroquad::{math, prelude::*, rand}; use sol_chess::{ board::{Board, BoardState}, - generator, + generator::{self, RandomRange}, }; use texture::PieceTexture; pub mod button; pub mod texture; +pub struct MacroquadRandAdapter; +impl RandomRange for MacroquadRandAdapter { + fn gen_range(&self, min: usize, max: usize) -> usize { + rand::gen_range(min, max) + } +} + pub struct Game { // The generated puzzle. We keep a copy of this to reset the game. original_board: Board, @@ -445,7 +452,7 @@ impl Game { fn next_puzzle(&mut self) { self.reset(); - let generate = generator::generate(6, 100); + let generate = generator::generate(6, 100, &MacroquadRandAdapter); let board = generate.board().expect("No puzzle was generated"); self.original_board = board.clone(); self.board = board; diff --git a/src/generator.rs b/src/generator.rs index a2d2d77..27872b0 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -5,9 +5,11 @@ use crate::{ solver::Solver, }; -use macroquad::{prelude::rand, time}; +pub trait RandomRange { + fn gen_range(&self, min: usize, max: usize) -> usize; +} -pub fn generate(num_pieces: u32, num_solutions: u32) -> GenerateStats { +pub fn generate(num_pieces: u32, num_solutions: u32, rand: &impl RandomRange) -> GenerateStats { let candidate_pieces = vec![ Piece::Pawn, Piece::Pawn, @@ -33,18 +35,13 @@ pub fn generate(num_pieces: u32, num_solutions: u32) -> GenerateStats { } let attempts: u32 = 1000; - let mut overall_stats = GenerateStats::new(0, 0, 0, 0., None); + let mut overall_stats = GenerateStats::new(0, 0, 0, None); for _ in 0..attempts { - let stats = try_generate(num_pieces, num_solutions, candidate_pieces.clone()); + let stats = try_generate(num_pieces, num_solutions, rand, candidate_pieces.clone()); overall_stats.piece_total += stats.piece_total; overall_stats.piece_success += stats.piece_success; overall_stats.total += stats.total; - overall_stats.total_seconds += stats.total_seconds; overall_stats.board = stats.board; - println!( - "Generating puzzle.. Elapsed: {}s", - overall_stats.total_seconds, - ); if overall_stats.board.is_some() { return overall_stats; } @@ -57,23 +54,15 @@ pub struct GenerateStats { piece_total: u32, piece_success: u32, total: u32, - total_seconds: f64, board: Option, } impl GenerateStats { - fn new( - piece_total: u32, - piece_success: u32, - total: u32, - total_millis: f64, - board: Option, - ) -> Self { + fn new(piece_total: u32, piece_success: u32, total: u32, board: Option) -> Self { Self { piece_total, piece_success, total, - total_seconds: total_millis, board, } } @@ -83,7 +72,6 @@ impl GenerateStats { add_stat(&mut stats, "Total attempts", self.total); add_stat(&mut stats, "Total pieces placed", self.piece_total); add_stat(&mut stats, "Success pieces placed", self.piece_success); - add_stat(&mut stats, "Total time (ms)", self.total_seconds); println!("{}", stats); } @@ -103,28 +91,27 @@ where fn try_generate( num_pieces: u32, num_solutions: u32, + rand: &impl RandomRange, mut candidate_pieces: Vec, ) -> GenerateStats { let mut board = Board::new(); let mut piece_total = 0; let mut piece_success = 0; - let now = time::get_time(); for _ in 0..num_pieces { let mut placed = false; let empty_squares = board.empty_squares(); let mut attempts = 15; while !placed { if attempts == 0 { - let elapsed = time::get_time() - now; - return GenerateStats::new(piece_total, piece_success, 1, elapsed, None); + return GenerateStats::new(piece_total, piece_success, 1, None); } attempts -= 1; piece_total += 1; - let index = rand::gen_range(0, candidate_pieces.len()); + let index = rand.gen_range(0, candidate_pieces.len()); let piece = candidate_pieces[index]; - let square_index = rand::gen_range(0, empty_squares.len()); + let square_index = rand.gen_range(0, empty_squares.len()); let mut random_square = empty_squares[square_index].clone(); random_square.piece = Some(piece); board.set(random_square.clone()); @@ -142,11 +129,10 @@ fn try_generate( } let solutions = Solver::new(board.clone()).solve(); - let elapsed = time::get_time() - now; if solutions.len() > num_solutions as usize { - GenerateStats::new(piece_total, piece_success, 1, elapsed, None) + GenerateStats::new(piece_total, piece_success, 1, None) } else { - GenerateStats::new(piece_total, piece_success, 1, elapsed, Some(board)) + GenerateStats::new(piece_total, piece_success, 1, Some(board)) } } @@ -156,11 +142,19 @@ mod tests { use super::*; - // Figure out a way to remove the macroquad dependencies from this package - // #[test] + use rand::Rng; + + struct TestRandom; + impl RandomRange for TestRandom { + fn gen_range(&self, min: usize, max: usize) -> usize { + rand::rng().random_range(min..max) + } + } + + #[test] fn generator_smoke() { for _ in 0..10 { - let gen_stats = generate(5, 5); + let gen_stats = generate(5, 5, &TestRandom); let board = gen_stats.board.expect("No puzzle was generated"); assert_eq!(board.game_state, BoardState::InProgress); diff --git a/src/main.rs b/src/main.rs index 280c5b0..888c87d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use game::Game; +use game::{Game, MacroquadRandAdapter}; use macroquad::prelude::*; use miniquad::date; use sol_chess::generator; @@ -37,7 +37,7 @@ async fn init() -> Game { let texture_res = Texture2D::from_file_with_format(&texture_bytes[..], None); texture_res.set_filter(FilterMode::Nearest); build_textures_atlas(); - let generate = generator::generate(6, 100); + let generate = generator::generate(6, 100, &MacroquadRandAdapter); let board = generate.board().expect("No puzzle was generated"); let game = Game::new(board, texture_res);