From 94288fc36a9e6b934c61634db1acbbcd0f7367f7 Mon Sep 17 00:00:00 2001 From: LordMidas <55047920+LordMidas@users.noreply.github.com> Date: Fri, 6 Oct 2023 21:51:23 -0400 Subject: [PATCH 1/2] feat: allow making a weighted container ordered The primary purpose is to allow a `foreach (item in container)` type iteration instead of the standard `foreach (item, weight in container)`. This helps the container to be used interchangeably with arrays without having to do a typeof check and duplicate foreach loops separately for arrays and weighted containers. --- msu/classes/weighted_container.nut | 45 +++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/msu/classes/weighted_container.nut b/msu/classes/weighted_container.nut index a94637f29..3e438776e 100644 --- a/msu/classes/weighted_container.nut +++ b/msu/classes/weighted_container.nut @@ -2,6 +2,7 @@ { Total = null; Table = null; + Array = null; Forced = null; NextIItems = null; NextIIndex = null; @@ -16,7 +17,8 @@ function _get( _item ) { - if (_item in this.Table) return this.Table[_item]; + if (this.Array != null) return this.Array[_item]; // _item is an idx in this case + else if (_item in this.Table) return this.Table[_item]; throw null; } @@ -25,10 +27,24 @@ this.Total = _original.Total; this.Table = clone _original.Table; this.Forced = clone _original.Forced; + this.Array = _original.Array == null ? null : clone _original.Array; } function _nexti( _prev ) { + if (this.Array != null) + { + if (this.Array.len() == 0) + return null; + + if (_prev == null) + return 0; + else if (_prev == this.Array.len() - 1) + return null; + + return _prev + 1; + } + if (_prev == null) { this.NextIItems = ::MSU.Table.keys(this.Table); @@ -101,6 +117,7 @@ if (this.Table[_item] < 0) delete this.Forced[_item]; else this.Total -= this.Table[_item]; delete this.Table[_item]; + this.Array.remove(this.Array.find(_item)); } function contains( _item ) @@ -108,6 +125,29 @@ return _item in this.Table; } + function makeOrdered( _bool = true ) + { + if (_bool) + { + this.Array = ::MSU.Table.keys(this.Table); + this.sort(); + } + else + { + this.Array = null; + } + } + + function isOrdered() + { + return this.Array != null; + } + + function sort() + { + this.Array.sort(@(a, b) this.Table[a] <=> this.Table[b]); // Sort ascending + } + function getProbability( _item, _exclude = null ) { if (_exclude != null) @@ -155,6 +195,7 @@ // must return a len 2 array with weight, item as elements local ret = ::MSU.Class.WeightedContainer(); + if (this.Array != null) ret.makeOrdered(); foreach (item, weight in this.Table) { local pair = _function(item, weight); @@ -169,6 +210,7 @@ // must return a boolean local ret = ::MSU.Class.WeightedContainer(); + if (this.Array != null) ret.makeOrdered(); foreach (item, weight in this.Table) { if (_function(item, weight)) ret.add(item, weight); @@ -181,6 +223,7 @@ this.Total = 0.0; this.Table.clear(); this.Forced.clear(); + if (this.Array != null) this.Array.clear(); } function max() From 78338c237ca22c203fa02f705eef753717e68702 Mon Sep 17 00:00:00 2001 From: LordMidas <55047920+LordMidas@users.noreply.github.com> Date: Fri, 6 Oct 2023 22:05:31 -0400 Subject: [PATCH 2/2] fix: add and remove functions when array is not null --- msu/classes/weighted_container.nut | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/msu/classes/weighted_container.nut b/msu/classes/weighted_container.nut index 3e438776e..e781b19f7 100644 --- a/msu/classes/weighted_container.nut +++ b/msu/classes/weighted_container.nut @@ -109,15 +109,20 @@ { this.Table[_item] <- 0; this.updateWeight(_item, _weight); + if (this.Array != null) this.Array.push(_item); } } function remove( _item ) { + if (this.Array != null) // _item is an idx + { + _item = this.Array.remove(this.Array.find(_item)); + } + if (this.Table[_item] < 0) delete this.Forced[_item]; else this.Total -= this.Table[_item]; delete this.Table[_item]; - this.Array.remove(this.Array.find(_item)); } function contains( _item )