diff --git a/ArrayClass.yymps b/ArrayClass.yymps index 39b3b9a..b3b88f8 100644 Binary files a/ArrayClass.yymps and b/ArrayClass.yymps differ diff --git a/Sample+Tests/#backups/scripts/ArrayClass/ArrayClass.gml.backup0 b/Sample+Tests/#backups/scripts/ArrayClass/ArrayClass.gml.backup0 new file mode 100644 index 0000000..53452a5 --- /dev/null +++ b/Sample+Tests/#backups/scripts/ArrayClass/ArrayClass.gml.backup0 @@ -0,0 +1,1029 @@ +// 2020-09-15 10:45:15 +///!!! +/// For examples see Tests.gml +///!!! + +// See type-conversion API at the bottom of this file + + +///@function Array(*item1, *item2, ...) +///@description Constructor funcion for Array objects +///@param {any} *item +function Array() constructor { + content = []; + size = 0; + + // Change these if you want to avoid crashes + // (it may or may not cause unexpected consequences) + #macro ARRAY_SHOW_ERROR true + #macro ARRAY_SHOW_WARNING true + + + static __throw = function(err) { + if ARRAY_SHOW_ERROR { + throw err; + } + else if ARRAY_SHOW_WARNING { + show_debug_message("Array error: "+string(err)) + } + } + + ///@function append(value, value2, ..) + ///@description Adds (a) value(s) to the end of the array + ///@param {any} value + static append = function(value) { + for(var i = 0; i < argument_count; ++i) { + var val = argument[i] + content[size] = val; + ++size; + } + + return self; + } + + ///@function add(value, value2, ..) + ///@description Mirrors append() method + ///@param {any} value + static add = function(value) { + for(var i = 0; i < argument_count; ++i) { + var val = argument[i] + content[size] = val; + ++size; + } + + return self; + } + + ///@function bogosort() + ///@description This is just a funny meme, please don't use this in actual projects + static bogosort = function(func) { + var i = 0; + while(!self.isSorted(func)) { + self.shuffle(); + i++; + } + + //show_debug_message("bogosort complete in "+string(i)+" iteration(s)"); + return self; + } + + ///@function concat(other) + ///@description Adds every element of the second array to this array + ///@param {Array/array} other + static concat = function(_other) { + if(!is_Array(_other)) { + if is_array(_other) { + _other = array_to_Array(_other) + } + else { + __throw("TypeError: trying to concat "+typeof(_other)+" with Array"); + return self; + } + } + + for(var i = 0; i < _other.size; i++) { + append(_other.get(i)); + } + + return self; + } + + ///@function copy() + ///@description Returns a copy of the array object + static copy = function() { + ans = new Array(); + + forEach(function(el) { + ans.append(el); + }); + + return ans; + } + + ///@function clear() + ///@description clears an array object + static clear = function() { + content = []; + size = 0; + + return self; + } + + ///@function empty() + ///@description Returns true if the array is empty and false otherwise + static empty = function() { + return size == 0; + } + + ///@function equal(other) + ///@description Returns true if arrays are equal and false otherwise + static equal = function(_other) { + if(!is_Array(_other)) { + __throw( "TypeError: trying to compare "+typeof(_other)+" with Array"); + return false; + } + + if(size != _other.size) + return false; + + for(var i = 0; i < size; i++) { + var c1 = get(i); + var c2 = _other.get(i); + + + if(typeof(c1) != typeof(c2)) + return false; + + + if(is_array(c1) and is_array(c2)) { + if(!array_equals(c1, c2)) + return false; + } + else if(is_Array(c1) and is_Array(c2)) { + if(!c1.equal(c2)) + return false; + } + else if c1 != c2 + return false; + } + + return true; + } + + ///@function exists(value) + ///@description Returns true if the value exists in the array and false otherwise + static exists = function(_val) { + val = _val; + ans = false; + + forEach(function(x, pos) { + if(x == val) { + ans = true; + return 1; //Break out of forEach() + } + }); + + return ans; + } + + ///@function filter(func) + ///@description Loops through the array and passes each value into a function. + /// Returns a new array with only values, that returned true. + /// Function func gets (x, *pos) as input + /// Note: Clean function. Does not affect the original array! + ///@param {function} func + static filter = function(_func) { + func = _func; + ans = new Array(); + + forEach(function(x, pos) { + if(func(x, pos)) + ans.append(x); + }); + + //content = ans.content; + //return self; + return ans; + } + + ///@function find(value) + ///@description finds a value and returns its position. -1 if not found + ///@param {any} value + static find = function(_val) { + val = _val; + ans = -1; + + forEach(function(x, pos) { + if(x == val) { + ans = pos; + return 1; //Break out of forEach() + } + }); + + return ans; + } + + ///@function findAll(value) + ///@description finds all places a value appears and returns an Array with all the positions. empty set if not found + ///@param {any} value + static findAll = function(_val) { + val = _val; + ans = new Array(); + + forEach(function(x, pos) { + if(x == val) + ans.append(pos); + }); + + return ans; + } + + ///@function first() + ///@description Returns the first value of the array + static first = function() { + return get(0); + } + + ///@function forEach(func) + ///@description Loops through the array and runs the function with each element as an argument + /// Function func gets (x, *pos) as arguments + /// Note: Loop will stop immediately if the function returns anything but zero or undefined + ///@param {function} func(x, *pos) + static forEach = function(func) { + for(var i = 0; i < size; i++) { + var res = func(get(i), i) + if(!is_undefined(res) and res != 0) { + break; + } + } + + return self; + } + + ///@function get(pos) + ///@description Returns value at given pos + ///@param {real} pos + static get = function(pos) { + if(pos < 0) + pos += size; //i.e. Array.get(-1) = Array.last() + + if(size == 0) { + __throw( "Error: trying to achieve value from empty Array"); + return undefined; + } + else if(pos < 0 or pos > size-1) { + __throw( "Error: index "+string(pos)+" is out of range [0, "+string(size-1)+"]"); + return undefined; + } + + + return content[pos]; + } + + ///@function getRandom() + ///@description Returns a random element from the array + static getRandom = function() { + var idx = irandom(size-1) + if empty() { + var ans = undefined + } + else { + var ans = get(idx) + } + + return ans + } + + ///@function insert(pos, value) + ///@description inserts a value into the array at given position + ///@param {real} pos + ///@param {any} value + static insert = function(pos, value) { + if(pos < 0) + pos += size; + + if(pos < 0 or (pos > size-1 and size != 0)) { + show_debug_message("Warning: trying to insert a value outside of the array. Use Array.set() or Array.append() instead"); + return set(pos, value); + } + + var part1 = slice(0, pos); + var part2 = slice(pos); + + part1.append(value); + part1.concat(part2); + + content = part1.content; + size++; + + return self; + } + + ///@function isSorted(func) + ///@description checks wether the array is sorted or not. + /// You can provide a function that compares `a` and `b` and returns true if a is "less" + /// default function: (a, b) => { return a < b; } + ///@param {function} func + static isSorted = function(func) { + if is_undefined(func) { + func = function(a, b) { + return a < b; + } + } + + for(var i = 1; i < size; ++i) { + if !func(content[i-1], content[i]) + return false; + } + return true; + } + + ///@function join(separator) + ///@description returns a string, containing all of the array values separated by 'sep' + ///@tip to join part of the array, use array.slice().join() + ///@param {string} separator + ///@param {bool} show_bounds + static join = function(sep, show_bounds) { + if is_undefined(sep) + sep = ", " + if is_undefined(show_bounds) + show_bounds = true + + _sep = sep + + if show_bounds + str = "[" + else + str = "" + + forEach(function(el, i) { + str += string(el) + if(i < size-1) + str += _sep + }) + + if show_bounds + str += "]" + + return str + } + + ///@function lambda(func) + ///@description Loops through the array and applies the function to each element + ///@param {function} func(x, *pos) + static lambda = function(func) { + for(var i = 0; i < size; i++) { + set(i, func(get(i), i) ); + } + + return self; + } + + ///@function last() + ///@description Returns the last value of the array + static last = function() { + return get(-1); + } + + ///@function _max() + ///@description Returns a maximum of the array. Only works with numbers + static _max = function() { + ans = get(0); + + forEach(function(x) { + if(!is_numeric(x)) { + __throw( "TypeError: Trying to calculate maximum of "+typeof(x)+""); + ans = undefined; + return 1 // Break out of forEach() + } + + if(x > ans) + ans = x; + }); + + return ans; + } + + ///@function _min() + ///@description Returns a minimum of the array. Only works with numbers + static _min = function() { + ans = content[0]; + + forEach(function(x) { + if(!is_numeric(x)) { + __throw( "TypeError: Trying to calculate minimum of "+typeof(x)+""); + ans = undefined; + return 1 + } + + if(x < ans) + ans = x; + }); + + return ans; + } + + ///@function merge(other) + ///@description Merges this array with another + static merge = function(_other) { + for(var i = 0; i < _other.size; ++i) { + self.append(_other.get(i)); + } + + return self; + } + + ///@function merged(other) + ///@description like merge() method, but without modifying the original array + static merged = function(_other) { + ans = self.copy(); + _other.forEach(function(item) { + ans.append(item); + }) + + return ans; + } + + ///@function __merge(other) + ///@description an internal function, used for MergeSorting. Not for you to use (unless you know what you're doing) :] + static __merge = function(_other) { + var ans = array_create(size + _other.size); + var i = 0; + var j = 0; + var k = 0; + while(i < size && j < _other.size) { + if self.get(i) < _other.get(j) { + ans[k] = self.get(i); + i++; + } + else { + ans[k] = _other.get(j); + j++; + } + + k++ + } + + while(i < size) { + ans[k] = self.get(i); + i++; + k++; + } + + while(j < _other.size) { + ans[k] = _other.get(j); + j++; + k++; + } + + return ans; + } + + ///@function mergeSort(l, r) + ///@description Sorts the array using merge sort algorithm (pretty fast) + static mergeSort = function(l, r) { + if size == 1 + return self; + + if is_undefined(l) { + l = 0; + } + if is_undefined(r) + r = size; + + // var mid = (size - 1) div 2; + // var left = (slice(0, mid)).mergeSort(); + // var right = (slice(mid+1, size)).mergeSort(); + + var mid = (l + r - 1) div 2; + var left = mergeSort(l, mid); + var right = mergeSort(mid+1, r); + + + show_debug_message("left: "+left.toString()); + show_debug_message("right: "+right.toString()); + + var _merged = left.__merge(right); + + // if (first_time) { + // content = _merged.content; + // size = array_length(content); + // return self; + // } + // else { + return _merged; + // } + } + + ///@function number(value) + ///@description Returns the amount of elements equal to given value in the array + ///@note IMPORTANT! Don't try to use this with data structures, as results may be unpredictable + /// (Use forEach() with your own logic instead) + ///@param {any} value + static number = function(_val) { + val = _val; + ans = 0; + + forEach(function(x, pos) { + if(x == val) + ans++; + }); + + return ans; + } + + ///@function pop() + ///@description removes a value from the end of the array and returns it + static pop = function() { + ans = last(); + if(empty()) { + __throw( "Error: trying to pop value from empty Array"); + return undefined; + } + + remove(-1); + + return ans; + } + + ///@function popBack() + ///@description removes a value from the beginning of the array and returns it + static popBack = function() { + ans = first(); + remove(0); + + return ans; + } + + ///@function push(value, value2, ..) + ///@description Mirrors append() method + ///@param {any} value + static push = function(value) { + for(var i = 0; i < argument_count; ++i) { + var val = argument[i] + content[size] = val; + ++size; + } + + return self; + } + + ///@function pushBack(value) + ///@description inserts a value to the beginning of the array + ///@param {any} value + static pushBack = function(val) { + insert(0, val); + } + + ///@function radixSort() + ///@description sorts the array using radix sort algorythm + static radixSort = function(digits) { + + static getDigit = function(num, digit) { // digit from right to left + repeat(digit) { + num = num div 10; + } + return (num % 10); + } + + for(var digit = 0; digit < digits; ++digit) { + // 0-9 indexies representing each possible digit + var counters = array_create(10, 0); + output = array_create(size, -1); + + for(var i = 0; i < size; ++i) { + var dig = getDigit(content[i], digit); + counters[dig]++; + } + + // sum + for(var i = 1; i < array_length(counters); ++i) { + counters[i] += counters[i - 1]; // get positions + } + + for(var i = size - 1; i >= 0; --i) { + var dig = getDigit(content[i], digit); + var pos = counters[dig]; + + if pos != 0 + pos--; + + while(output[pos] != -1) + pos--; + + output[pos] = content[i]; + } + + array_copy(content, 0, output, 0, array_length(output)); + } + + return self; + } + + ///@function remove(pos) + ///@description removes the value at given position + ///@param {real} pos + static remove = function(pos) { + if(pos < 0) + pos += size; + + if(size == 0) { + __throw("Error: trying to remove value from an empty Array"); + return self; + } + else if(pos < 0 or pos > size - 1) { + __throw( "Error: index "+string(pos)+" is out of range [0, "+string(size-1)+"]"); + return self; + } + + var part1 = slice(0, pos); + var part2 = slice(pos+1); + + part1.concat(part2); + + content = part1.content; + size--; + + return self; + } + + ///@function resize(size) + ///@description resizes the array. Sizing up leads to filling the empty spots with zeros + ///@param {real} size + static resize = function(size) { + if(size < 0) { + __throw( "Error: array size cannot be negative"); + return self; + } + + while(size < size) { + append(0); + } + while(size > size) { + pop(); + } + + return self; + } + + ///@function reverse() + ///@description reverses the array, affecting it + static reverse = function() { + ans = new Array(); + forEach(function(element, pos) { + ans.set(size-pos-1, element); + }); + + content = ans.content; + return self; + } + + ///@function reversed() + ///@description Returns reversed version of the array, without affecting the original + static reversed = function() { + ans = new Array(); + forEach(function(element, pos) { + ans.set(size-pos-1, element); + }); + + return ans; + } + + ///@function set(pos, value) + ///@description sets value in the array at given index + ///@param {real} pos + ///@param {any} item + static set = function(pos, value) { + if(pos < 0) + pos += size; + + if(pos > size-1) + size = pos+1; + + + content[pos] = value; + + return self; + } + + ///@function slice(begin, end) + ///@description Returns a slice from the array with given boundaries. If begin > end - returns reversed version + ///@param {real} begin + ///@param {real} end + static slice = function(_begin, _end) { + if(is_undefined(_begin)) + _begin = 0; + + if(is_undefined(_end)) + _end = size; + + ans = new Array(); + + + if(_begin > _end) { + for(var i = _end; i < _begin; i++) { + ans.pushBack(content[i]); + } + } + else { + for(var i = _begin; i < _end; i++) { + ans.append(content[i]); + } + } + + return ans; + } + + ///@function sort(func, *startpos, *endpos) + ///@description Bubble sorts through the array in given range, comparing values using provided function. + ///Function gets (a, b) as input and must return True if A has more priority than B and False otherwise. + ///@example myarray.sort(function(a, b) { return a > b }) will sort 'myarray' in descending order + ///@param {function} func + ///@param {real} *startpos Default - 0 + ///@param {real} *endpos Default - size + static sort = function(compare, _begin, _end) { + if (is_undefined(compare)) + compare = SORT_ASCENDING; + + if(is_undefined(_begin)) + _begin = 0; + + if(is_undefined(_end)) + _end = size; + + + if(!is_numeric(_begin) or round(_begin) != _begin or !is_numeric(_end) or round(_end) != _end) { + __throw( "TypeError: sort boundaries must be integers"); + return self; + } + + for(var i = _begin; i < _end; i++) { // Bubble sort LUL + for(var j = i; j > _begin; j--) { + if(j > 0 and compare(get(j), get(j-1))) { + swap(j, j-1); + } + } + } + + return self; + } + + #macro SORT_ASCENDING (function(a, b) { return a < b }) + #macro SORT_DESCENDING (function(a, b) { return a > b }) + + + ///@function sorted(func, *startpos, *endpos) + ///@description Mirrors .sort() function, but doesn't affect the original Array + static sorted = function(compare, _begin, _end) { + var ans = copy() // self.copy() + return ans.sort(compare, _begin, _end) + } + + ///@function shuffle() + ///@description shuffles the array (randomly replaces every element) + static shuffle = function() { + // Knuth shuffle implementation + for(var i = size-1; i > 0; --i) { + var j = irandom_range(0, i) + swap(i, j) + } + + + return self + } + + ///@function shuffled() + ///@description clean version of .shuffle() + static shuffled = function() { + var ans = copy(); + return ans.shuffle(); + } + + ///@function sum() + ///@description Returns the sum of all the elements of the array. concats strings. + ///NOTE: Works only with strings or numbars and only if all the elements are the same type. + static sum = function() { + if(is_string(get(0))) + ans = ""; + else if(is_numeric(get(0))) + ans = 0; + else { + __throw( "TypeError: trying to sum up elements, that aren't strings or reals"); + return undefined; + } + + forEach(function(el) { + if(typeof(el) != typeof(ans)) + __throw( "TypeError: Array elements aren't the same type: got "+typeof(el)+", "+typeof(ans)+" expected."); + + ans += el; + }); + + return ans; + } + + ///@function swap(pos1, pos2) + ///@description swaps 2 values at given positions + ///@param {real} pos1 + ///@param {real} pos2 + static swap = function(pos1, pos2) { + var temp = get(pos1); + set(pos1, get(pos2)); + set(pos2, temp); + + return self; + } + + ///@function unique() + ///@description Returns a copy of this Array object, deleting all duplicates + static unique = function() { + ans = new Array(); + + forEach(function(x) { + if(!ans.exists(x)) + ans.append(x); + }); + + return ans; + } + + for(var i = 0; i < argument_count; i++) + append(argument[i]) + + + static toString = function() { + return self.join() + } +} + + +///@function Range(min, max, step) +///@function Range(min, max) +///@function Range(max) +///@description Returns a new Array object, containing numbers in certain range +function Range() : Array() constructor { + + if argument_count > 1 { + var mi = argument[0]; + var ma = argument[1]; + } + else { + var mi = 0; + var ma = argument[0]; + } + + if argument_count > 2 { + var step = argument[2]; + } + else { + var step = 1; + } + + + // Iterate! + if mi < ma // Normal + { + for(var i = mi; i <= ma; i += step) { + append(i); + } + } + else { // Reversed + for(var i = mi; i >= ma; i += step) { + append(i); + } + } + + return self +} + + +///@function Iterator(arr) +///@description Constructs an iterator object to allow easier iteration through Array's +function Iterator(arr) constructor { + self.index = -1; + self.value = undefined; + self.array = arr + + ///@function next() + next = function() { + index++; + try { + value = array.get(index); + } + catch(e) { + value = undefined; + } + + return value; + } + + get = function() { + return value; + } + + + return self; +} + +// Helper functions to convert between data types + +///@function array_to_Array(array) +///@description Returns an instance of Array object with all the contents of an array +///@param {array} array +function array_to_Array(array) { + if(!is_array(array)) { + __throw( "TypeError: expected array, got "+typeof(array)); + return undefined; + } + + ans = new Array(); + + for(var i = 0; i < array_length(array); i++) { + ans.append(array[i]); + } + + return ans; +} + +///@function array_from_Array(Arr) +///@description Mirrors function Array_to_array() +///@param {Array} Arr +function array_from_Array(Arr) { + return Array_to_array(Arr) +} + +///@function ds_list_to_Array(list) +///@description Returns an instance of Array object with all the contents of an array +///@param {real} list +function ds_list_to_Array(list) { + if(!ds_exists(list, ds_type_list)) { + __throw( "Error: ds_list with given index does not exist"); + return undefined; + } + + ans = new Array(); + + for(var i = 0; i < ds_list_size(list); i++) { + ans.append(list[| i]); + } + + return ans; +} + +///@function is_Array(Arr) +///@description Checks if a variable holds reference to an Array object +///@param {any} arr +function is_Array(Arr) { + return is_struct(Arr) and (instanceof(Arr) == "Array" or instanceof(Arr) == "Range"); +} + +///@function Array_to_array(Arr) +///@description Returns contents of an Array object in format of regular array +///@param {Array} Arr +function Array_to_array(Arr) { + if !is_Array(Arr) { + __throw("Error in function Array_to_array(): expected Array(), got "+typeof(Arr)) + return undefined; + } + return Arr.content +} + +///@function ds_list_from_Array(Arr) +///@description Returns contents of an Array object in format of ds_list +///@param {Array} Arr +function ds_list_from_Array(Arr) { + if !is_Array(Arr) { + __throw("Error in function ds_list_from_Array(): expected Array(), got "+typeof(Arr)) + return undefined; + } + + _list = ds_list_create() + Arr.forEach(function(item) { + ds_list_add(_list, item) + }) + return _list +} + +///@function Array_to_ds_list(Arr) +///@description Mirrors function ds_list_from_Array() +///@param {Array} Arr +function Array_to_ds_list(Arr) { + return ds_list_from_Array(Arr) +} + +///@function ds_list_to_array(ds_list) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +// use ds_list_to_Array() for Array Class support +///@param {real} ds_list +function ds_list_to_array(_list) { + var arr = [] + + // ah yes, performance + for(var i = ds_list_size(_list) - 1; i >= 0; --i) { + arr[i] = _list[| i] + } + + return arr +} + +///@function ds_list_from_array(gm_array) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +// use ds_list_from_Array() for Array Class support +///@param {array} arr +function ds_list_from_array(arr) { + var _list = ds_list_create() + + for(var i = array_length(arr) - 1; i >= 0; --i) { + _list[| i] = arr[i] + } + + return _list +} + +///@function array_to_ds_list(gm_array) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +// use ds_list_from_Array() for Array Class support +///@param {array} arr +function array_to_ds_list(arr) { + return ds_list_from_array(arr) +} \ No newline at end of file diff --git a/Sample+Tests/#backups/scripts/SpeedTimer/SpeedTimer.gml.backup0 b/Sample+Tests/#backups/scripts/SpeedTimer/SpeedTimer.gml.backup0 new file mode 100644 index 0000000..53604ca --- /dev/null +++ b/Sample+Tests/#backups/scripts/SpeedTimer/SpeedTimer.gml.backup0 @@ -0,0 +1,29 @@ +// 2020-09-15 09:45:53 +function SpeedTimer() constructor { + start_time = get_timer(); + last_time = start_time; + last_split = undefined; + running = false; + splits = new Array(); + + static startSplit = function() { + running = true; + last_time = get_timer(); + return get_timer(); + } + + static endSplit = function() { + running = false; + var _split = get_timer() - last_time; + splits.append(_split); + + return _split; + } + + static split = function() { + var ans = endSplit(); + startSplit(); + + return ans; + } +} \ No newline at end of file diff --git a/Sample+Tests/#backups/scripts/Tests/Tests.gml.backup0 b/Sample+Tests/#backups/scripts/Tests/Tests.gml.backup0 new file mode 100644 index 0000000..a536410 --- /dev/null +++ b/Sample+Tests/#backups/scripts/Tests/Tests.gml.backup0 @@ -0,0 +1,307 @@ +// 2020-09-15 10:41:53 +// +// +///@description check out ArrayClass.gml for docs + +randomize(); + + +function __Array_test() { + show_debug_message("#### STARTING TESTS ####") + + + // Creating + var array = new Array(0) + + + // Use these if you have fps issues due to garbage collection + // v F1 or Middle Click v + //gc_enable(false) + //gc_collect() + + + // Adding new stuff + array.append(1, 2, 3) + show_debug_message(array) + + + // the most useful function + show_debug_message("#### FOREACH ####") + array.forEach(function(num, pos) { + if num == 3 { + show_debug_message(string(pos) + ") " + string(num) + " is for suckers") + return 1 + // break out of forEach() + } + + if num % 2 == 0 { + show_debug_message(string(pos) + ") " + string(num) + " (even)") + } + else { + show_debug_message(string(pos) + ") " + string(num) + " (odd)") + } + + + // Please don't delete stuff inside .forEach(), use .filter() instead + }) + show_debug_message(array) + + + + // Concatenating regular arrays + show_debug_message("#### CONCAT ####") + array.concat(["string", 1, -pi]) + show_debug_message(array) + + + + // Chaining methods + show_debug_message("#### CHAINING METHODS ####") + + array = new Array(1, "string", pi) + + array = array.insert(0, "first") + .insert(1, "second") + .append("last", "last2") + show_debug_message(array) + + + + // Careful: some methods don't return the array + show_debug_message("#### CHAINING METHODS 2 ####") + var m = array.clear() + //.concat(new Range(1, 4, 1)) + //.concat(new Range(3, 1, -1)) + .append(1, 2, 3, 4) + .append(3, 2, 1) + ._max() + + //.add(1) would throw an error, as it would apply .add() to a number + show_debug_message(array) + show_debug_message(m) + + + + + // getting/setting + show_debug_message("#### GET/SET ####") + var first = array.get(0) + var second = array.get(1) + var last = array.get(array.size-1) + show_debug_message(array) + show_debug_message("First: "+string(first)) + show_debug_message("Second: "+string(second)) + show_debug_message("Last: "+string(last)) + + array.set(0, "first") + array.set(1, "second") + array.set(array.size-1, "last") + show_debug_message(array) + + + + // Modifying contents by hand + show_debug_message("#### MANUAL MODIFYING ####") + array.content = [4, 2, 1, 3, 8, 7, 6, 5] + // Note that size will not automatically update this way + array.size = 8 + show_debug_message(array) + + + + + // Swap + show_debug_message("#### SWAP ####") + array.swap(0, array.size-1) + show_debug_message(array) + + + + + // Slice + show_debug_message("#### SLICE ####") + var array_slice = array.slice(0, 4) + show_debug_message("Sliced 0-4. Result: "+string(array_slice)) + + + // Joining + show_debug_message("#### PRINTING (JOINING) ####") + show_debug_message(array.join("|")) + + + // sorting (slow, don't do every frame) + show_debug_message("#### SORTING ####") + + var t = new SpeedTimer(); + + array.sort(function(a, b) { + return a > b // Descending + }, 0, 4) // from 0 to 3 + + array.sort(function(a, b) { + return a < b // Ascending + }, 4) // from 4 to end + + show_debug_message(array) + + + + // .sorted() and .reversed(), as well as .filter() don't modify the original array + show_debug_message("#### CLEAN FUNCTIONS ####") + var myarray = array.sorted(SORT_ASCENDING, 0, array.size).reversed() + show_debug_message(myarray) + show_debug_message(array) + + + + + // Useful to delete several elements based on some parameter + show_debug_message("#### FILTER ####") + array = array.filter(function(num) { + return num % 2 == 0 + }).concat(array.copy()) // Repeat the array. Note how the copy still has the odd numbers + show_debug_message(array) + + + + + // find() / findAll() + show_debug_message("#### SEARCHING ####") + var idx = array.find(2) + show_debug_message("First 2 is found at "+string(idx)) + + var arr = array.findAll(2) + // yep, you can string() arrays! + show_debug_message("All 2's positions: " + string(arr)) + var num = array.number(2) + show_debug_message("Total amount of 2's: " + string(num)) + + var uniq = array.unique() // like array but without duplicates + var num = uniq.number(2) + show_debug_message("Total amount of 2's: " + string(num)) + + + + + // adding up the whole array + show_debug_message("#### ADDING UP ####") + var sum = array.sum() + show_debug_message(sum) + + // Strings are summable too + array = array.clear().append("Hello", ", ", "World", "!") + show_debug_message(array.sum()) + + + + + // shuffle! + show_debug_message("#### SHUFFLING ####") + array = new Array(1, 2, 3, 4, 5, 6, 7, 8) // array.clear().append() is the most stupid thing you could ever do... + show_debug_message(array.shuffled()) + array.shuffle() + show_debug_message(array) + + + + + // iterators + show_debug_message("#### ITERATORS (EXPERIMENTAL) ####") + + var iter = new Iterator(array) + while !is_undefined(iter.next()) { + var it = iter.get() + show_debug_message("Current iteration: "+string(it)) + } + + + // convertation + show_debug_message("#### CONVERSION ####") + + var arr = ["Lowercase", "a"] + var Arr = new Array("Uppercase", "A") + + var list = ds_list_create() + ds_list_add(list, "ds", "list") + + + var a_to_A = array_to_Array(arr) + var a_to_l = array_to_ds_list(arr) + var A_to_a = Array_to_array(Arr) + var A_to_l = Array_to_ds_list(Arr) + var l_to_a = ds_list_to_array(list) + var l_to_A = ds_list_to_Array(list) + + show_debug_message("From regular array:") + show_debug_message(a_to_A) + show_debug_message(a_to_l) + + show_debug_message("From Array Class:") + show_debug_message(A_to_a) + show_debug_message(A_to_l) + + show_debug_message("From ds_list:") + show_debug_message(l_to_a) + show_debug_message(l_to_A) + + + ds_list_destroy(a_to_l) + ds_list_destroy(A_to_l) + + + // DIFFERENT SORTING ALGORITHMS + var t = new SpeedTimer(); + + // generate dataset + var array = new Array(); + repeat(15) { + array.append(irandom(1000)); + } + + // radix sort + show_debug_message("#### RADIX SORT ####"); + + var arr = array.copy(); + + var time = string(t.split()); + show_debug_message("Array allocated in: "+time); + + show_debug_message(arr.radixSort(4)); + + var time = string(t.split()); + show_debug_message("RadixSorted in: "+time); + + // bogosort OMEGALUL +// show_debug_message("#### BOGOSORT (OMG) ####"); + +// var arr = new Array(3812, 5, 604, 69, 31123, -123456, 1337, .56789, 404); +// var time = string(t.split()); +// show_debug_message("Array allocated in: "+time); + +// show_debug_message(arr.bogosort()); + +// var time = string(t.split()); +// show_debug_message("BogoSorted in: "+time+"("+string(time / 1000000)+"s)"); + + + // merge sort +// var arr = array.copy(); +// var time = string(t.split()); +// show_debug_message("Array allocated in: "+time); + +// show_debug_message(arr.mergeSort()); + +// var time = string(t.split()); +// show_debug_message("MergeSorted in: "+time); + + + // bubble sort + var arr = array.copy(); + var time = string(t.split()); + show_debug_message("Array allocated in: "+time); + + show_debug_message(arr.sort()); + + var time = string(t.split()); + show_debug_message("BubbleSorted in: "+time); +} \ No newline at end of file diff --git a/Sample+Tests/#config/properties.json b/Sample+Tests/#config/properties.json new file mode 100644 index 0000000..0d1b749 --- /dev/null +++ b/Sample+Tests/#config/properties.json @@ -0,0 +1,6 @@ +{ + "indentWithTabs": true, + "linterPrefs": { + + } +} \ No newline at end of file diff --git a/Sample+Tests/ArrayClass.yyp b/Sample+Tests/ArrayClass.yyp index dbb0537..fbe68d3 100644 --- a/Sample+Tests/ArrayClass.yyp +++ b/Sample+Tests/ArrayClass.yyp @@ -1,8 +1,9 @@ { "resources": [ {"id":{"name":"oMain","path":"objects/oMain/oMain.yy",},"order":0,}, - {"id":{"name":"Tests","path":"scripts/Tests/Tests.yy",},"order":1,}, - {"id":{"name":"ArrayClass","path":"scripts/ArrayClass/ArrayClass.yy",},"order":0,}, + {"id":{"name":"ArrayClass","path":"scripts/ArrayClass/ArrayClass.yy",},"order":3,}, + {"id":{"name":"Tests","path":"scripts/Tests/Tests.yy",},"order":0,}, + {"id":{"name":"SpeedTimer","path":"scripts/SpeedTimer/SpeedTimer.yy",},"order":1,}, {"id":{"name":"Room1","path":"rooms/Room1/Room1.yy",},"order":0,}, ], "Options": [ @@ -11,6 +12,10 @@ {"name":"macOS","path":"options/mac/options_mac.yy",}, {"name":"Main","path":"options/main/options_main.yy",}, {"name":"Windows","path":"options/windows/options_windows.yy",}, + {"name":"Amazon Fire","path":"options/amazonfire/options_amazonfire.yy",}, + {"name":"Android","path":"options/android/options_android.yy",}, + {"name":"iOS","path":"options/ios/options_ios.yy",}, + {"name":"tvOS","path":"options/tvos/options_tvos.yy",}, ], "isDnDProject": false, "isEcma": false, @@ -19,8 +24,8 @@ "name": "Default", "children": [], }, - "RoomOrder": [ - {"name":"Room1","path":"rooms/Room1/Room1.yy",}, + "RoomOrderNodes": [ + {"roomId":{"name":"Room1","path":"rooms/Room1/Room1.yy",},}, ], "Folders": [ {"folderPath":"folders/Scripts.yy","order":5,"resourceVersion":"1.0","name":"Scripts","tags":[],"resourceType":"GMFolder",}, @@ -28,10 +33,10 @@ {"folderPath":"folders/Rooms.yy","order":10,"resourceVersion":"1.0","name":"Rooms","tags":[],"resourceType":"GMFolder",}, ], "AudioGroups": [ - {"targets":461609314234257646,"resourceVersion":"1.0","name":"audiogroup_default","resourceType":"GMAudioGroup",}, + {"targets":-1,"resourceVersion":"1.3","name":"audiogroup_default","resourceType":"GMAudioGroup",}, ], "TextureGroups": [ - {"isScaled":true,"autocrop":true,"border":2,"mipsToGenerate":0,"targets":461609314234257646,"resourceVersion":"1.0","name":"Default","resourceType":"GMTextureGroup",}, + {"isScaled":true,"autocrop":true,"border":2,"mipsToGenerate":0,"groupParent":null,"targets":-1,"resourceVersion":"1.3","name":"Default","resourceType":"GMTextureGroup",}, ], "IncludedFiles": [ {"CopyToMask":0,"filePath":"datafiles/GMLive","resourceVersion":"1.0","name":"gcmt-dll.dll","resourceType":"GMIncludedFile",}, @@ -50,9 +55,9 @@ {"CopyToMask":-1,"filePath":"datafiles/GMLive","resourceVersion":"1.0","name":"gmlive-server.n","resourceType":"GMIncludedFile",}, ], "MetaData": { - "IDEVersion": "2.3.0.529", + "IDEVersion": "2.3.1.542", }, - "resourceVersion": "1.3", + "resourceVersion": "1.4", "name": "ArrayClass", "tags": [], "resourceType": "GMProject", diff --git a/Sample+Tests/options/amazonfire/options_amazonfire.yy b/Sample+Tests/options/amazonfire/options_amazonfire.yy new file mode 100644 index 0000000..c4b6d7d --- /dev/null +++ b/Sample+Tests/options/amazonfire/options_amazonfire.yy @@ -0,0 +1,49 @@ +{ + "option_amazonfire_sync_android": false, + "option_amazonfire_display_name": "Created with GameMaker Studio 2", + "option_amazonfire_version": "1.0.0.0", + "option_amazonfire_tools_from_version": false, + "option_amazonfire_build_tools": "", + "option_amazonfire_support_lib": "", + "option_amazonfire_target_sdk": "", + "option_amazonfire_minimum_sdk": "", + "option_amazonfire_compile_sdk": "", + "option_amazonfire_package_domain": "com", + "option_amazonfire_package_company": "company", + "option_amazonfire_package_product": "game", + "option_amazonfire_orient_portrait": true, + "option_amazonfire_orient_portrait_flipped": true, + "option_amazonfire_orient_landscape": true, + "option_amazonfire_orient_landscape_flipped": true, + "option_amazonfire_gamepad_support": true, + "option_amazonfire_lint": false, + "option_amazonfire_install_location": 0, + "option_amazonfire_sleep_margin": 4, + "option_amazonfire_splash_screens_landscape": "${base_options_dir}/amazonfire/splash/landscape.png", + "option_amazonfire_splash_screens_portrait": "${base_options_dir}/amazonfire/splash/portrait.png", + "option_amazonfire_splash_time": 0, + "option_amazonfire_launchscreen_fill": 0, + "option_amazonfire_splashscreen_background_colour": 255, + "option_amazonfire_tv_banner": "${base_options_dir}/amazonfire/tv_banner.png", + "option_amazonfire_interpolate_pixels": false, + "option_amazonfire_screen_depth": 0, + "option_amazonfire_scale": 0, + "option_amazonfire_texture_page": "2048x2048", + "option_amazonfire_icon_ldpi": "${base_options_dir}/android/icons/ldpi.png", + "option_amazonfire_icon_mdpi": "${base_options_dir}/android/icons/mdpi.png", + "option_amazonfire_icon_hdpi": "${base_options_dir}/android/icons/hdpi.png", + "option_amazonfire_icon_xhdpi": "${base_options_dir}/android/icons/xhdpi.png", + "option_amazonfire_icon_xxhdpi": "${base_options_dir}/android/icons/xxhdpi.png", + "option_amazonfire_icon_xxxhdpi": "${base_options_dir}/android/icons/xxxhdpi.png", + "option_amazonfire_permission_write_external_storage": false, + "option_amazonfire_permission_read_phone_state": false, + "option_amazonfire_permission_network_state": false, + "option_amazonfire_permission_internet": true, + "option_amazonfire_permission_bluetooth": true, + "option_amazonfire_permission_record_audio": false, + "option_amazonfire_application_tag_inject": "", + "resourceVersion": "1.0", + "name": "Amazon Fire", + "tags": [], + "resourceType": "GMAmazonFireOptions", +} \ No newline at end of file diff --git a/Sample+Tests/options/android/options_android.yy b/Sample+Tests/options/android/options_android.yy new file mode 100644 index 0000000..328f326 --- /dev/null +++ b/Sample+Tests/options/android/options_android.yy @@ -0,0 +1,76 @@ +{ + "option_android_sync_amazon": false, + "option_android_display_name": "Created with GameMaker Studio 2", + "option_android_version": "1.0.0.0", + "option_android_tools_from_version": false, + "option_android_build_tools": "", + "option_android_support_lib": "", + "option_android_target_sdk": "", + "option_android_minimum_sdk": "", + "option_android_compile_sdk": "", + "option_android_package_domain": "com", + "option_android_package_company": "company", + "option_android_package_product": "game", + "option_android_arch_armv7": true, + "option_android_arch_x86": false, + "option_android_arch_arm64": false, + "option_android_arch_x86_64": false, + "option_android_orient_portrait": true, + "option_android_orient_portrait_flipped": true, + "option_android_orient_landscape": true, + "option_android_orient_landscape_flipped": true, + "option_android_gamepad_support": true, + "option_android_lint": false, + "option_android_install_location": 0, + "option_android_sleep_margin": 4, + "option_android_splash_screens_landscape": "${base_options_dir}/android/splash/landscape.png", + "option_android_splash_screens_portrait": "${base_options_dir}/android/splash/portrait.png", + "option_android_splash_time": 0, + "option_android_launchscreen_fill": 0, + "option_android_splashscreen_background_colour": 255, + "option_android_tv_banner": "${base_options_dir}/android/tv_banner.png", + "option_android_interpolate_pixels": false, + "option_android_screen_depth": 0, + "option_android_device_support": 0, + "option_android_scale": 0, + "option_android_texture_page": "2048x2048", + "option_android_icon_ldpi": "${base_options_dir}/android/icons/ldpi.png", + "option_android_icon_mdpi": "${base_options_dir}/android/icons/mdpi.png", + "option_android_icon_hdpi": "${base_options_dir}/android/icons/hdpi.png", + "option_android_icon_xhdpi": "${base_options_dir}/android/icons/xhdpi.png", + "option_android_icon_xxhdpi": "${base_options_dir}/android/icons/xxhdpi.png", + "option_android_icon_xxxhdpi": "${base_options_dir}/android/icons/xxxhdpi.png", + "option_android_icon_adaptive_generate": false, + "option_android_icon_adaptive_ldpi": "${base_options_dir}/android/icons_adaptive/ldpi.png", + "option_android_icon_adaptive_mdpi": "${base_options_dir}/android/icons_adaptive/mdpi.png", + "option_android_icon_adaptive_hdpi": "${base_options_dir}/android/icons_adaptive/hdpi.png", + "option_android_icon_adaptive_xhdpi": "${base_options_dir}/android/icons_adaptive/xhdpi.png", + "option_android_icon_adaptive_xxhdpi": "${base_options_dir}/android/icons_adaptive/xxhdpi.png", + "option_android_icon_adaptive_xxxhdpi": "${base_options_dir}/android/icons_adaptive/xxxhdpi.png", + "option_android_icon_adaptivebg_ldpi": "${base_options_dir}/android/icons_adaptivebg/ldpi.png", + "option_android_icon_adaptivebg_mdpi": "${base_options_dir}/android/icons_adaptivebg/mdpi.png", + "option_android_icon_adaptivebg_hdpi": "${base_options_dir}/android/icons_adaptivebg/hdpi.png", + "option_android_icon_adaptivebg_xhdpi": "${base_options_dir}/android/icons_adaptivebg/xhdpi.png", + "option_android_icon_adaptivebg_xxhdpi": "${base_options_dir}/android/icons_adaptivebg/xxhdpi.png", + "option_android_icon_adaptivebg_xxxhdpi": "${base_options_dir}/android/icons_adaptivebg/xxxhdpi.png", + "option_android_use_facebook": false, + "option_android_facebook_id": "", + "option_android_facebook_app_display_name": "", + "option_android_google_cloud_saving": false, + "option_android_google_services_app_id": "", + "option_android_permission_write_external_storage": false, + "option_android_permission_read_phone_state": false, + "option_android_permission_network_state": false, + "option_android_permission_internet": true, + "option_android_permission_bluetooth": true, + "option_android_permission_record_audio": false, + "option_android_application_tag_inject": "", + "option_android_google_apk_expansion": false, + "option_android_google_dynamic_asset_delivery": false, + "option_android_google_licensing_public_key": "", + "option_android_tv_isgame": true, + "resourceVersion": "1.0", + "name": "Android", + "tags": [], + "resourceType": "GMAndroidOptions", +} \ No newline at end of file diff --git a/Sample+Tests/options/ios/options_ios.yy b/Sample+Tests/options/ios/options_ios.yy new file mode 100644 index 0000000..1498dc4 --- /dev/null +++ b/Sample+Tests/options/ios/options_ios.yy @@ -0,0 +1,50 @@ +{ + "option_ios_display_name": "Created with GameMaker Studio 2", + "option_ios_bundle_name": "com.company.game", + "option_ios_version": "1.0.0.0", + "option_ios_output_dir": "~/gamemakerstudio2", + "option_ios_team_id": "", + "option_ios_orientation_portrait": true, + "option_ios_orientation_portrait_flipped": true, + "option_ios_orientation_landscape": true, + "option_ios_orientation_landscape_flipped": true, + "option_ios_devices": 2, + "option_ios_defer_home_indicator": false, + "option_ios_icon_iphone_app_120": "${base_options_dir}/ios/icons/app/iphone_120.png", + "option_ios_icon_iphone_app_180": "${base_options_dir}/ios/icons/app/iphone_180.png", + "option_ios_icon_ipad_app_76": "${base_options_dir}/ios/icons/app/ipad_76.png", + "option_ios_icon_ipad_app_152": "${base_options_dir}/ios/icons/app/ipad_152.png", + "option_ios_icon_ipad_pro_app_167": "${base_options_dir}/ios/icons/app/ipad_pro_167.png", + "option_ios_icon_iphone_notification_40": "${base_options_dir}/ios/icons/notification/iphone_40.png", + "option_ios_icon_iphone_notification_60": "${base_options_dir}/ios/icons/notification/iphone_60.png", + "option_ios_icon_ipad_notification_20": "${base_options_dir}/ios/icons/notification/ipad_20.png", + "option_ios_icon_ipad_notification_40": "${base_options_dir}/ios/icons/notification/ipad_40.png", + "option_ios_icon_iphone_spotlight_80": "${base_options_dir}/ios/icons/spotlight/iphone_80.png", + "option_ios_icon_iphone_spotlight_120": "${base_options_dir}/ios/icons/spotlight/iphone_120.png", + "option_ios_icon_ipad_spotlight_40": "${base_options_dir}/ios/icons/spotlight/ipad_40.png", + "option_ios_icon_ipad_spotlight_80": "${base_options_dir}/ios/icons/spotlight/ipad_80.png", + "option_ios_icon_iphone_settings_58": "${base_options_dir}/ios/icons/settings/iphone_58.png", + "option_ios_icon_iphone_settings_87": "${base_options_dir}/ios/icons/settings/iphone_87.png", + "option_ios_icon_ipad_settings_29": "${base_options_dir}/ios/icons/settings/ipad_29.png", + "option_ios_icon_ipad_settings_58": "${base_options_dir}/ios/icons/settings/ipad_58.png", + "option_ios_icon_itunes_artwork_1024": "${base_options_dir}/ios/icons/itunes/itunes_1024.png", + "option_ios_splashscreen_background_colour": 255, + "option_ios_launchscreen_image": "${base_options_dir}/ios/splash/launchscreen.png", + "option_ios_launchscreen_image_landscape": "${base_options_dir}/ios/splash/launchscreen-landscape.png", + "option_ios_launchscreen_fill": 0, + "option_ios_interpolate_pixels": false, + "option_ios_half_ipad1_textures": false, + "option_ios_scale": 0, + "option_ios_texture_page": "2048x2048", + "option_ios_use_facebook": false, + "option_ios_facebook_id": "", + "option_ios_facebook_app_display_name": "", + "option_ios_push_notifications": false, + "option_ios_apple_sign_in": false, + "option_ios_podfile_path": "${options_dir}/ios/Podfile", + "option_ios_podfile_lock_path": "${options_dir}/ios/Podfile.lock", + "resourceVersion": "1.3", + "name": "iOS", + "tags": [], + "resourceType": "GMiOSOptions", +} \ No newline at end of file diff --git a/Sample+Tests/options/tvos/options_tvos.yy b/Sample+Tests/options/tvos/options_tvos.yy new file mode 100644 index 0000000..5ee2c44 --- /dev/null +++ b/Sample+Tests/options/tvos/options_tvos.yy @@ -0,0 +1,29 @@ +{ + "option_tvos_display_name": "Made in GameMaker Studio 2", + "option_tvos_bundle_name": "com.company.game", + "option_tvos_version": "1.0.0.0", + "option_tvos_output_dir": "~/GameMakerStudio2/tvOS", + "option_tvos_team_id": "", + "option_tvos_icon_400": "${base_options_dir}/tvos/icons/400.png", + "option_tvos_icon_400_2x": "${base_options_dir}/tvos/icons/400_2x.png", + "option_tvos_icon_1280": "${base_options_dir}/tvos/icons/1280.png", + "option_tvos_topshelf": "${base_options_dir}/tvos/topshelf/topshelf.png", + "option_tvos_topshelf_2x": "${base_options_dir}/tvos/topshelf/topshelf_2x.png", + "option_tvos_topshelf_wide": "${base_options_dir}/tvos/topshelf/topshelf_wide.png", + "option_tvos_topshelf_wide_2x": "${base_options_dir}/tvos/topshelf/topshelf_wide_2x.png", + "option_tvos_splashscreen": "${base_options_dir}/tvos/splash/splash.png", + "option_tvos_splashscreen_2x": "${base_options_dir}/tvos/splash/splash_2x.png", + "option_tvos_splash_time": 0, + "option_tvos_interpolate_pixels": true, + "option_tvos_scale": 0, + "option_tvos_texture_page": "2048x2048", + "option_tvos_display_cursor": false, + "option_tvos_push_notifications": false, + "option_tvos_apple_sign_in": false, + "option_tvos_podfile_path": "${options_dir}\\tvos\\Podfile", + "option_tvos_podfile_lock_path": "${options_dir}\\tvos\\Podfile.lock", + "resourceVersion": "1.3", + "name": "tvOS", + "tags": [], + "resourceType": "GMtvOSOptions", +} \ No newline at end of file diff --git a/Sample+Tests/options/windows/options_windows.yy b/Sample+Tests/options/windows/options_windows.yy index 7fb7dad..44cc31c 100644 --- a/Sample+Tests/options/windows/options_windows.yy +++ b/Sample+Tests/options/windows/options_windows.yy @@ -7,9 +7,9 @@ "option_windows_copyright_info": "", "option_windows_description_info": "A GameMaker Studio 2 Game", "option_windows_display_cursor": true, - "option_windows_icon": "${base_options_dir}\\windows\\icons\\icon.ico", + "option_windows_icon": "${base_options_dir}/windows/icons/icon.ico", "option_windows_save_location": 0, - "option_windows_splash_screen": "${base_options_dir}\\windows\\splash\\splash.png", + "option_windows_splash_screen": "${base_options_dir}/windows/splash/splash.png", "option_windows_use_splash": false, "option_windows_start_fullscreen": false, "option_windows_allow_fullscreen_switching": false, @@ -21,14 +21,15 @@ "option_windows_copy_exe_to_dest": false, "option_windows_sleep_margin": 10, "option_windows_texture_page": "2048x2048", - "option_windows_installer_finished": "${base_options_dir}\\windows\\installer\\finished.bmp", - "option_windows_installer_header": "${base_options_dir}\\windows\\installer\\header.bmp", - "option_windows_license": "${base_options_dir}\\windows\\installer\\license.txt", - "option_windows_nsis_file": "${base_options_dir}\\windows\\installer\\nsis_script.nsi", + "option_windows_installer_finished": "${base_options_dir}/windows/installer/finished.bmp", + "option_windows_installer_header": "${base_options_dir}/windows/installer/header.bmp", + "option_windows_license": "${base_options_dir}/windows/installer/license.txt", + "option_windows_nsis_file": "${base_options_dir}/windows/installer/nsis_script.nsi", "option_windows_enable_steam": false, "option_windows_disable_sandbox": false, "option_windows_steam_use_alternative_launcher": false, - "resourceVersion": "1.0", + "option_windows_use_x64": false, + "resourceVersion": "1.1", "name": "Windows", "tags": [], "resourceType": "GMWindowsOptions", diff --git a/Sample+Tests/scripts/ArrayClass/ArrayClass.gml b/Sample+Tests/scripts/ArrayClass/ArrayClass.gml index af55f8c..504460a 100644 --- a/Sample+Tests/scripts/ArrayClass/ArrayClass.gml +++ b/Sample+Tests/scripts/ArrayClass/ArrayClass.gml @@ -4,6 +4,8 @@ // See type-conversion API at the bottom of this file +globalvar ARRAY_LOOP; // edit this inside forEach, filter, etc. to exit a loop +ARRAY_LOOP = 1; ///@function Array(*item1, *item2, ...) ///@description Constructor funcion for Array objects @@ -18,13 +20,16 @@ function Array() constructor { #macro ARRAY_SHOW_WARNING true - __throw = function(err) { + static __throw = function(err) { if ARRAY_SHOW_ERROR { throw err; } else if ARRAY_SHOW_WARNING { show_debug_message("Array error: "+string(err)) } + else { + // nothing + } } ///@function append(value, value2, ..) @@ -53,6 +58,19 @@ function Array() constructor { return self; } + ///@function bogosort() + ///@description This is just a funny meme, please don't use this in actual projects + static bogosort = function(func) { + var i = 0; + while(!self.isSorted(func)) { + self.shuffle(); + i++; + } + + //show_debug_message("bogosort complete in "+string(i)+" iteration(s)"); + return self; + } + ///@function concat(other) ///@description Adds every element of the second array to this array ///@param {Array/array} other @@ -77,11 +95,12 @@ function Array() constructor { ///@function copy() ///@description Returns a copy of the array object static copy = function() { - ans = new Array(); + var ans = new Array(); - forEach(function(el) { - ans.append(el); - }); + for(var i = 0; i < size; ++i) { + var el = get(i); + ans.push(el); + } return ans; } @@ -95,33 +114,6 @@ function Array() constructor { return self; } - ///@function remove(pos) - ///@description removes the value at given position - ///@param {real} pos - static remove = function(pos) { - if(pos < 0) - pos += size; - - if(size == 0) { - __throw("Error: trying to remove value from an empty Array"); - return self; - } - else if(pos < 0 or pos > size - 1) { - __throw( "Error: index "+string(pos)+" is out of range [0, "+string(size-1)+"]"); - return self; - } - - var part1 = slice(0, pos); - var part2 = slice(pos+1); - - part1.concat(part2); - - content = part1.content; - size--; - - return self; - } - ///@function empty() ///@description Returns true if the array is empty and false otherwise static empty = function() { @@ -165,38 +157,39 @@ function Array() constructor { ///@function exists(value) ///@description Returns true if the value exists in the array and false otherwise - static exists = function(_val) { - val = _val; - ans = false; - - forEach(function(x, pos) { - if(x == val) { + static exists = function(val) { + var ans = false; + for(var i = 0; i < size; ++i) { + if (get(i) == val) { ans = true; - return 1; //Break out of forEach() + break; } - }); + } return ans; } ///@function filter(func) ///@description Loops through the array and passes each value into a function. - /// Returns a new array with only values, that returned true. + /// Filters the array to only include values, that returned true. /// Function func gets (x, *pos) as input - /// Note: Clean function. Does not affect the original array! ///@param {function} func static filter = function(_func) { func = _func; - ans = new Array(); + var ans = new Array(); - forEach(function(x, pos) { - if(func(x, pos)) - ans.append(x); - }); + ARRAY_LOOP = true; + for(var i = 0; i < size; ++i) { + if(func(get(i), i)) + ans.append(get(i)); + + if (!ARRAY_LOOP) + break; + } - //content = ans.content; - //return self; - return ans; + content = ans.content; + size = ans.size; + return self; } ///@function find(value) @@ -204,14 +197,14 @@ function Array() constructor { ///@param {any} value static find = function(_val) { val = _val; - ans = -1; + var ans = -1; - forEach(function(x, pos) { + ans = findAnswer(function(x, pos, ans) { if(x == val) { - ans = pos; - return 1; //Break out of forEach() + ARRAY_LOOP = 0; + return pos; } - }); + }, ans); return ans; } @@ -219,17 +212,55 @@ function Array() constructor { ///@function findAll(value) ///@description finds all places a value appears and returns an Array with all the positions. empty set if not found ///@param {any} value - static findAll = function(_val) { - val = _val; - ans = new Array(); + static findAll = function(val) { + var ans = new Array(); - forEach(function(x, pos) { - if(x == val) + ans = findAnswer(function(x, pos, struct) { + var val = struct.val; + var ans = struct.ans; + + if(x == val) { ans.append(pos); - }); + } + + if (pos == size-1) { + ARRAY_LOOP = false; + return ans; + } + else { + return {ans: ans, val: val} + } + }, {ans: ans, val: val}); + + return ans; + } + + ///@function findAnswer(func, def_ans) + ///@description loops over the Array and returns the value when your function sets ARRAY_LOOP to `false` + /// works not too unlike forEach(), but uses function format `foo(val, idx, ans)`, on first iteration ans = undefined + /// alternatively you can provide a default answer, that gets passed into the first iteration + /// basically this is a customized find() function, that can return anything you want + ///@note + /// Note: Loop will stop immediately if you set ARRAY_LOOP globalvar to 0 + ///@param {function} func + ///@param {any} def_ans + static findAnswer = function(func, ans) { + if (argument_count < 2) + ans = undefined; + + ARRAY_LOOP = true; + + for(var i = 0; i < size; ++i) { + ans = func(get(i), i, ans); + if (!ARRAY_LOOP) { + break; + } + } return ans; } + + static findCustom = findAnswer; ///@function first() ///@description Returns the first value of the array @@ -239,13 +270,16 @@ function Array() constructor { ///@function forEach(func) ///@description Loops through the array and runs the function with each element as an argument - /// Function func gets (x, *pos) as arguments - /// Note: Loop will stop immediately if the function returns anything but zero or undefined - ///@param {function} func(x, *pos) + /// Function format is `foo(val, *pos)` (function takes value and position as arguments) + /// Note: Loop will stop immediately if you set ARRAY_LOOP globalvar to 0 + ///@param {function} func static forEach = function(func) { + ARRAY_LOOP = true; + for(var i = 0; i < size; i++) { - var res = func(get(i), i) - if(!is_undefined(res) and res != 0) { + //var res = + func(get(i), i) + if(!ARRAY_LOOP) { break; } } @@ -273,6 +307,20 @@ function Array() constructor { return content[pos]; } + ///@function getRandom() + ///@description Returns a random element from the array + static getRandom = function() { + var idx = irandom(size-1) + if empty() { + var ans = undefined + } + else { + var ans = get(idx) + } + + return ans + } + ///@function insert(pos, value) ///@description inserts a value into the array at given position ///@param {real} pos @@ -298,6 +346,26 @@ function Array() constructor { return self; } + ///@function isSorted(func) + ///@description checks wether the array is sorted or not. + /// You can provide a function that compares `a` and `b` and returns true if a is "less" + /// default function: (a, b) => { return a < b; } + ///@param {function} func + static isSorted = function(func) { + if is_undefined(func) { + //func = function(a, b) { + // return a < b; + //} + func = SORT_ASCENDING + } + + for(var i = 1; i < size; ++i) { + if !func(content[i-1], content[i]) + return false; + } + return true; + } + ///@function join(separator) ///@description returns a string, containing all of the array values separated by 'sep' ///@tip to join part of the array, use array.slice().join() @@ -331,9 +399,14 @@ function Array() constructor { ///@function lambda(func) ///@description Loops through the array and applies the function to each element ///@param {function} func(x, *pos) + /// Note: Loop will stop immediately if you set ARRAY_LOOP globalvar to 0 static lambda = function(func) { + ARRAY_LOOP = true; + for(var i = 0; i < size; i++) { - set(i, func(get(i), i) ); + set(i, func(get(i),i) ); + if(!ARRAY_LOOP) + break; } return self; @@ -348,18 +421,17 @@ function Array() constructor { ///@function _max() ///@description Returns a maximum of the array. Only works with numbers static _max = function() { - ans = get(0); + var ans = get(0); - forEach(function(x) { + ans = findAnswer(function(x, ans) { if(!is_numeric(x)) { __throw( "TypeError: Trying to calculate maximum of "+typeof(x)+""); - ans = undefined; - return 1 // Break out of forEach() + return undefined; // Break out of the loop } if(x > ans) - ans = x; - }); + return x; + }, ans); return ans; } @@ -367,22 +439,123 @@ function Array() constructor { ///@function _min() ///@description Returns a minimum of the array. Only works with numbers static _min = function() { - ans = content[0]; + var ans = get(0); - forEach(function(x) { + forEach(function(x, ans) { if(!is_numeric(x)) { __throw( "TypeError: Trying to calculate minimum of "+typeof(x)+""); - ans = undefined; - return 1 + ARRAY_LOOP = false; + return undefined; } if(x < ans) - ans = x; - }); + return x; + }, ans); return ans; } + ///@function merge(other) + ///@description Merges this array with another + static merge = function(_other) { + for(var i = 0; i < _other.size; ++i) { + self.append(_other.get(i)); + } + + return self; + } + + ///@function merged(other) + ///@description like merge() method, but without modifying the original array + static merged = function(_other) { + var ans = self.copy(); + _other.forEach(function(item) { + ans.append(item); + }) + + return ans; + } + + ///@function __merge(other) + ///@description an internal function, used for MergeSorting. + /// Not for you to use. (unless you know what you're doing) :] + static __merge = function(func, _other) { + var ans = array_create(size + _other.size); + var i = 0; + var j = 0; + var k = 0; + while(i < size && j < _other.size) { + //if self.get(i) < _other.get(j) { + if func(self.get(i), _other.get(j)) { + ans[k] = self.get(i); + i++; + } + else { + ans[k] = _other.get(j); + j++; + } + + k++ + } + + while(i < size) { + ans[k] = self.get(i); + i++; + k++; + } + + while(j < _other.size) { + ans[k] = _other.get(j); + j++; + k++; + } + + return array_to_Array(ans); + } + + ///@note Does not affect the original array!! (due to the internal recursive way it works) + /// !!! This is an internal function! You probably want to use the version without '__' !!! + /// (unless you know what you're doing) + static __mergeSort = function(func, l, r) { + if is_undefined(func) + func = SORT_ASCENDING + if is_undefined(l) + l = 0; + if is_undefined(r) + r = size; + + + if (r - l <= 1) || size <= 1 + return slice(l, r); + //return self; + + var mid = (l + r - 1) / 2; + + if (size % 2 == 0) { + var L = slice(l, mid).__mergeSort(func); + var R = slice(mid+1, r).__mergeSort(func); + } + else { + var L = slice(l, mid).__mergeSort(func); + var R = slice(mid, r).__mergeSort(func); + } + + var _merged = L.__merge(func, R); + + return _merged; + } + + ///@function __mergeSort(l, r, func) + ///@description Sorts the array using merge sort algorithm + /// In theory this should be fast, but my implementation is slower than bubble sort :) + /// So actually there's no reason to use this... + ///@param {function} func - a function, used to compare values. See .sort() for explanation + ///@param {real} l - the index to start the sort from. Defaults to 0 + ///@param {real} r - the index to end the sort on (including). Defaults to array.size + static mergeSort = function(func, l, r) { + return __mergeSort(func, l, r) + } + ///@function number(value) ///@description Returns the amount of elements equal to given value in the array ///@note IMPORTANT! Don't try to use this with data structures, as results may be unpredictable @@ -403,7 +576,7 @@ function Array() constructor { ///@function pop() ///@description removes a value from the end of the array and returns it static pop = function() { - ans = last(); + var ans = last(); if(empty()) { __throw( "Error: trying to pop value from empty Array"); return undefined; @@ -417,7 +590,7 @@ function Array() constructor { ///@function popBack() ///@description removes a value from the beginning of the array and returns it static popBack = function() { - ans = first(); + var ans = first(); remove(0); return ans; @@ -443,18 +616,137 @@ function Array() constructor { insert(0, val); } - ///@function getRandom() - ///@description Returns a random element from the array - static getRandom = function() { - var idx = irandom(size-1) - if empty() { - var ans = undefined + // An internal function, used for QuickSort + static __partition = function(func, l, r) { + //show_debug_message(slice(l, r-1)) + var i = l-1; + var j = l; + var piv = get(r); + + for(j = l; j < r; ++j) { + //if get(j) <= piv { + if func(get(j), piv) { + i++; + swap(i, j); + } } - else { - var ans = get(idx) + + swap(i+1, j); + + return i; + } + + ///@function quickSort(func, l, r) + ///@param {function} func + ///@param {int} l + ///@param {int} r + static quickSort = function(func, l, r) { // including r + if is_undefined(func) + func = SORT_ASCENDING + if is_undefined(l) + l = 0 + if is_undefined(r) + r = size-1 + + if (l < r-1) { + var pivot = __partition(func, l, r); + + quickSort(func, l, pivot); + quickSort(func, pivot+1, r); } - return ans + return self; + } + + ///@function radixSort() + ///@description sorts the array using radix sort algorithm + static radixSort = function(digits) { + + static getDigit = function(num, digit) { // digit from right to left + repeat(digit) { + num = num div 10; + } + return (num % 10); + } + + for(var digit = 0; digit < digits; ++digit) { + // 0-9 indexies representing each possible digit + static counters = array_create(10, 0); + static output = array_create(size, -1); + + for(var i = 9; i >= 0; --i) + counters[i] = 0; + + for(var i = size-1; i >= 0; --i) + output[i] = -1; + + for(var i = 0; i < size; ++i) { + var dig = getDigit(content[i], digit); + counters[dig]++; + } + + // sum + var len = array_length(counters) + for(var i = 1; i < len; ++i) { + counters[i] += counters[i - 1]; // get positions + } + + for(var i = size - 1; i >= 0; --i) { + var dig = getDigit(content[i], digit); + var pos = counters[dig]; + + if pos != 0 + pos--; + + while(output[pos] != -1) + pos--; + + output[pos] = content[i]; + } + + //array_copy(content, 0, output, 0, array_length(output)); + content = output; + } + + return self; + } + + ///@function remove(pos) + ///@description removes the value at given position + ///@param {real} pos + static remove = function(pos) { + if(pos < 0) + pos += size; + + if(size == 0) { + __throw("Error: trying to remove value from an empty Array"); + return self; + } + else if(pos < 0 or pos > size - 1) { + __throw( "Error: index "+string(pos)+" is out of range [0, "+string(size-1)+"]"); + return self; + } + + var part1 = slice(0, pos); + var part2 = slice(pos+1); + + part1.concat(part2); + + content = part1.content; + size--; + + return self; + } + + ///@function removeValue(value) + ///@description removes a selected value from the array + ///@param {any} value + static removeValue = function(value) { + var idx = find(value); + if (idx > -1) + remove(idx); + + return self; } ///@function resize(size) @@ -477,12 +769,13 @@ function Array() constructor { } ///@function reverse() - ///@description reverses the array, affecting it + ///@description reverses the array (overrides its contents) static reverse = function() { - ans = new Array(); - forEach(function(element, pos) { - ans.set(size-pos-1, element); - }); + var ans = new Array(); + //forEach(function(element, pos) { + // ans.set(size-pos-1, element); + //}); + findAnswer() content = ans.content; return self; @@ -491,10 +784,14 @@ function Array() constructor { ///@function reversed() ///@description Returns reversed version of the array, without affecting the original static reversed = function() { - ans = new Array(); - forEach(function(element, pos) { - ans.set(size-pos-1, element); - }); + var ans = new Array(); + //forEach(function(element, pos) { + // ans.set(size-pos-1, element); + //}); + for(var i = 0; i < size; ++i) { + var element = get(i) + ans.set(size-i-1, element) + } return ans; } @@ -527,7 +824,7 @@ function Array() constructor { if(is_undefined(_end)) _end = size; - ans = new Array(); + var ans = new Array(); if(_begin > _end) { @@ -544,6 +841,18 @@ function Array() constructor { return ans; } + ///@function some(predicate) + ///@description Returns whether there's an element in the Array that matches the predicate function + ///@param {function} predicate + static some = function(predicate) { + for(var i = 0; i < size; i++) { + var val = get(i) + if (predicate(val, i)) + return true; + } + return false; + } + ///@function sort(func, *startpos, *endpos) ///@description Bubble sorts through the array in given range, comparing values using provided function. ///Function gets (a, b) as input and must return True if A has more priority than B and False otherwise. @@ -552,6 +861,9 @@ function Array() constructor { ///@param {real} *startpos Default - 0 ///@param {real} *endpos Default - size static sort = function(compare, _begin, _end) { + if (is_undefined(compare)) + compare = SORT_ASCENDING; + if(is_undefined(_begin)) _begin = 0; @@ -611,20 +923,21 @@ function Array() constructor { ///NOTE: Works only with strings or numbars and only if all the elements are the same type. static sum = function() { if(is_string(get(0))) - ans = ""; + var ans = ""; else if(is_numeric(get(0))) - ans = 0; + var ans = 0; else { __throw( "TypeError: trying to sum up elements, that aren't strings or reals"); return undefined; } - forEach(function(el) { - if(typeof(el) != typeof(ans)) + for(var i = 0; i < size; ++i) { + var el = get(i); + if (typeof(el) != typeof(ans)) __throw( "TypeError: Array elements aren't the same type: got "+typeof(el)+", "+typeof(ans)+" expected."); ans += el; - }); + } return ans; } @@ -644,15 +957,54 @@ function Array() constructor { ///@function unique() ///@description Returns a copy of this Array object, deleting all duplicates static unique = function() { - ans = new Array(); + var ans = new Array(); + + //forEach(function(x) { + // if(!ans.exists(x)) + // ans.append(x); + //}); + for(var i = 0; i < size; ++i) { + if (!ans.exists(get(i))) + ans.push(get(i)); + } - forEach(function(x) { - if(!ans.exists(x)) - ans.append(x); - }); + return ans; + } + + + ///@function where(func) + ///@description Loops through the array and passes each value into a function. + /// Returns a new array with only values, that returned true. + /// Function func gets (x, *pos) as input + /// Note: Clean function. Does not affect the original array! + ///@param {function} func + static where = function(_func) { + func = _func; + var ans = new Array(); + + for(var i = 0; i < size; ++i) { + if(func(get(i), i)) + ans.append(get(i)); + } return ans; } + + static wrapIndex = function(idx) { + if (size == 0) + return idx + + while(idx >= size) { + idx -= size + } + + while (idx < 0) { + idx += size + } + + return idx + } + for(var i = 0; i < argument_count; i++) append(argument[i]) @@ -704,31 +1056,63 @@ function Range() : Array() constructor { } +///@function RandomArray(size, pool) +///@param {real} size +///@param {Array} pool +///@description Creates an array and fills it with random contents from the pool. +/// If pool is not provided, Range(100) is used +/// If pool is numeric, Range(pool) is used +function RandomArray(_size, pool) : Array() constructor { + if is_undefined(_size) + _size = 0; + if is_undefined(pool) + pool = new Range(100); + else if is_numeric(pool) + pool = new Range(pool); + else if is_array(pool) + pool = array_to_Array(pool); + + + repeat(_size) { + self.append(pool.getRandom()); + } + + return self; +} + + ///@function Iterator(arr) ///@description Constructs an iterator object to allow easier iteration through Array's +// actually i have no idea why you would use these function Iterator(arr) constructor { self.index = -1; self.value = undefined; self.array = arr + self.loop = false ///@function next() - next = function() { + static next = function() { index++; - try { + if (index > array.size) { value = array.get(index); } - catch(e) { - value = undefined; + else { + if (loop) { + index = 0 + value = array.get(index) + } + else { + value = undefined; + } } return value; } - get = function() { + static get = function() { return value; } - return self; } @@ -743,7 +1127,7 @@ function array_to_Array(array) { return undefined; } - ans = new Array(); + var ans = new Array(); for(var i = 0; i < array_length(array); i++) { ans.append(array[i]); @@ -768,7 +1152,7 @@ function ds_list_to_Array(list) { return undefined; } - ans = new Array(); + var ans = new Array(); for(var i = 0; i < ds_list_size(list); i++) { ans.append(list[| i]); @@ -806,7 +1190,14 @@ function ds_list_from_Array(Arr) { _list = ds_list_create() Arr.forEach(function(item) { - ds_list_add(_list, item) + //if (is_Array(item)) { + // item = ds_list_from_Array(item) + // ds_list_add(_list, item) + // ds_list_mark_as_list(_list, ds_list_size(_list)-1) + //} + //else { + ds_list_add(_list, item) + //} }) return _list } @@ -853,4 +1244,50 @@ function ds_list_from_array(arr) { ///@param {array} arr function array_to_ds_list(arr) { return ds_list_from_array(arr) -} \ No newline at end of file +} + + +// for nerds who care about optimization and use native arrays +#region non-OO arrays functions + +///@function array_exists(array, val) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +function array_exists(array, val) { + var _len = array_length(array) + for(var i = 0; i < _len; ++i) { + if (array[i] == val) + return true + } + + return false +} + +///@function array_find(array, val) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +function array_find(array, val) { + var _len = array_length(array) + for(var i = 0; i < _len; ++i) { + if (array[i] == val) + return i + } + + return -1 +} + +///@function array_foreach(array, func) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +function array_foreach(array, func) { + var _len = array_length(array) + for(var i = 0; i < _len; ++i) { + func(array[i], i) + } +} + +///@function array_push(array, val) +///@description IMPORTANT: Used for native gm arrays, not Array Class!!! +function array_push(array, val) { + array[@ array_length(array)] = val +} + + +#endregion \ No newline at end of file diff --git a/Sample+Tests/scripts/SpeedTimer/SpeedTimer.gml b/Sample+Tests/scripts/SpeedTimer/SpeedTimer.gml new file mode 100644 index 0000000..dd5f80c --- /dev/null +++ b/Sample+Tests/scripts/SpeedTimer/SpeedTimer.gml @@ -0,0 +1,28 @@ +function SpeedTimer() constructor { + start_time = get_timer(); + last_time = start_time; + last_split = undefined; + running = false; + splits = new Array(); + + static startSplit = function() { + running = true; + last_time = get_timer(); + return get_timer(); + } + + static endSplit = function() { + running = false; + var _split = get_timer() - last_time; + splits.append(_split); + + return _split; + } + + static split = function() { + var ans = endSplit(); + startSplit(); + + return ans; + } +} \ No newline at end of file diff --git a/Sample+Tests/scripts/SpeedTimer/SpeedTimer.yy b/Sample+Tests/scripts/SpeedTimer/SpeedTimer.yy new file mode 100644 index 0000000..f4758e8 --- /dev/null +++ b/Sample+Tests/scripts/SpeedTimer/SpeedTimer.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "Scripts", + "path": "folders/Scripts.yy", + }, + "resourceVersion": "1.0", + "name": "SpeedTimer", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/Sample+Tests/scripts/Tests/Tests.gml b/Sample+Tests/scripts/Tests/Tests.gml index bb84d56..30df87c 100644 --- a/Sample+Tests/scripts/Tests/Tests.gml +++ b/Sample+Tests/scripts/Tests/Tests.gml @@ -2,6 +2,9 @@ // ///@description check out ArrayClass.gml for docs +randomize(); + + function __Array_test() { show_debug_message("#### STARTING TESTS ####") @@ -26,7 +29,7 @@ function __Array_test() { array.forEach(function(num, pos) { if num == 3 { show_debug_message(string(pos) + ") " + string(num) + " is for suckers") - return 1 + ARRAY_LOOP = false // break out of forEach() } @@ -38,7 +41,7 @@ function __Array_test() { } - // Please don't delete stuff inside .forEach(), use .filter() instead + // Please don't delete stuff inside .forEach(), use .filter() or .where() instead }) show_debug_message(array) @@ -127,6 +130,9 @@ function __Array_test() { // sorting (slow, don't do every frame) show_debug_message("#### SORTING ####") + + var t = new SpeedTimer(); + array.sort(function(a, b) { return a > b // Descending }, 0, 4) // from 0 to 3 @@ -139,7 +145,6 @@ function __Array_test() { - // .sorted() and .reversed(), as well as .filter() don't modify the original array show_debug_message("#### CLEAN FUNCTIONS ####") var myarray = array.sorted(SORT_ASCENDING, 0, array.size).reversed() @@ -172,6 +177,7 @@ function __Array_test() { var uniq = array.unique() // like array but without duplicates var num = uniq.number(2) + show_debug_message(uniq) show_debug_message("Total amount of 2's: " + string(num)) @@ -241,4 +247,77 @@ function __Array_test() { ds_list_destroy(a_to_l) ds_list_destroy(A_to_l) + + + // DIFFERENT SORTING ALGORITHMS + show_debug_message("#### SORTING ALGORITHMS ####") + var t = new SpeedTimer(); + + + show_debug_message("randomly generated array:") + // generate dataset + var array = new RandomArray(20, 1000) + if array.size <= 100 + show_debug_message(array) + + + + // radix sort + show_debug_message("#### RADIX SORT ####"); + var arr = array.copy(); t.split(); // ignore array allocation time + + arr.radixSort(4); // 2875 + show_debug_message(arr); + + var time = string(t.split()); + show_debug_message("RadixSorted in: "+time); + + + + // merge sort + show_debug_message("#### MERGESORT ####"); + var arr = array.copy(); t.split(); // ignore array allocation time + + arr.mergeSort(); + show_debug_message(arr); + + var time = string(t.split()); + show_debug_message("MergeSorted in: "+time); + show_debug_message("AS YOU CAN SEE, MERGE SORT DOESN'T WORK..."); + + + + // bubble sort + show_debug_message("#### BUBBLESORT ####"); + var arr = array.copy(); t.split(); // ignore array allocation time + + arr.sort(); + show_debug_message(arr); + + var time = string(t.split()); + show_debug_message("BubbleSorted in: "+time); + + + + // quick sort + show_debug_message("#### QUICKSORT ####"); + var arr = array.copy(); t.split(); // ignore array allocation time + + arr.quickSort(); + + var time = string(t.split()); + show_debug_message("QuickSorted in: "+time); + + show_debug_message(arr) + + + //// bogosort (OMEGALUL) + //show_debug_message("#### BOGOSORT (OMG) ####"); + + //var arr = array.copy(); t.split(); + + //arr.bogosort(); + + //var time = string(t.split()); + //show_debug_message("BogoSorted in: "+time+"("+string(time / 1000000)+"s)"); } \ No newline at end of file