ActionScript 3.0 Randomize array, display number, and splice that number - arrays

So I am building a deck of cards. I have them blocked out, and appearing correctly on the screen. Now I need to build an array with numbers 1-16, and display them randomly on the cards without duplicating any numbers. My main problem is I can't figure out how to display the random numbers on the cards. I have filled the array, got the cards displaying correctly, I can even display the numbers in order, but can't figure out the code to display the numbers randomly. Thanks in advance.
Below is the code I have so far, which displays the cards with numerically ordered numbers.
var numberOfColumns=8;
var cardNumber:Array = new Array();
//---"for" function to display card columns---\\
for(var i:int = 1; i < 17; i++) {
var card = new Card();
cardNumber[i]= i;
card.x = ((i-1) % numberOfColumns) * 70;
card.y = (Math.floor ((i-1)/numberOfColumns) * 80);
card.cardTxt.text = i;
trace(i);//trace card count in Output
addChild(card);//add object to display list
}
trace(cardNumber);

One solution ( definetly not the best ) would be to fill another array with only indexes and then randomly splice it, like this :
var cardCount:int = 17;
var indexesArray:Array = [];
for(var j:int = 1; j < cardCount; j++)
indexesArray.push(j)
for(var i:int = 1; i < cardCount; i++) {
var card = new Card();
//Use a random index inside the array length
var randIndex:int = Math.round(Math.random()*indexesArray.length);
cardNumber[i]= indexesArray[idIndex];
//Strip out our used index so we can't use it again
indexesArray.splice( randIndex, 1 );
//... your code
}
However I'm pretty sure some logic freak can come up with a more optimized/clean solution, and avoid the need for a second array.

Related

How to tweenLite all objects in array and keep distance position?

Hey everyone so I have an array of Movie Clip Objects called aPlanetArray and what I am trying to accomplish is having all the objects in the array move down to a certain positing and then stop using tweenLite or any other method that would accomplish this. I know I can do it with y+=2 but I want all objects to move down the screen real quick in a bounce like effect using Tweenlite and to keep their distance ratios.
Here is how I have them setup when added to the stage:
//Numbers
xSpacing = 100;
ySpacing = 180;
startPoint = new Point((stage.stageWidth / 2), (stage.stageHeight / 2) );
private function addOuterPlanets():void
{
for (var i:int = 0; i < nPlanets; i++)
{
outerPlanets = new mcOuterPlanets();
outerPlanets.x = startPoint.x + (xSpacing * i);
outerPlanets.y = startPoint.y - (ySpacing * i);
stage.addChild(outerPlanets);
aPlanetArray.push(outerPlanets);
}
}
and when I tween them I am using this tweenlite function:
for each(var allPlanets:mcOuterPlanets in aPlanetArray)
{
TweenLite.to(allPlanets, 5.0, {y:550, ease:Back.easeOut});
}
This works perfect but all objects in array line up together and don't keep their spacing against one another. Any ideas would be appreciated thank you!
The simplest way would be to just have all the planets in a parent container and then move the container instead of the planets.
var planetContainer:Sprite = new Sprite();
function addPlanetsToContainer():void{
for (var i:int = 0; i < aPlanetArray.length; i++){
planetContainer.addChild(aPlanetArray[i]);
}
}
And now you can do your tween on planetContainer
Now to put the character on a planet, you can either do
planet.addChild(character);
or
character.x = planet.x + planet.parent.x;
character.y = planet.y + planet.parent.y;

AS3 Picking a random object from an Array with certain conditions

I'm looking for the fastest way to pick a random object that has a certain condition (from an array).
In the example below I have a multidimensional array, 50 * 50 that contains objects. I want to pick a random object from that array but that object needs to have a size larger than 100.
while (object.size <= 100)
{
attempts++;
object = grid_array[Math.round(Math.random() * 49)][Math.round(Math.random() * 49)];
}
Currently I have tested this and in some instances it takes over 300+ attempts. Is there a more elegant way to do this?
Thanks,
What I would do is first filter the source array to extract only valid candidates, then return a random one (if there are any).
For example:
function getRandomObject(grid_array:Array, minSize:Number):Object {
var filtered:Array = [];
for(var i:int = 0; i < grid_array.length; i++){
var inner:Array = grid_array[i];
for(var ii:int = 0; ii < inner.length; ii++){
var object:Object = inner[ii];
if(object.size >= minSize){
filtered.push(object);
}
}
}
return filtered.length ? filtered[int(Math.random() * filtered.length)] : null;
}
// example:
var object:Object = getRandomObject(grid_array, 100);
if(object){
// do stuff with `object`
}
I asked if you need the indexes because you could do this with RegExps and the JSON Class (Flash Player 11). With this example I stored the indexes of the objects:
Create random multidimensional Array to test the function
//---I stored a variable size and the indexes inside the Object
//---Size variable will be numbers between 0 and 500
var array:Array = [];
var i;
var j;
var size:uint = 50;
var obj:Object;
for(i = 0; i < size; i++){
array[i] = [];
for(j = 0; j < size; j++){
obj = new Object();
obj.size = Math.floor(Math.random() * 500);
obj.files = i;
obj.columns = j;
array[i][j] = obj;
}
}
Method to get random Object with size property bigger than 100
//---I'll use to search the object a JSON string
var str:String = JSON.stringify(array);
//---Function to get the random Object
function getRandom():Object{
//---RegExp to search object with size between 100 and 500
var reg:RegExp = /\{[^\}]*"size":(?:10[1-9]|1[1-9]\d|[2-5]\d\d)[^\}]*\}/g;
//---Get all matches
var matches:Array = str.match(reg);
//---Return a random match converted to object
//---If no match founded the return will be null
return matches ? JSON.parse( matches[Math.floor(Math.random() * matches.length)] ) : null;
}

Adding a fixed number of unique items to an array using a for loop and indexOf

I'm using a for loop to get 6 random numbers between 1-20, using indexOf to omit duplicates, and pushing them to an array.
However, I always want 6 items in the array, so I'd like duplicates to be replaced. In my naive code duplicates are simply omitted, which means that sometimes I'll get less than 6 in the array. How do I replace the omissions to fill those 6 array slots?
function rolld(event:MouseEvent) {
for (i = 0; i < 6; i++){
d = (Math.floor(Math.random() * (1 + d_hi - d_lo)) + d_lo);
if (rollArray.indexOf(d) < 0){
rollArray.push(d);
}
}
trace (rollArray);
}
Still very new to this. Thanks for any help!
When you get an element from array with 20 elements, try to remove it from array.
function rolld(event:MouseEvent) {
var elements:Array = [];
for (var i:int = 1; i <= 20; i++)
{
elements.push(i);
}
for (i = 0; i < 6; i++){
d = (Math.floor(Math.random() * elements.length);
rollArray.push(d);
//remove the element
elements.splice(d, 1);
}
trace (rollArray);
}

Assigning instance names to array Objects: ActionScript 3.0

I'll just start by saying that I am a bit new to programming, and I apologize if this is a stupid question.
I have a timer running in my application that at every interval, creates an a new instance of a MovieClip called blueBall.Here is my code:
var randomX:Number = Math.random() * 350;
var newBlue:mc_BlueBall = new mc_BlueBall ;
newBlue.x = randomX;
newBlue.y = -20;
for(var i:Number = 0;i < blueArray.length; i++)
{
newBlue.name = "newBlue" + i;
}
blueArray.push(newBlue);
addChild(newBlue);
}
var randomX:Number = Math.random() * 350;
var newBlue:mc_BlueBall = new mc_BlueBall ;
newBlue.x = randomX;
newBlue.y = -20;
for(var i:Number = 0;i < blueArray.length; i++)
{
newBlue.name = "newBlue" + i;
}
blueArray.push(newBlue);
addChild(newBlue);
}
My question is: How do I make it so that each newly created object in the array has it's own hitTestObject Event? I want to make it so that if the if the user's icon touches one of the newBlue objects, that newBlue object with be removed, and the score will go up a point.
Thanks!
this is my first time answering a question here but I hope I can help! Assuming you have a timer for your main game loop, you should try something like this once per frame:
//For each blue ball in the array
for(var i:int = 0; i < blueArray.length; i++) {
//If it touches the player
if(blueArray[i].hitTestObject(thePlayerMC)) {
//Increment the score
score++;
//Remove from stage and array
removeChild(blueArray[i]);
blueArray.splice(i, 1); //<-At index i, remove 1 element
//Decrement i since we just pulled it out of the array and don't want to skip the next array item
i--;
}
}
This is sort of the quick and dirty solution, but highly effective and commonly used.

as3 using addChild with an array containing indexes

so i have an array containing many instances. let's say movieclips.
and i have another array which contains numbers..in this case those numbers represent selected indices that i've somehow chosen!
var manydots:Array = new Array ();
for (var i=0; i<10; i++)
{
var newDot:dot = new dot ;
manydots.push(newDot);
}
var indices:Array = [0,1,5,8,4]
i want to use AddChild to add those movieclips into my scene, but not all of them, only selected indices contained in my 2nd array
I think this is what you are looking for,
for (var j=0; j<indicies.length; j++) {
addChild(manyDots[incidies[j]]);
}
sberry solution is correct. But you may also want to check that you actually are not adding null as a child.
for each(var i:int in indices) {
if (i < manydots.length) {
var d:dot = manydots[i];
if (d) {
addChild(d);
}
}
}

Resources