From fbd10833b2b0aa98cdf1fc9bf35bd5dd206bcd03 Mon Sep 17 00:00:00 2001 From: dan63047 Date: Wed, 15 Nov 2023 18:31:25 +0300 Subject: [PATCH] RandomWithoutDirectRepetition & BagX2 randomizers --- src/engine/randomizers.rs | 50 +++++++++++++++++++++++++++++++++++---- src/engine/resources.rs | 3 ++- src/engine/systems.rs | 4 ++-- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/engine/randomizers.rs b/src/engine/randomizers.rs index 0f58920..e85424b 100644 --- a/src/engine/randomizers.rs +++ b/src/engine/randomizers.rs @@ -4,15 +4,20 @@ use rand::thread_rng; use super::{rotation_systems::PiecesData, resources::Piece}; pub trait Randomizer{ - fn populate_next(&self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec; + fn create() -> Self where Self: Sized; + fn populate_next(&mut self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec; } pub struct Bag {} -pub struct RandomWithoutDirectRepetition {} +pub struct BagX2 {} + +pub struct RandomWithoutDirectRepetition { + memory: usize +} impl Randomizer for Bag { - fn populate_next(&self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec { + fn populate_next(&mut self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec { let mut bag = vec![]; let mut id: usize = 0; for _ in &pieces_data.pieces{ @@ -23,11 +28,46 @@ impl Randomizer for Bag { bag.shuffle(&mut rng); bag } + + fn create() -> Self where Self: Sized { + Bag { } + } +} + +impl Randomizer for BagX2 { + fn populate_next(&mut self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec { + let mut bag = vec![]; + let mut id: usize = 0; + for _ in &pieces_data.pieces{ + bag.insert(id, Piece::create(pieces_data, id, board_width, board_height)); + bag.insert(id, Piece::create(pieces_data, id, board_width, board_height)); + id += 1; + } + let mut rng = thread_rng(); + bag.shuffle(&mut rng); + bag + } + + fn create() -> Self where Self: Sized { + BagX2 { } + } } impl Randomizer for RandomWithoutDirectRepetition { - fn populate_next(&self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec { + fn populate_next(&mut self, pieces_data: &PiecesData, board_width: isize, board_height: isize) -> Vec { let random_number = random::() % pieces_data.pieces.len(); - vec![Piece::create(pieces_data, random_number, board_width, board_height)] + if random_number != self.memory { + self.memory = random_number; + vec![Piece::create(pieces_data, random_number, board_width, board_height)] + }else{ + let random_number = random::() % pieces_data.pieces.len(); + self.memory = random_number; + vec![Piece::create(pieces_data, random_number, board_width, board_height)] + } + + } + + fn create() -> Self where Self: Sized { + RandomWithoutDirectRepetition { memory: 65535 } } } \ No newline at end of file diff --git a/src/engine/resources.rs b/src/engine/resources.rs index bb12b63..5d90bf6 100644 --- a/src/engine/resources.rs +++ b/src/engine/resources.rs @@ -180,8 +180,9 @@ impl Engine { self.next_queue.remove(0); } - pub fn init(&mut self, rotation_system: &str){ + pub fn init(&mut self, rotation_system: &str, randomizer: Box){ self.rotation_system = ROTATION_SYSTEMS[rotation_system].clone(); + self.randomizer = randomizer; while self.next_queue.len() <= self.board.show_next as usize { self.next_queue.append(&mut self.randomizer.populate_next(&self.rotation_system, self.board.width as isize, self.board.height as isize)); } diff --git a/src/engine/systems.rs b/src/engine/systems.rs index 2741861..b5ef271 100644 --- a/src/engine/systems.rs +++ b/src/engine/systems.rs @@ -1,4 +1,4 @@ -use super::{resources::Engine, rotation_systems::LockDelayMode, GameStates, GameloopStates}; +use super::{resources::Engine, rotation_systems::LockDelayMode, GameStates, GameloopStates, randomizers::*}; use crate::engine::components::*; use bevy::{prelude::*, sprite::MaterialMesh2dBundle}; @@ -29,7 +29,7 @@ pub fn init_engine( }, BoardVisual {}, )); - engine.init("NRS"); + engine.init("SRS", Box::new(BagX2::create())); next_state.set(GameloopStates::Falling); }