rewrote the list implementation to use traits for better mocking when testing
This commit is contained in:
parent
c7b41c94c3
commit
70e2b4460c
4 changed files with 142 additions and 34 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -6,7 +6,7 @@ version = 3
|
||||||
name = "BeepSortMacroQuad"
|
name = "BeepSortMacroQuad"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-recursion",
|
"async-trait",
|
||||||
"macroquad",
|
"macroquad",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-recursion"
|
name = "async-trait"
|
||||||
version = "1.0.2"
|
version = "0.1.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b015a331cc64ebd1774ba119538573603427eaace0a1950c423ab971f903796"
|
checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
macroquad = "0.3.25"
|
macroquad = "0.3.25"
|
||||||
async-recursion = "1.0.2"
|
async-trait = "0.1.64"
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly"
|
channel = "nightly"
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
|
||||||
use crate::BarPlugin::Bar;
|
use crate::BarPlugin::Bar;
|
||||||
|
use crate::GuiHookVec;
|
||||||
use crate::GuiHookVec::GuiVec;
|
use crate::GuiHookVec::GuiVec;
|
||||||
|
use crate::GuiHookVec::SortingList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use async_recursion::async_recursion;
|
|
||||||
use macroquad::prelude::screen_width;
|
|
||||||
use macroquad::window::screen_height;
|
|
||||||
use std::collections::BinaryHeap;
|
use std::collections::BinaryHeap;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
@ -21,7 +22,7 @@ pub struct Algorithm{
|
||||||
impl Algorithm{
|
impl Algorithm{
|
||||||
|
|
||||||
pub async fn run(length:i32, delay:f32, functionName:String){
|
pub async fn run(length:i32, delay:f32, functionName:String){
|
||||||
let mut list = GuiVec::new(length, delay);
|
let mut list:GuiVec = SortingList::new(length, delay);
|
||||||
list.randomize();
|
list.randomize();
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ impl Algorithm{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insertSort(list:&mut GuiVec){
|
pub async fn insertSort(list:&mut impl SortingList){
|
||||||
for index in 0..list.len(){
|
for index in 0..list.len(){
|
||||||
let mut j = index;
|
let mut j = index;
|
||||||
while j>0 && list.lessThan(j, j-1){
|
while j>0 && list.lessThan(j, j-1){
|
||||||
|
@ -73,7 +74,7 @@ impl Algorithm{
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub async fn bubbleSort(list:&mut GuiVec){
|
pub async fn bubbleSort(list:&mut impl SortingList){
|
||||||
let n = list.len();
|
let n = list.len();
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
for j in 0..(n - i - 1) {
|
for j in 0..(n - i - 1) {
|
||||||
|
@ -85,7 +86,7 @@ impl Algorithm{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn bogoSort(list:&mut GuiVec){
|
pub async fn bogoSort(list:&mut impl SortingList){
|
||||||
|
|
||||||
loop{
|
loop{
|
||||||
if list.swap(0,0).await {return};
|
if list.swap(0,0).await {return};
|
||||||
|
@ -96,7 +97,7 @@ impl Algorithm{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn cocktailShaker(list:&mut GuiVec){
|
pub async fn cocktailShaker(list:&mut impl SortingList){
|
||||||
let mut lowerBound = 0;
|
let mut lowerBound = 0;
|
||||||
let mut upperBound = list.len()-1;
|
let mut upperBound = list.len()-1;
|
||||||
let mut swapped = true;
|
let mut swapped = true;
|
||||||
|
@ -127,7 +128,7 @@ impl Algorithm{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn binaryHeap(list:&mut GuiVec){
|
pub async fn binaryHeap(list:&mut impl SortingList){
|
||||||
|
|
||||||
let mut indexMap:HashMap<i32, usize> = HashMap::new();
|
let mut indexMap:HashMap<i32, usize> = HashMap::new();
|
||||||
let mut binHeap:BinaryHeap<i32> = BinaryHeap::new();
|
let mut binHeap:BinaryHeap<i32> = BinaryHeap::new();
|
||||||
|
@ -151,7 +152,7 @@ impl Algorithm{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn partition(list:&mut GuiVec, mut low:usize, mut high:usize, p:i32) -> i32{
|
pub async fn partition(list:&mut impl SortingList, mut low:usize, mut high:usize, p:i32) -> i32{
|
||||||
let mut pIndex = low;
|
let mut pIndex = low;
|
||||||
|
|
||||||
for i in low..high{
|
for i in low..high{
|
||||||
|
@ -166,7 +167,7 @@ impl Algorithm{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn quickSort(list:&mut GuiVec) {
|
pub async fn quickSort(list:&mut impl SortingList) {
|
||||||
let mut stack:Vec<(usize,usize)> = Vec::new();
|
let mut stack:Vec<(usize,usize)> = Vec::new();
|
||||||
|
|
||||||
let start = 0;
|
let start = 0;
|
||||||
|
@ -177,7 +178,7 @@ impl Algorithm{
|
||||||
while stack.len() > 0{
|
while stack.len() > 0{
|
||||||
let (start,end) = stack.pop().unwrap();
|
let (start,end) = stack.pop().unwrap();
|
||||||
|
|
||||||
let p = list.list[end].position;
|
let p = list.get(end).position;
|
||||||
let temp = Algorithm::partition(list, start, end, p).await;
|
let temp = Algorithm::partition(list, start, end, p).await;
|
||||||
let pivot = if temp >= 0 {temp} else {return};
|
let pivot = if temp >= 0 {temp} else {return};
|
||||||
|
|
||||||
|
@ -193,10 +194,10 @@ impl Algorithm{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn radixSort(list:&mut GuiVec) {
|
pub async fn radixSort(list:&mut impl SortingList) {
|
||||||
|
|
||||||
let mut max = usize::MAX;
|
let mut max = usize::MAX;
|
||||||
for i in list.list.clone().into_iter().map(|x| x.position.to_string()){
|
for i in list.getListClone().into_iter().map(|x| x.position.to_string()){
|
||||||
if max < i.len(){
|
if max < i.len(){
|
||||||
max = i.len();
|
max = i.len();
|
||||||
}
|
}
|
||||||
|
@ -207,7 +208,7 @@ impl Algorithm{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn radix(list:&mut GuiVec, radix:usize) -> bool{
|
pub async fn radix(list:&mut impl SortingList, radix:usize) -> bool{
|
||||||
let mut bucket = vec![vec![];10];
|
let mut bucket = vec![vec![];10];
|
||||||
|
|
||||||
for (i, bar) in list.elements().enumerate(){
|
for (i, bar) in list.elements().enumerate(){
|
||||||
|
@ -229,7 +230,7 @@ impl Algorithm{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut listClone = list.list.clone();
|
let mut listClone = list.getListClone();
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for i in sortedIndexes.clone(){
|
for i in sortedIndexes.clone(){
|
||||||
if list.set(count, listClone[i]).await {return true};
|
if list.set(count, listClone[i]).await {return true};
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
use std::borrow::{Borrow, BorrowMut};
|
use std::borrow::{Borrow, BorrowMut};
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use std::path::Iter;
|
use std::path::Iter;
|
||||||
|
use async_trait::async_trait;
|
||||||
use macroquad::color::{BROWN, WHITE};
|
use macroquad::color::{BROWN, WHITE};
|
||||||
use macroquad::hash;
|
use macroquad::hash;
|
||||||
use macroquad::prelude::{clear_background, Vec2, BLACK};
|
use macroquad::prelude::{clear_background, Vec2, BLACK};
|
||||||
|
@ -31,10 +32,40 @@ pub struct GuiVec{
|
||||||
skipped:i32
|
skipped:i32
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#[async_trait]
|
||||||
|
pub trait SortingList{
|
||||||
|
|
||||||
impl GuiVec{
|
fn new(length:i32, delay:f32) -> Self;
|
||||||
|
|
||||||
|
fn len(&self) -> usize;
|
||||||
|
|
||||||
|
async fn swap(&mut self, index1:usize, index2:usize) -> bool;
|
||||||
|
|
||||||
|
async fn draw(&mut self);
|
||||||
|
|
||||||
pub fn new(length:i32, delay:f32) -> Self {
|
fn randomize(&mut self);
|
||||||
|
|
||||||
|
fn elements(&mut self) -> std::slice::Iter<'_, Bar>;
|
||||||
|
|
||||||
|
fn get(&mut self, i:usize)-> &Bar;
|
||||||
|
|
||||||
|
fn lessThan(&mut self, a:usize, b:usize) -> bool;
|
||||||
|
|
||||||
|
|
||||||
|
fn lessThanEqual(&mut self, a:usize, b:i32) -> bool;
|
||||||
|
|
||||||
|
fn isSorted(&mut self) -> bool;
|
||||||
|
|
||||||
|
async fn set(&mut self, i:usize, elem:Bar) -> bool;
|
||||||
|
|
||||||
|
async fn show(&mut self);
|
||||||
|
|
||||||
|
fn getListClone(&self) -> Vec<Bar>;
|
||||||
|
}
|
||||||
|
#[async_trait]
|
||||||
|
impl SortingList for GuiVec{
|
||||||
|
|
||||||
|
fn new(length:i32, delay:f32) -> Self {
|
||||||
let colorStep = 360./length as f32;
|
let colorStep = 360./length as f32;
|
||||||
let mut list:Vec<Bar> = vec!();
|
let mut list:Vec<Bar> = vec!();
|
||||||
for i in 1..length+1 {
|
for i in 1..length+1 {
|
||||||
|
@ -55,7 +86,7 @@ impl GuiVec{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn draw(&mut self){
|
async fn draw(&mut self){
|
||||||
let mut frames = 0.0;
|
let mut frames = 0.0;
|
||||||
let mut delayText = self.delay.to_string();
|
let mut delayText = self.delay.to_string();
|
||||||
let mut renderSkipText = self.renderSkip.to_string();
|
let mut renderSkipText = self.renderSkip.to_string();
|
||||||
|
@ -123,38 +154,38 @@ impl GuiVec{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize{
|
fn len(&self) -> usize{
|
||||||
self.list.len()
|
self.list.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn swap(&mut self, index1:usize, index2:usize) -> bool{
|
async fn swap(&mut self, index1:usize, index2:usize) -> bool{
|
||||||
self.writes += 2;
|
self.writes += 2;
|
||||||
self.reads += 2;
|
self.reads += 2;
|
||||||
self.list.swap(index1, index2);
|
self.list.swap(index1, index2);
|
||||||
self.draw().await;
|
self.draw().await;
|
||||||
self.done
|
self.done
|
||||||
}
|
}
|
||||||
pub fn randomize(&mut self){
|
fn randomize(&mut self){
|
||||||
self.list.shuffle();
|
self.list.shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn elements(&mut self) -> std::slice::Iter<'_, Bar> {
|
fn elements(&mut self) -> std::slice::Iter<'_, Bar> {
|
||||||
self.list.iter()
|
self.list.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&mut self, i:usize)-> &Bar{
|
fn get(&mut self, i:usize)-> &Bar{
|
||||||
self.reads += 1;
|
self.reads += 1;
|
||||||
self.list.get(i).unwrap()
|
self.list.get(i).unwrap()
|
||||||
}
|
}
|
||||||
pub fn lessThan(&mut self, a:usize, b:usize) -> bool{
|
fn lessThan(&mut self, a:usize, b:usize) -> bool{
|
||||||
self.comps += 1;
|
self.comps += 1;
|
||||||
return self.get(a).position < self.get(b).position
|
return self.get(a).position < self.get(b).position
|
||||||
}
|
}
|
||||||
pub fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{
|
fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{
|
||||||
self.comps += 1;
|
self.comps += 1;
|
||||||
return self.get(a).position <= b
|
return self.get(a).position <= b
|
||||||
}
|
}
|
||||||
pub fn isSorted(&mut self) -> bool{
|
fn isSorted(&mut self) -> bool{
|
||||||
self.reads += self.len() as i32;
|
self.reads += self.len() as i32;
|
||||||
let mut prev = 0;
|
let mut prev = 0;
|
||||||
for bar in self.list.iter() {
|
for bar in self.list.iter() {
|
||||||
|
@ -166,7 +197,7 @@ impl GuiVec{
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
pub async fn set(&mut self, i:usize, elem:Bar) -> bool{
|
async fn set(&mut self, i:usize, elem:Bar) -> bool{
|
||||||
|
|
||||||
self.writes += 1;
|
self.writes += 1;
|
||||||
self.reads += 1;
|
self.reads += 1;
|
||||||
|
@ -175,7 +206,7 @@ impl GuiVec{
|
||||||
self.done
|
self.done
|
||||||
|
|
||||||
}
|
}
|
||||||
pub async fn show(&mut self){
|
async fn show(&mut self){
|
||||||
loop{
|
loop{
|
||||||
if !self.done{
|
if !self.done{
|
||||||
self.draw().await
|
self.draw().await
|
||||||
|
@ -185,5 +216,81 @@ impl GuiVec{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn getListClone(&self) -> Vec<Bar>{
|
||||||
|
self.list.clone()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NonGuiVec{
|
||||||
|
pub list: Vec<Bar>,
|
||||||
|
|
||||||
|
}
|
||||||
|
#[async_trait]
|
||||||
|
impl SortingList for NonGuiVec{
|
||||||
|
fn new(length:i32, delay:f32) -> Self{
|
||||||
|
let mut list = Vec::new();
|
||||||
|
for i in 0..(length as usize){
|
||||||
|
list.push(Bar::new(i as i32, i as f32))
|
||||||
|
}
|
||||||
|
NonGuiVec { list: list }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn len(&self) -> usize{
|
||||||
|
self.list.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn swap(&mut self, index1:usize, index2:usize) -> bool{
|
||||||
|
self.list.swap(index1, index2);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn draw(&mut self){
|
||||||
|
self.swap(0, 0).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn randomize(&mut self){
|
||||||
|
self.list.shuffle();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn elements(&mut self) -> std::slice::Iter<'_, Bar> {
|
||||||
|
self.list.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&mut self, i:usize)-> &Bar{
|
||||||
|
|
||||||
|
self.list.get(i).unwrap()
|
||||||
|
}
|
||||||
|
fn lessThan(&mut self, a:usize, b:usize) -> bool{
|
||||||
|
|
||||||
|
return self.get(a).position < self.get(b).position
|
||||||
|
}
|
||||||
|
fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{
|
||||||
|
return self.get(a).position <= b
|
||||||
|
}
|
||||||
|
fn isSorted(&mut self) -> bool{
|
||||||
|
let mut prev = 0;
|
||||||
|
for bar in self.list.iter() {
|
||||||
|
if bar.position < prev{
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
prev = bar.position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
async fn set(&mut self, i:usize, elem:Bar) -> bool{
|
||||||
|
|
||||||
|
self.list[i] = elem;
|
||||||
|
self.draw().await;
|
||||||
|
false
|
||||||
|
|
||||||
|
}
|
||||||
|
async fn show(&mut self){
|
||||||
|
|
||||||
|
}
|
||||||
|
fn getListClone(&self) -> Vec<Bar>{
|
||||||
|
self.list.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue