all groups > flash actionscript > august 2004 >
You're in the

flash actionscript

group:

arrays of arrays...best way to copy?



arrays of arrays...best way to copy? sneakyimp
8/25/2004 11:39:25 PM
flash actionscript: 2 questions

QUESTION 1:
i have an array of arrays to describe playing cards like this

arr[0][0] = "Ace";
arr[0][1] = "Hearts";
arr[1][0] = "2";
arr[1][1] = "Hearts";

etc. etc.

i have tried doing this:
var oneCard;
oneCard = arr[0];

but it totally doesn't work. this does:
var oneCard = new Array();
oneCard = arr[0];

that kind of sucks. is there any way to avoid the extra line to tell flash
that oneCard is a new array??

QUESTION 2:
I seem to recall that flash passes arrays by reference rather than by value.
this seems absolutely crazy to me...or maybe it would be convenient in some
cases i don't know. what is the simplest way to make sure that i don't end up
modifying an array passed as an argument to a function? ALSO...how do i make
sure that if i call a function with an array argument and then call the same
function with a distinct array argument with identical structure that i don't
get cross talk? i've had some weird behavior with even plain old integers
getting cross talk unless i explicitly use the VAR key word when referring to
them the first time...like this:

// although is not referenced anywhere outside this function
// the second time i called it, the if clause returned false
function foo() {
if (intCount == undefined) {
intCount = 165;
}
}
Re: arrays of arrays...best way to copy? maxil
8/26/2004 12:06:58 AM
Your first question. It isn't one card, it is an array that contains two value:

oneCard = arr[0]; // Contains the values Ace and Hearts
cardValue = new Array();
category = new Array();
arr = new Array(cardValue,Category)
arr[0][0] = "Ace";
arr[0][1] = "Hearts";
arr[1][0] = "2";
arr[1][1] = "Hearts";


oneCard = arr[0].join(" of ");

trace(oneCard//Returns Ace of Hearts);
Re: arrays of arrays...best way to copy? sneakyimp
8/26/2004 12:20:41 AM
thanks for your help, but a couple of things:

1) ok...i know oneCard is supposed to be a two dimensional array. that's how
i planned it. it's imperative that i keep the values separate because i need
to parse and process and check them later.

2) i am NOT trying to construct a larger array out of smaller arrays
structured like oneCard. the actual task at hand is to selectively copy items
from a larger array (i.e, "arrDeckOfCards") of oneCard items to a NEW array of
oneCard items (i.e., "arrMyBestPossibleHand")

i'm just trying to make the line count a little smaller in my code...rather
than this:

var oneCard = new Array();
oneCard[0] = arrDeckOfCards[0];
oneCard[1] = arrDeckOfCards[1];

by doing something much simpler...like this:

oneCard = arrDeckOfCards

but i know that doesn't work...which is really stupid and incomprehensible to
me..why????

maybe this would work?

oneCard = arrDeckOfCards.concat();

concat() is supposed to return a new array. this seems silly but maybe
because its actionscript is a fairly strongly typed language? i dunno...trying
to figure that out.

i've also encountered some scope weirdness using arrays (and even integers) in
the past and am trying to figure out what the rules of scope are in flash.
Re: arrays of arrays...best way to copy? Rothrock
8/26/2004 1:07:13 AM
Is there a reason you don't want to do something like:

arr[0]={Suit:"Heart",Rank:"Ace"};
arr[1]={Suit:"Heart",Rank:2}

Also somebody was asking about duplicating arrays here just a bit ago. Yes, I
believe you are correct about Flash passing arrays by reference.

I'm not really clear on what you are trying to do, but does the following code
give you any ideas?

stop();
myDeck = new Array();
myDeck[0] = {Suit:"Hearts", Rank:"Ace"};
myDeck[1] = {Suit:"Hearts", Rank:2};
myHand = new Array();
myHand[0] = myDeck[0];
myDeck[0] = {Suit:"Clubs", Rank:"Queen"};
trace(myHand[0].Rank + " of " +myHand[0].Suit);

