0

Firstly, I'm new to JavaScript and in an effort to gain a better understanding of OOP I've decided to build solitaire (the three-card version mind you). In solitaire--as I'm sure is well known-- you deal out the cards in the whatever pattern and the remaining cards are placed off to the side; I'm calling these the 'reserve' deck. Then you move the cards you dealt around following the rules of the game (can only place a red 6 on a black 7, etc.) and when you run out of options you can pull three cards off the top of 'reserve' and see if you can use the third card to continue playing. If not, you pull three more cards, so on and so forth until you run out of cards in the 'reserve' deck. At this point, all the cards you pulled off the top of 'reserve' deck can then get placed back into the 'reserve' deck and then reused in the same manner.

And this is where my javascript is breaking. So I've created a Table object with the properties playSlots, winSlots, reserve and pick. playSlots is an array of arrays in which cards get dealt into, reserve is an array of the cards existent within the 'reserve' deck, winSlots isn't relative to this question and pick is an array that becomes populated with cards from reserve as it becomes necessary throughout game play. Pretty self-explanatory. When reserve becomes empty and you want to put the pick cards back into it, my code for this is currently:

if(!Array.isArray(newGame.reserve) || !newGame.reserve.length){
  newGame.pick.forEach(function(cur, i, arr){
    newGame.reserve.push(arr.shift());
  });
}

The problem with this is that this only iterates through half of the cards in the pick array. I went through it in the debugger and it is, in fact adding the cards back into the reserve deck one at a time but once it gets to the 13th card it breaks out of the loop (28 cards cards get dealt out in the solitaire pattern, leaving 24 in the reserve deck...).

I was pretty sure this issue has something to do with the !newGame.reserve.length condition. That condition is something I found here:

Check if array is empty / does not exist. JS

and although the answer-er is pretty clear in his his explanation of this, I'm still kinda fuzzy on what it means. Thing is, I also tried this for a condition:

if(newGame.reserve[0] === undefined)

and had the exact same result. The .forEach loop is only iterating over half of the array elements.... What am I missing here?

panrosmithe
  • 69
  • 10
  • 3
    When removing elements from an array while looping through it, you'll generally want to iterate through it *backwards* to avoid re-indexing. See this related post: [Looping through array and removing items, without breaking for loop](https://stackoverflow.com/questions/9882284/looping-through-array-and-removing-items-without-breaking-for-loop) – Tyler Roper Jul 14 '18 at 02:44
  • `console.log(arr)` inside the loop and see what happens.... – epascarello Jul 14 '18 at 02:47
  • isn't the loop just trying to achieve `newGame.reserve.push(...newGame.pick.splice(0, newGame.pick.length));` – Jaromanda X Jul 14 '18 at 02:52
  • @TylerRoper okay, but won't that put the elements but into the 'reserve' array in reverse? If so, that won't work in the context of the game... I suppose there's the `.reverse()` method if this is only way but... really? – panrosmithe Jul 14 '18 at 02:53
  • your code doesn't put them in in reverse anyway, does it? (hint: it doesn't) – Jaromanda X Jul 14 '18 at 02:53
  • @JaromandaX *to first comment*: woah, that looks efficient... but what's the `...`? *to second comment*: no it doesn't but it looks as if the code in @TylerRoper ' s comment would do that.. – panrosmithe Jul 14 '18 at 02:58
  • ... is spread ES2016+ operator – Jaromanda X Jul 14 '18 at 02:58
  • I've added an answer using `...` and old school javascript as well (using `.apply` ) – Jaromanda X Jul 14 '18 at 03:00
  • @JaromandaX ok, hold on.. I've been learning a lot about ES2015 but I am not aware of an ES 2016... just tried looking up this ellipse thing but nothing coming up; care to share a link to some docs? – panrosmithe Jul 14 '18 at 03:02
  • sorry, typo, it's ES2015 ... [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) – Jaromanda X Jul 14 '18 at 03:03
  • ES2015 was also known as ES6, but there is [ES2016](https://www.ecma-international.org/ecma-262/7.0/) and [ES2017](https://www.ecma-international.org/ecma-262/8.0/) and even [ES2018](https://www.ecma-international.org/ecma-262/9.0/) – Jaromanda X Jul 14 '18 at 03:07

1 Answers1

0

You can achieve this easier using Array splice

Note: this reverses pick to the end of reserve, whereas your code does not

If you do not need it reversed, simply remove the .reverse()

It's not clear if you want pick reversed into reserve or not

var newGame = {
    pick: [1,2,3,4],
    reserve: [10,11,12]
};

newGame.reserve.push(...newGame.pick.splice(0, newGame.pick.length).reverse());
console.log(newGame);

in "old school" javascript, this can be written using .push.apply

var newGame = {
    pick: [1,2,3,4],
    reserve: [10,11,12]
};
newGame.reserve.push.apply(newGame.reserve, newGame.pick.splice(0, newGame.pick.length).reverse());
console.log(newGame);
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Nice!! This works perfectly! And no I don't need it it reversed. Looking at @TylerRoper's answer it appeared I would have needed to do that since that code removed items from the end of the array, thusly 'reserve' would have ended up backwards, but this method doesn't do that. Thank you!! Sidenote: people need to get up to speed with this `...` syntax 'cause in two months of studying javascript this is my first time hearing about it.. myself included, obviously... – panrosmithe Jul 14 '18 at 04:19
  • and by people, I mean youtuber's who provide tutorials on javascript as well as W3Schools!! – panrosmithe Jul 14 '18 at 04:21
  • w3schools is a joke - and youtubers problem is there's so much garbage out there it's hard finding the actual knowledgable ones :p – Jaromanda X Jul 14 '18 at 04:43