how to catch duplicate random number - actionscript-3

I want to display random number in bb1,bb2,bb3,bb4.
alphaset:Array = [1,2,3,4,5,6,7,8,9,10];
bb1 = randomNumber(0, alphaset.length);
bb2 = randomNumber(0, alphaset.length);
bb3 = randomNumber(0, alphaset.length);
bb4 = randomNumber(0, alphaset.length);
in above, i want to delete duplicate entry of each variable (i.e., bb1,bb2,bb3,bb4)
finally i want random number without duplicate entry of each variable
please anyone help me to achieve it.
The above four var are options for addition program. And i have to compare the above four var and bbb = randomNumber(1,10) and display bbb value in that four var randomly i,e., [bbb=bb1 or bbb=bb2 or bbb=bb3 or bbb=bb4] coz, i have to select the bbb value to display output.

If all the values in the array are unique to begin with, just remove them when they're used:
var list:Array = [1,2,3,4,5,6,7,8,9,10];
function getRandom(list:Array):*
{
var i:int = Math.random() * list.length;
return list.splice(i, 1)[0] || null;
}
var bb1:int = getRandom(list);
var bb2:int = getRandom(list);
var bb3:int = getRandom(list);
var bb4:int = getRandom(list);

One option is to shuffle the entire list of random elements - then you can take the first N elements, where N is the number you need, and know those will all be unique and randomly chosen. If you use a large amount of the total random element list, this is faster than sampling and removing.
If you can't find a standard implementation of shuffle, implement the Fisher-Yates Shuffle: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm It is important that there are n! possible ways for the shuffle to come out, not n^n which you incorrectly get if you take each element one at a time and allow it to be exchanged with any other element, including previous elements, otherwise certain configurations will be more common than others.

Related

Accessing a random Object AS3

I have 9 different movie clips and they are called MC1, MC2, MC3,...,MC9. Then I want to add them randomly. I made a randomizer and it generate numbers from 1 to 9 randomly. And now how can I add them using the random number that I generate. Example:
var box11:MC[the random number] = new MC[the random number], where in the place of [the random number] will stay that number, for ex: var box11:MC2 = new MC2.
And would it be also possible to do the same with box value? For example box[i][j] for different values od i and j will become box11, box32...?
You can use flash.utils.getDefinitionByName() for this.
Example:
var theClass:Class = getDefinitionByName("MC" + randNum) as Class;
var instance = new theClass();
For dynamic istances (the box), see my answer to this question:
How to push instantiated MC into Array dynamically?

AS3 - getting variable named in order within a function

I am sorry if this is a beginner's question.
I made some Arrays named like map01, map02 and so on... As you can see, I'm making a tile-based flash here. And I need to make a function that when you input a number like: createmap(1); it will get the variable map01 and use the information.
Can I do anything like: var temp:Array = Array(["map" + valueInput]);??
Please tell me if you need anything more.
First, instead of having variables with indices in their names, you should create an array of them. Here, an array of arrays.
So you just have to call var temp:Array = maps[valueInput] as Array;.
If you really don't want to do that and stick with your n variables, you can write
var index:String = valueInput.toString();
if (index.length == 1)
index = "0" + index; //have the index on two digits "01", "02"
var temp:Array = this["map" + index];
Note that it will only work for your 99 first variables (oh God...)

How do I select a part of an array? Or match parts of one array with parts of another?

I have some drag and drop function where there are 8 items (dragArray) that can be dropped onto 2 big 'landing zones' (matchArray). But since I don't want them lie on top of each other, I've made an array where they are given positions (posArray).
var dragArray:Array = [drag_1, drag_2, drag_3, drag_4, drag_5, drag_6, drag_7, drag_8];
var matchArray:Array = [drop_1, drop_1, drop_1, drop_1, drop_2, drop_2, drop_2, drop_2];
var posArray:Array = [{x:412,y:246},{x:530,y:218},{x:431,y:186},{x:470,y:152},{x:140,y:111},{x:108,y:162},{x:179,y:210},{x:113,y:254}];
When all 8 items are dropped, a check button appears and I want to check if they are dropped onto the correct big landing zone. I tried using the following:
if (posArray[i].x != dragArray[i].x || dragArray[i].y != posArray[i].y )
But then, not only the landing zone must match, but the positions must also match.
When I use
if (matchArray[i].x != dragArray[i].x || dragArray[i].y != matchArray[i].y )
it doesn't work, because the positions of the (dragArray) items don't match with the registration points of the (matchArray) landing zones.
Is there any way of checking if the first 4 (drag_1, drag_2, drag_3, drag_4) items match with ANY of the first 4 posArray positions and the last 4 (drag_5, drag_6, drag_7, drag_8) match with ANY of the last 4 posArray positions?
If the goal is to check each element of one set against all elements of another set then you'll need to have two loops, one "nested" within the other. The general form of this algorithm in AS3 looks like
var allMatched:Boolean = true;
for(var i:Number=0; i<array1.length; i++)
{
var matchFound:Boolean = false;
for(var j:Number=0; j<array2.length; j++)
{
if(array1[i]==array2[j])
{
matchFound=true;
break; //exit the inner loop we found a match
}
}
if(!matchFound)
{
allMatched=false;
break; //we found an element in one set not present in the other, we can stop searching
}
}
if(allMatched)
trace("Everything from array1 was found somewhere in array2"); //For an element a in the set A there exists an element b in set B such that a = b
Let me know if this helps

How do i make my pickNum array just one index instead of 3 different indexes.

