JS array and object help


#1

This is unrelated to any of the JS exercises. This is an independent project.
I had no idea where to post this. Please move as necessary.

I am attempting to put the entire "FullDeck" array into the "Draw" object.
How do I do that?

Here is my full code:

var FullDeck = [
"01r","02r","03r","04r","05r","06r","07r","08r","09r","10r","11r","12r","13r",
"01w","02w","03w","04w","05w","06w","07w","08w","09w","10w","11w","12w","13w",
"01m","02m","03m","04m","05m","06m","07m","08m","09m","10m","11m","12m","13m",
"01l","02l","03l","04l","05l","06l","07l","08l","09l","10l","11l","12l","13l"
];
var Draw = {
    //This is the zone in which a full deck is placed and cards are drawn.
};
var Hand = {
    //Drawn cards land here. Played cards are moved from here.
};
var Stack = {
    //Played cards land here. The top card, or most recent card, is the active card.
};
var Action ={
    //Cards between zones land here.
};
var Zones = [Draw,Hand,Stack,Action];
function getRandom(min,max){
	min = Math.ceil(min);
	max = Math.floor(max);
	return Math.floor(Math.random()*(max-min)+min);
}
console.log(FullDeck[0]);


function Shuffle(FullDeck){
	var currentIndex = FullDeck.length, temporaryValue, randomIndex;
	while (0!== currentIndex){
		randomIndex= Math.floor(Math.random()*currentIndex);
		currentIndex-=1;
		temporaryValue =FullDeck[currentIndex];
		FullDeck[currentIndex] = FullDeck[randomIndex];
		FullDeck[randomIndex] = temporaryValue;
	}
	return FullDeck;
}
Shuffle(FullDeck);
console.log(FullDeck[0]);

Draw.push(FullDeck);

console.log(Draw);
//Re-order a full deck randomly.
function Deal(){}
//Deal five cards randomly chosen from two full decks.

`


#2

Just a thought on shuffling. Still mulling it over so bear with me...

start with a full deck
create an empty shoe
loop through a range 51 to -1 in reverse
generate a random number in the current range
append the card at that index by popping it from the full deck

I'm going to use Python to generate a proof of concept, then we can port it over to JS.

>>> FullDeck = [
"01r","02r","03r","04r","05r","06r","07r","08r","09r","10r","11r","12r","13r",
"01w","02w","03w","04w","05w","06w","07w","08w","09w","10w","11w","12w","13w",
"01m","02m","03m","04m","05m","06m","07m","08m","09m","10m","11m","12m","13m",
"01l","02l","03l","04l","05l","06l","07l","08l","09l","10l","11l","12l","13l"
]
>>> shoe = []
>>> for i in range(51, -1, -1):
    x = randint(0, i)
    shoe.append(FullDeck.pop(x))
    
>>> shoe
[
'12w', '06r', '03r', '01m', '13w', '02w', '10m', '02m', '02l', '04w', '04r', '07m', '06l', 
'09r', '11m', '09m', '13r', '05m', '01r', '10r', '13l', '07l', '08l', '07r', '08m', '08r', 
'06m', '04l', '03m', '10w', '06w', '05r', '01l', '10l', '12m', '05l', '12r', '03l', '05w', 
'11w', '11r', '11l', '09l', '12l', '13m', '07w', '09w', '03w', '04m', '02r', '08w', '01w'
]
>>> len(shoe)
52
>>>

#3

As keys? Or as values? If we use their index as a key,

for (var i = 0; i < FullDeck.length; i++) {
    Draw[i] = FullDeck[i];
}

The object will have no order. The keys are the array indices, but now strings.

Note that we can still draw randomly from the object if we use the indices as keys. We have only to convert the random number to a string. Just a passing thought, which brings up this question... Is Draw a shuffled copy of FullDeck?


#4

So what I literally want is for the "cards" in FullDeck to be placed in the zone such that I can manipulate each card as I desire. So if 10w was the top card in the draw object I could move it away if I so desired.

It would probably be best if they were inserted as values.


#5

Here is some more proof of concept to examine:

var FullDeck = [
"01r","02r","03r","04r","05r","06r","07r","08r","09r","10r","11r","12r","13r",
"01w","02w","03w","04w","05w","06w","07w","08w","09w","10w","11w","12w","13w",
"01m","02m","03m","04m","05m","06m","07m","08m","09m","10m","11m","12m","13m",
"01l","02l","03l","04l","05l","06l","07l","08l","09l","10l","11l","12l","13l"
];
var Draw = {};
var random = Math.random;
var floor = Math.floor;
function shuffle(deck) {
    var shoe = [];
    for (var x, i = 51; i > -1; i--) {
        x = floor(random() * (i + 1));
        shoe.push(deck.splice(x, 1).toString());
    }
    return shoe;
}
var shoe = shuffle(FullDeck.slice());

for (var i = 0; i < shoe.length; i++) {
    Draw[i] = shoe[i];
}

The above passes only a copy of FullDeck so the main object is preserved. We never manipulate FullDeck. Only clone it.

If you notice, inside the function we destroy the array, deck. All its cards have gone into the shoe in random order. We can simplify the function even further...

function shuffle(deck) {
    var shoe = [], x;
    while (deck.length) {
        x = floor(random() * deck.length);
        shoe.push(deck.splice(x, 1)[0]);
    }
    return shoe;
}

Now it's a little more obvious that this is a destructive loop. What this method offers is variable deck size. It can be used to shuffle partial decks, as well, or two decks, etc.


#6

Looks like you had fun doing this ; )


#7

Yes I did, indeed. Switching to this method in future and past code is not going to be a fight. Actually patted myself on the back.


#8

This was very helpful. Thank you very much for your help. :slight_smile:


#9

You're welcome. How is the project going?


#10

Slowly but surely. Just trying to solve one problem at a time.


#11

That's the best way to approach a big project. One component at a time. Work out all the details on that one fragment of code and test the life out of it to make sure it does exactly what you want, every time, with every form of inputs. This will help discover all the edge cases and mitigate them, while at the same time refactoring and refining your code, as we did above.

If you need help testing, post just the fragment and list the constraints, expected inputs and expected output/returns.