2

I have an array of PAIRS of 25 images (meaning a total of 50 images) each image path being in its own associative array.

const cardArray = [
    { name:'A', img:'images/A.jpg' },
    { name:'A', img:'images/A.jpg' },
    { name:'B', img:'images/B.jpg' },
    { name:'B', img:'images/B.jpg' },
    { name:'C', img:'images/C.jpg' },
    { name:'C', img:'images/C.jpg' },
    ...
    ... (bla bla bla, up to 25 times)
  ]

I know that if I have exactly 8 pairs then the function I can use is:

cardArray.sort(() => 0.5 - Math.random())

What I'd like to do is to randomly select 8 pairs of these images, then shuffle them like in a memory match game. How do I make it so that every time the user reloads the browser, different pairs of images from the array will load instead of the same 8 ones every time?

Thanks.

AbsoluteBeginner
  • 2,160
  • 3
  • 11
  • 21
Jim L
  • 21
  • 3
  • 6
    Why don't you start with 25 items instead of 25 pairs. Then you can shuffle the 25 items, pull off the top 8, and *then* make pairs from those 8. – Mark Feb 28 '21 at 05:07
  • 2
    Sorting with `cardArray.sort(() => 0.5 - Math.random())` is probably not a great idea. The comparator function is supposed to return the same result given the same elements, and the distribution with this comparator is not guaranteed to be uniform. That is, some orderings may be more likely than others. See https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array for a more efficient and proper shuffling algorithm, and then use the previous commenter's suggestion. – jeffkmeng Feb 28 '21 at 05:10
  • 1
    In addition to the info from @jeffkmeng, there's a good thread about this approach to shuffling here: https://stackoverflow.com/questions/962802/is-it-correct-to-use-javascript-array-sort-method-for-shuffling/19896494 – Mark Feb 28 '21 at 05:14
  • You may also want to consider using an npm module if you don't want to directly implement the algorithm described in the post referenced above https://www.npmjs.com/package/shuffle-array – greenBox Feb 28 '21 at 05:24

2 Answers2

1

To select one card at random out of the card array it would just be:

const randomCard = Math.floor(Math.random() * cardArray.length);
Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
dkburd
  • 1
  • 4
1

The following will get you a random selection of 8 pairs of images from a total of 25 possible choices. The 16 images are then presented in a random order.

function shuffle(a,n){ // shuffle array a in place (Fisher-Yates)
 let m=a.length;
 n=n||m-1;
 for(let i=0,j;i<n;i++){
  j=Math.floor(Math.random()*(m-i)+i);
  if (j-i) [ a[i],a[j] ] = [ a[j],a[i] ]; // swap 2 array elements
 }
}
const a=[...new Array(25)].map((v,i)=>i);
shuffle(a,8);  // array of indices, like  [ 2, 13, 0, 7, 5, 24, 19, 8, ... ]
let sel=a.slice(0,8).map(k=>  // array of 8 image paths
 "images/"+String.fromCharCode(k+65)+".jpg");
sel=sel.concat(sel);          // double the array ...
shuffle(sel);                 // ... and shuffe it again

console.log(sel);
.as-console-wrapper {max-height: 100%  !important}

The approach is based on an array shuffle algorithm (Fisher-Yates) which I apply only for the first 8 elements. These elements are then extracted and presented as uppercase characters.

I took the liberty of rearranging your images object as an array of image names. The images are now picked twice (sel.concat(sel)) and shuffled again to present them in a random order.

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43