this will random my numPool and push the random three numbers to my array called pickNum. I need that pickeNum to be just one index instead of three indexes. Thanks and i will appreciate any help thanks.
var numPool:Array = [1,2,3];
var pickNum:Array = [];
var randomCount:Number = 3;
var r:Number;
for (var i = 0; i < randomCount; i++)
{
r = Math.floor(Math.random() * numPool.length);
pickNum[pickNum.length] = numPool.splice(r,1);
}
trace("Number Picked " + pickNum);
Can't say I completely understand what you are saying, but the issue with the code above is that splice returns an Array containing the values that were spliced from the array. Also, would be easiest to just do a push. So the proper line for getting that value and pushing it into the pickNum array would be :
pickNum.push(numPool.splice(r,1).pop());
And if you are saying that you want only 1 random number from the pool, then why do you need a loop ?

AdvancedDataGrid total sum of branch nodes

Introduction:
I have an AdvancedDataGrid displaying hierarchical data illustrated by the image below:
The branch nodes "Prosjekt" and "Tiltak" display the sum of the leaf nodes below.
Problem: I want the root node "Tavle" to display the total sum of the branch nodes below. When i attempted to do this by adding the same SummaryRow the sum of the root node was not calculcated correctly(Every node's sum was calculated twice).
dg_Teknikktavles = new AutoSizingAdvancedDataGrid();
dg_Teknikktavles.sortExpertMode="true";
dg_Teknikktavles.headerHeight = 50;
dg_Teknikktavles.variableRowHeight = true;
dg_Teknikktavles.addEventListener(ListEvent.ITEM_CLICK,dg_TeknikktavlesItemClicked);
dg_Teknikktavles.editable="false";
dg_Teknikktavles.percentWidth=100;
dg_Teknikktavles.minColumnWidth =0.8;
dg_Teknikktavles.height = 1000;
var sumFieldArray:Array = new Array(context.brukerList.length);
for(var i:int = 0; i < context.brukerList.length; i++)
{
var sumField:SummaryField2 = new SummaryField2();
sumField.dataField = Ressurstavle.ressursKey + i;
sumField.summaryOperation = "SUM";
sumFieldArray[i] = sumField;
}
var summaryRow:SummaryRow = new SummaryRow();
summaryRow.summaryPlacement = "group";
summaryRow.fields = sumFieldArray;
var summaryRow2:SummaryRow = new SummaryRow();
summaryRow2.summaryPlacement = "group";
summaryRow2.fields = sumFieldArray;
var groupField1:GroupingField = new GroupingField();
groupField1.name = "tavle";
//groupField1.summaries = [summaryRow2];
var groupField2:GroupingField = new GroupingField();
groupField2.name = "kategori";
groupField2.summaries = [summaryRow];
var group:Grouping = new Grouping();
group.fields = [groupField1, groupField2];
var groupCol:GroupingCollection2 = new GroupingCollection2();
groupCol.source = ressursTavle;
groupCol.grouping = group;
groupCol.refresh();
Main Question: How do i get my AdvancedDataGrid's (dg_Teknikktavles) root node "Tavle" to correctly display the sum of the two branch nodes below?
Side Question: How do i add a red color to the numbers of the root node's summary row that exceed 5? E.g the column displaying 8 will exceed 5 in the root node's summary row, and should therefore be marked red
Thanks in advance!
This is a general answer, without code examples, but I had to do the same just couple of days ago, so my memory is still fresh :) Here's what I did:
Created a class A to represent an item renderer data, extended it from Proxy (I had field names defined at run time), and let it contain a collection of values as it's data member. Once accessed through flash_proxy::getPropery(fieldName) it would find a corresponding value in the data member containing the values and return it. Special note: implement IUID, just do it, it'll save you couple of days of frustration.
Extended A in B, added a children property containing ArrayCollection of A (don't try to experiment with other collection types, unless you want to find yourself examining tons of framework code, trust me, it's ugly and is impossible to identify as interesting). Let B override flash_proxy::getPropery - depending of your compiler this may, or may not be possible, if not possible - call some function from A.flash_proxy::getPropery() that you can override in B. Let this function query every instance of A, which is a child of B, asking the same thing, as DataGrid itself would, when building item renderers - this way you would get the total.
When creating a data provider. Create an ArrayCollection of B (again, don't try to experiment with other collections--unless you are ready for lots of frustration). Create Hierarchical data that uses this array collection as a source.
Colors - that's what you use item renderers for, just look up any tutorial on using item renderers, that must be pretty basic.
In case someone else has the same problem:
The initial problem that everything was summed twice, was the result of using the same Array of SummaryField2 (sumFieldArray in the code) for both grouping fields(GropingField2 tavle and kategori)
The Solution to the main question: was to create a new array of summaryfields for the root node(in my intial for loop):
//Summary fields for root node
var sumFieldRoot:SummaryField2 = new SummaryField2();
sumFieldRoot.dataField = Ressurstavle.ressursKey + i;
sumFieldRoot.summaryOperation = "SUM";
sumFieldArrayRoot[i] = sumFieldRoot;
Answer to the side question:
This was pretty much as easy as pointed out by wvxyw. Code for this solution below:
private function summary_styleFunction(data:Object, col:AdvancedDataGridColumn):Object
{
var output:Object;
var field:String = col.dataField;
if ( data.children != null )
{
if(data[field] >5){
output = {color:0xFF0000, fontWeight:"bold"}
}
else {
output = {color:0x006633, fontWeight:"bold"}
}
//output = {color:0x081EA6, fontWeight:"bold", fontSize:14}
}
return output;
}