how to find the value of an array in a random location? - arrays

i have an array of objects that I'm trying to randomize and i was wondering how can i find the data of a random location in an array using Debug.log? this is mainly so i know if it is working right.
my Code:
while(Deck.length != suffledDeck.length)
{
var ranNum = Random.Range(1,Deck.length);
suffledDeck.Add(Deck[ranNum]);
Debug.Log(suffledDeck[ranNum]);
//Debug.Log(suffledDeck[ranNum]);
}

You can shuffle a array with this fonction:
//# http://jsfromhell.com/array/shuffle [v1.0]
function shuffle(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
deck = shuffle(deck);
After that you can acces your array normally.

Related

How do I find the largest x,y and smallest x,y in a 2 dimensional array?

List<List<double>> intArr = [[448.0, 392.5], [465.5, 392.5], [493.5, 388.0], [536.0, 383.0], [609.5, 374.0], [667.5, 371.5], [714.5, 370.0], [771.0, 375.0], [804.0, 387.5], [821.0, 409.0], [828.0, 434.5], [833.0, 471.5], [834.0, 511.0], [833.0, 546.5], [829.5, 607.5], [819.5, 650.0], [804.5, 697.0], [799.5, 721.0], [796.5, 737.0], [795.0, 746.0], [792.5, 757.5], [791.0, 765.0]]
The above is my 2D ours. I want to find the smallest x and smallest y in this array and keep it as 2 in a new array. How can I do it. I am sharing a piece as an example below.
List<List> newList [[834,757.5],[448,370]]
List biggestPair = intArr[0];
List smallestPair = intArr[0];
for (int i = 0; i < intArr.length; i++) {
List pair = intArr[i];
if (pair[0] >= biggestPair[0]) {
if (pair[1] < biggestPair[1]) {
continue;
}
biggestPair = pair;
} else if (pair[0] < smallestPair[0]) {
if (pair[1] > smallestPair[1]) {
continue;
}
smallestPair = pair;
}
}
newArr = [biggestPair, smallestPair];
print(newArr);
The above code does not give the exact result I want. The above code gives the following result, but this result is wrong.
[[834.0, 511.0], [448.0, 392.5]]
The reason for your code is not working as intended is because what you want is not part of your existing set of points since your result is actually a new generated point where you combine data from other points.
But in your code you are doing biggestPair = pair; and smallestPair = pair; where you save points form your list of points and uses that as result.
I would rewrite the code into something like this making use of dart:math:
void main() {
var maxX = intArr[0][0];
var maxY = intArr[0][0];
var minX = intArr[0][1];
var minY = intArr[0][1];
for (final pair in intArr) {
final x = pair[0];
final y = pair[1];
maxX = max(maxX, x);
maxY = max(maxY, y);
minX = min(minX, x);
minY = min(minY, y);
}
final result = [[maxX, maxY], [minX, minY]];
print(result); // [[834.0, 765.0], [392.5, 370.0]]
}

Dart. Cant' change elements of list

I can't change elements of array using anonymous function:
var collection=[0, 1, 2];
collection.forEach((c)=> c+=1);
print(collection);
This variant doesn't work eithter:
var collection = [0, 1, 2];
for (var x in collection) {
x=x+1;
}
print(collection);
If you wish to replace/update all items in a list (List<int> items = [1, 2, 3]):
items = items.map((x) => x + 1).toList();
for (int i = 0; i < items.length; i++) items[i] += 1;
items = List<int>.generate(items.length, (i) => items[i] + 1);
List<int> tempItems = [];
items.forEach((x) => tempItems.add(x + 1));
items = tempItems;
You can't change the arguments to a function or var-in loop. You can call methods on them, which might have the side effect of mutating them, but assigning directly to them will not alter the value from which they are effectively copied.
collection.forEach((c)=> c+=1);
In above line you are incrementing parameter by 1 and that will not affect to the list.
It's equavalent to:
collection.forEach((int c) {// in this case int because list contains int's
c = c + 1;
});
As you can see, no point of changing the value of a parameter(local variable).
Since it's 0,1,2, you can do like this: collection.forEach((c)=> collection[c] = c+1);. That is stupid way because whenever you change any value, you will get an error(out of range).
So, here are some ways that you can change list values:
The easy way:
void main() {
var collection=[0, 1, 2];
for(int i = 0; i < collection.length; i++) {
collection[i] += 1;
}
print(collection);
}
Using replaceRange:
void main() {
var collection=[0, 1, 2];
var temp = collection.map((c) => c+1).toList();
collection.replaceRange(0, collection.length, temp);
print(collection);
}

Resize a 2D map

I'm developing a 2D map editor for a game and I need a way to increase or decrease the size of the grid/map uniformly in all directions.
Suppose you have a 3x3 map with a sort of "cross" symbol.
(arrays are zero-indexed. They start with 0)
Like this:
0,1,0
1,1,1
0,1,0
The array would look like this:
map = [0,1,0,1,1,1,0,1,0]
So, tile index 4 would be the center of the map.
I'd like to increase the size from 3x3 to 5x5 for example. So I end up with this:
0,0,0,0,0
0,0,1,0,0
0,1,1,1,0
0,0,1,0,0
0,0,0,0,0
The new map array should end up like this:
map = [0,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0,0]
What's a good way of doing this?
Here are two functions for increase and decrease. The parameter arr is your one-dimensional map and xWidth is the width (and of course the height) of your grid.
I had a question with a similar background here on Stackoverflow so many thanks to willywonka_dailyblah who helped me on the j and i indices.
public int[] increase_grid(int[] arr, int xWidth)
{
int newWidth = (xWidth+2);
int[] result = new int[newWidth * newWidth];
int count=0;
while(count<newWidth)
{
result[count++] = 0;
}
for (int i=0;i<xWidth;i++)
{
result[count++] = 0;
for (int j=0;j<xWidth;j++)
{
result[count++] = arr[i * xWidth + j];
}
result[count++] = 0;
}
while(count<(newWidth*newWidth))
{
result[count++] = 0;
}
return result;
}
public int[] decrease_grid(int[] arr, int xWidth)
{
int newWidth = (xWidth-2);
int[] result = new int[newWidth*newWidth];
for(int i=0; i< newWidth;i++)
{
for (int j=0;j< newWidth;j++)
{
result[i* newWidth + j] = arr[(i+1) * xWidth + (j+1)];
}
}
return result;
}
And I have this print function:
public void print_arr(int[] a, int xWidth)
{
for(int i=0;i<xWidth;i++)
{
for(int j=0;j<xWidth;j++)
{
System.out.print(a[i * xWidth + j]+" ");
}
System.out.println();
}
System.out.println();
}
You call these functions like:
int[] map = new int[]{0,1,0,1,1,1,0,1,0};
print_arr(map, 3);
map = increase_grid(map, 3);
print_arr(map, 5);
map = increase_grid(map, 5);
print_arr(map, 7);
map = decrease_grid(map, 7);
print_arr(map, 5);
So you have to pass the current size of your map and either call increase or decrease. Beware, that the these functions include a nested for-loop. Thus, they are less scale-able on greater grid sizes. I think there may be a solution to wrap even this into a loop-sequence, which runs without nesting.

MQL4 array creating variables

I'm trying to make this function create X number of variables using an array. I know that this is technically wrong because I need a constant as my array's value (currently 'x'), but excluding that, what am I missing? Looked at so many code samples and can't figure it out, but I know it's got to be simple...
void variables()
{
int i;
int bars = 10;
int x = 1;
for (i = 1; i <= bars+1; i++)
{
int variables[bars] = { x };
x++;
if (i >= bars+1)
{
break;
}
}
void variables()
{
int bars = 10;
if(bars >= Bars) bars = Bars - 1;
// to be able to set array size based on variable,
// make a dynamically sized array
double highvalues[];
ArrayResize(highvalues, bars);
for (int i = 0 /*Note: Array index is zero-based, 0 is first*/; i <= bars; i++)
{
highvalues[i] = iHigh(NULL, 0, i);
// or
highvalues[i] = High[i];
}
}
It is hard to tell what do you want to achieve.
If you want to fill an array with a value ArrayFill() fill help you.

as3 random array - randomize array - actionscript 3

How do you randomize an array using actionscript 3?
There is a short version using Array.sort() function:
var arr : Array = [0,1,2,3,4,5,6,7,8,9];
function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
trace( arr.sort( randomize ) );
If you don't get "enough" randomness you can sort twice :)
EDIT - explanation line by line:
For Array class method sort() you can pass not only sort options like Array.CASEINSENSITIVE, Array.DESCENDING and so on but also your own custom compare function reference (a callback) that accepts two parameters (two elements from array to compare). From AS3 documentation:
A comparison function should take two arguments to compare. Given the elements A and B, the result of compareFunction can have a negative, 0, or positive value:
A negative return value specifies that A appears before B in the sorted sequence.
A return value of 0 specifies that A and B have the same sort order.
A positive return value specifies that A appears after B in the sorted sequence.
Note: compare function parameters might be typed (if your array is typed) and have any name you want eg.:
function compareElements ( elementA : SomeClass, elementB : SomeClass ) : int;
This method is very useful when you need to sort array elements by their special properties. In randomization case compareFunction randomly returns -1, 0 or 1 and makes array elements to switch their places (indices). I have found that better randomization (in my subjective and mathematically untested opinion) is when method returns only -1 and 1. Also have in mind that sorting function with custom compare function doesn't compare elements sequentially so in some special cases randomization results may differ from what you might expect.
There's a better way that will also allow you to randomize the array in place, if you need that, and it will not make you create more then a single copy of your original array.
package
{
import flash.display.Sprite;
public class RandomizeArrayExample extends Sprite
{
public function RandomizeArrayExample()
{
super();
testDistribution();
}
private function testDistribution():void
{
var hash:Object = { };
var tester:Array = [1, 2, 3, 4];
var key:String;
for (var i:int; i < 1e5; i++)
{
randomize(tester);
key = tester.join("");
if (key in hash) hash[key]++;
else hash[key] = 1;
}
for (var p:String in hash) trace(p, "=>", hash[p]);
}
private function randomize(array:Array):Array
{
var temp:Object;
var tempOffset:int;
for (var i:int = array.length - 1; i >= 0; i--)
{
tempOffset = Math.random() * i;
temp = array[i];
array[i] = array[tempOffset];
array[tempOffset] = temp;
}
return array;
}
}
}
I had an alternative requirement where i wanted to randomly insert lots of source arrays into a target array randomly. Like Rytis i'm a big fan of the forEach, map and sort functions on Arrays.
var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void
{
var j:Number = Math.floor(Math.random() * targetArray.length);
targetArray.splice(j,0,item);
}
targetArray = new Vector.<MyItem>();
sourceArray1.forEach(randomInsert, this);
sourceArray2.forEach(randomInsert, this);
here's an easier function. Works also on multidimensional arrays
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
var mn=Math.floor(Math.random()*array.length)
newArray[newArray.length]=array[mn]
array.splice(mn,1)
}
return newArray;
}
I found this very helpful. I hope it can help you too.
// Array to Randomize
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"];
trace(firstArray); // Prints in order
var newArray:Array = new Array();
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
var randomArray:Array = randomizeArray(firstArray);
trace(randomArray); // Prints out randomized :)
If you need your array to be shuffled (your elements can not repeat). You could use this function:
/**
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used.
*/
public function shuffleArray(original:Array):Array
{
// How many swaps we will do
// Increase this number for better results (more shuffled array, but slower performance)
const runs:int = original.length * 3;
var shuffled:Array = new Array(original.length);
var i:int;
var a:int;
var b:int;
var temp:Object;
// Copy original array to shuffled
for(i=0; i<shuffled.length; i++){
shuffled[i] = original[i];
}
// Run random swap cycle 'runs' times
for(i=0; i<runs; i++){
// There is a chance that array element will swap with itself,
// and there is always small probability it will make your shuffle
// results not that good, hence try to experiment with
// different runs count as stated above
a = Math.floor(Math.random() * original.length);
b = Math.floor(Math.random() * original.length);
// Swap messages
temp = shuffled[a];
shuffled[a] = shuffled[b];
shuffled[b] = temp;
}
return shuffled;
}
Usage:
var testArray:Array = ["Water", "Fire", "Air", "Earth"];
trace(shuffleArray(testArray).concat());
this is how I randomize my array of 36 cards for a memory game
const QUANT_CARTAS: int = 36;
//get the 36 numbers into the array
for (var i: int = 0; i < QUANT_CARTAS; i++)
{
cartas.push(i);
}
//shuffles them =)
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--)
{
var pos: int = Math.floor(Math.random() * moeda);
var carta: int = cartas[moeda];
cartas[moeda] = cartas[pos];
cartas[pos] = carta;
}
// and add them using the random order...
for (i = 0; i < QUANT_CARTAS; i++)
{
var novaCarta: Carta = new Carta();
novaCarta.tipoCarta = cartas[i];
etcetcetc.............
}
choose random string from array
function keyGenerator(len:Number):String
{
function randomRange(minNum:Number, maxNum:Number):Number
{
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
var hexArray = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var key = "";
for (var i=0; i<len; i++)
{
key += hexArray[randomRange(0,hexArray.length-1)];
}
return key;
}
usage:
trace(keyGenerator(16));

Resources