Re: arrays of arrays...best way to copy? sneakyimp
8/26/2004 1:18:17 AM
ok...i'm using flash MX. to my knowledge, flash MX doesn't support associative
arrays. you can't do this:

myDeck[0] = {Suit:"Hearts", Rank:"Ace"};

secondly, you can't do this:
myHand = new Array();
myHand[0] = myDeck[0];

i tried it. it wasn't working. maybe it's a flash mx thing?
Re: arrays of arrays...best way to copy? maxil
8/26/2004 3:34:34 AM
Sorry, yes I believe you are correct. concat(); will return a new array with
the option of adding additional values onto the end of the array

myCard = arr[0].concat();

trace(myCard//returns : Ace,Hearts);
Re: arrays of arrays...best way to copy? Xeal
8/26/2004 4:21:40 AM
Q 2:
It is a very good thing that Flash passes array and all the other objects as
references. Do you think that copying a 1000 elements array every time you pass
it to a method is a wise thing?

Of course, a nice thing would have been to pass "const" references. A la C++.
Then the problem of inadvertently modifying the array inside your method would
disappear.

However, if you want to pass or copy an array you just have to do:
array.splice(0);
Re: arrays of arrays...best way to copy? mandingo
8/26/2004 4:31:59 AM
I don't know what it is you are trying to do, but will this help??

suits = ["Spades","Clubs","Diamonds","Hearts"];
cards = ["2","3","4","5","6","7","8","9","10","J","Q","K","A"];
myDeck = new Array();
for(var x=0; x<suits.length; x++){
for(var y=0; y<cards.length; y++){
myCard = new Object();
myCard.suit = suits[x];
myCard.value = cards[y];
switch(cards[y]){
case "J":
myCard.actualCard = "Jack of " + suits[x];
break;
case "Q":
myCard.actualCard = "Queen of " + suits[x];
break;
case "K":
myCard.actualCard = "King of " + suits[x];
break;
case "A":
myCard.actualCard = "Ace of " + suits[x];
break;
default:
myCard.actualCard = cards[y] + " of " + suits[x];
}
myDeck.push(myCard);
}
}
trace(myDeck[0].value);
trace(myDeck[0].suit);
trace(myDeck[0].actualCard);
trace(myDeck[51].value);
trace(myDeck[51].suit);
trace(myDeck[51].actualCard);

output :
2
Spades
2 of Spades
A
Hearts
Ace of Hearts


I hope that helps,
cheers
Re: arrays of arrays...best way to copy? place57 NO[at]SPAM hotmail.com
8/26/2004 4:34:29 AM
[quoted text, click to view]

Does it HAVE to be an array? Why not set up class for a card with 2
properties suit and card value? Then the "deck" can be an array of
Re: arrays of arrays...best way to copy? sneakyimp
8/26/2004 5:25:47 AM
maxil: tried the assignment you just did when trying to build arrays and was
getting empty arrays! the trace on each element seemed to work fine but the
array i was building (arrMyHand) from the deck (arrTheDeck) kept getting
corrupted. i think it has something to do with arrays getting passed by
reference but i'm not sure. arrays of arrays made it confusing so i think
copying them item by item is better.

xeal: you are totally right...passing giant arrays around would be a
disaster. it would be nice to have the option,though. to avoid confusion.

i like mandingo's idea! it never occurred to me to use objects. are objects
passed by reference too?

thanks everybody for chiming in on this....for your reference i am pasting one
of my functions here. i'm working on a texas holdem game. i have been
thrashing on this for days...array copying stuff is rather minor but complicate
the chasing down of bugs. my math mind isn't as sharp as it could be so this
is tough for me.

I also think part of my problem is checking to see if the various variables
are undefined rather than arrays of length 0. i got some really REALLY REALLY
strange behavior and finally started initializing a few variables explicitly
with the var keyword and a value of some kind (i.e., "var skipCards=0;"). that
seemed to fix most of the weirdness. now it's just a matter of seeing if it
really works--which, to tell the truth is really a matter of staring at the
logic and thinking about it mathematically and i dread this notion--and then
making it more efficient and robust.

anyway, i think it works. this function checks an array of 7 cards to find
the straight flush (if any). cards are arrays with two elements:
0 - value
1 - suit
NOTE: in texas holdem, a straight with ace low is permitted (i.e, A-2-3-4-5).



function getStraightFlush(arrHand) {
// this function assumes the hand
// has been sorted in descending order
var numCards = arrHand.length;

// we only have to check a certain number of adjacent
// card groups...add 2 to make sure we take the
// aces low possibility into account.
var numCardGroupsToCheck = (numCards - 5) + 2;
for (i=0; i < numCardGroupsToCheck; i++) {
var intValue = arrHand[i][0];
var intSuit = arrHand[i][1];
trace('checking suit:' + intSuit);
// grab the first card
// all subsequent cards must match suit
// and be a straight or no straight flush
var currentCardSeries = new Array();
currentCardSeries[0] = new Array();
currentCardSeries[0][0] = arrHand[i][0];
currentCardSeries[0][1] = arrHand[i][1];

// we need to check the next 4
// (or possibly more if we have any pairs)
var skipCards = 0;

// remember the one card we have on the stack
var intPreviousCardValue = currentCardSeries[0][0];

// check the next 4 cards...
for (j=1;j<=(4+skipCards);j++) {
if ((i+j) >= numCards) {
// we've already searched all the cards
break;
}
if (arrHand[i+j] == arrHand[i+j-1]) {
// if this card is not the first card
// and has same value as previous card
// (half a pair or triple) our streak is not
// broken but we must check one more card
skipCards++;
} else if (arrHand[i+j][1] != intSuit) {
// the flush is broken...
// on to next card series...
trace('could find straight flush on suit' + intSuit);
skipCards++;
} else if (arrHand[i+j][0] != (intPreviousCardValue-1)) {
// straight is broken...
// on to next card series...
break;
} else {
// if our straight flush continues
var tmpIndex = currentCardSeries.length;
currentCardSeries[tmpIndex] = new Array();
currentCardSeries[tmpIndex][0] = arrHand[i+j][0];
currentCardSeries[tmpIndex][1] = arrHand[i+j][1];
intPreviousCardValue = currentCardSeries[tmpIndex][0];
} // if to check for broken straight flush
} // loop next 4 cards

if (currentCardSeries.length == 5) {
// we have a straight flush! return the current series!
var intHighestStraightCard = intValue;
var arrStraightFlushHand = new Array();
arrStraightFlushHand = currentCardSeries.concat();
return arrStraightFlushHand.concat();
} else if ((currentCardSeries.length == 4) &&
(currentCardSeries[3][0] == 0)) {
// we also allow straights with aces low
// in texas holdem
// if the current card series has 4 items (almost!)
// AND the lowest item is a 2
// then check the 3 high items for ace and matching suit
for (tmpIndex=0; tmpIndex<3; tmpIndex++) {
if ((arrHand[tmpIndex][0] == 12) &&
(arrHand[tmpIndex][1] == intSuit)) {
// if any of the highest three items
// are aces of proper suit then
// STRAIGHT FLUSH! aces low
currentCardSeries[4] = new Array();
currentCardSeries[4][0] = arrHand[0][0];
currentCardSeries[4][1] = arrHand[0][1];
var arrStraightFlushHand = new Array();
arrStraightFlushHand = currentCardSeries.concat();
return arrStraightFlushHand.concat();
} // if high card is an ace
} //for loop: check for aces low straight flush
} // if currentcardseries has 5 cards...
} // for loop: check groups of adjacent cards

// if we get this far, return undefined
return undefined;
} //getStraightFlush()
Re: arrays of arrays...best way to copy? Rothrock
8/26/2004 12:21:03 PM
My Code above works just fine in Flash MX. Just

You can create associative arrays.

You can set one element of an array equal to another. In this case the trace
will show that Flash passes the value, not just a reference.

However if you do something like "myHand=myDeck" (where they are both arrays)
Flash will just pass a reference.

Here is some expanded code. Try it out, you might learn something useful.

stop();
myDeck = new Array();
myHand = new Array();
myOtherHand = new Array();
//
//Just a sample array
myDeck[0] = {Suit:"Hearts", Rank:"Ace"};
myDeck[1] = {Suit:"Hearts", Rank:2};
//
//Two different ways to copy element of an array
//or the whole array at once.
myHand[0] = myDeck[0];//value passed
myOtherHand = myDeck;//reference passed
//
//This next line will change both myDeck and myOtherHand
//but not myHand. Interesting, huh? Might want to
//use Debug->List Objects in the testing environment
myDeck[0] = {Suit:"Clubs", Rank:"Queen"};
trace("First Element of My Hand:"+myHand[0].Rank+" of "+myHand[0].Suit);
trace("First Element of My Other Hand:"+myOtherHand[0].Rank+" of
"+myOtherHand[0].Suit);

Re: arrays of arrays...best way to copy? sneakyimp
8/26/2004 9:09:24 PM
i have indeed learned something. associative arrays in MX!! who knew? thanks
for your effort. i tested my data structures using your syntax/style and it
seems to work...this code requires that an object be in your library with
linkage id "opponentPlayer"



stop();
var myTableCards = new Array();
myTableCards[0] = {Suit:"Hearts", Rank:12};
myTableCards[1] = {Suit:"Hearts", Rank:2};
myTableCards[2] = {Suit:"Spades", Rank:2};
myTableCards[3] = {Suit:"Clubs", Rank:5};
myTableCards[4] = {Suit:"Hearts", Rank:6};

var myPlayers = new Array();
myPlayers[0] = _root.attachMovie("opponentPlayer", "player0", 10);
myPlayers[0].pocketCards = new Array();
myPlayers[0].pocketCards[0] = {Suit:"Spades", Rank:12};
myPlayers[0].pocketCards[1] = {Suit:"Clubs", Rank:12};

myPlayers[1] = _root.attachMovie("opponentPlayer", "player1", 20);
myPlayers[1].pocketCards = new Array();
myPlayers[1].pocketCards[0] = {Suit:"Spades", Rank:11};
myPlayers[1].pocketCards[1] = {Suit:"Clubs", Rank:11};

function checkMyHandForBlahBlah(intPlayer) {
var myHand = myTableCards.concat(myPlayers[intPlayer].pocketCards);

// just an example loop
var numCards = myHand.length;
trace('i have ' + numCards + " cards");
var myFullHouse = new Array();
for(i=0;i<numCards;i++) {
if ((myHand[i]["Rank"] == 2) ||
(myHand[i]["Rank"] == 12) ||
(myHand[i]["Rank"] == 11)) {
var tmpLength = myFullHouse.length;
myFullHouse[tmpLength] = myHand[i];
}
}

myPlayers[intPlayer].winningHand = myFullHouse;
} // checkMyHand()

checkmyHandForBlahBlah(0);
var tmpLength = myPlayers[0].winningHand.length;
for(i=0; i<tmpLength; i++) {
var myCard = myPlayers[0].winningHand[i];
trace(myCard.Rank + " of " + myCard.Suit);
}
checkmyHandForBlahBlah(1);
var tmpLength = myPlayers[1].winningHand.length;
for(i=0; i<tmpLength; i++) {
var myCard = myPlayers[1].winningHand[i];
trace(myCard.Rank + " of " + myCard.Suit);
}
Re: arrays of arrays...best way to copy? Rothrock
8/26/2004 10:58:42 PM
AddThis Social Bookmark Button