JSFiddle - React, Tailwind, and code Playground

by Gwyn Milcote

HTML

<div id="content">
  <div id="cardPile"></div>
  <div id="cardSlots"></div>
  
  <div id="successMessage">
    <h2>You did it!</h2>
    <button class="restart">Play Again!</button>
  </div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js'></script>

CSS

#content {text-align: center;-moz-user-select: none;-webkit-user-select: none;user-select: none;}

.wideBox {
  clear: both;
  text-align: center;
  margin: 70px;
  padding: 10px;
  background: #ebedf2;
  border: 1px solid #333;
}

/* Slots for final card positions */

#cardSlots {
  margin: 50px auto 0 auto;
  background: #ddf;
}

/* The initial pile of unsorted cards */

#cardPile {
  margin: 0 auto;
  background: #ffd;
}

#cardSlots, #cardPile {
  width: 500px;
  height: 320px;
  padding: 10px;
  border: 2px solid #333;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  -moz-box-shadow: 0 0 .3em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .3em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .3em rgba(0, 0, 0, .8);
}

/* Individual cards and slots */

#cardSlots div, #cardPile div {
  display:inline-table;vertical-align:top;
  width: 70px;
  height: 90px;
  padding: 5px;
  padding-top: 20px;
  padding-bottom: 0;
  border: 2px solid #333;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  margin: 5px;
  background: #fff;
}

#cardSlots div:first-child, #cardPile div:first-child {
  margin-left: 0;
}

#cardSlots div.hovered {
  background: #aaa;
}

#cardSlots div {
  border-style: dashed;
}

#cardPile div {
  background: #666;
  color: #fff;
  font-size: 50px;
  text-shadow: 0 0 3px #000;
}

#cardPile div.ui-draggable-dragging {
  -moz-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
  box-shadow: 0 0 .5em rgba(0, 0, 0, .8);
}

/* Individually coloured cards */

.card .correct { background: red; color:red;}


#successMessage {
  position: absolute;
  left: 580px;
  top: 250px;
  width: 0;
  height: 0;
  z-index: 100;
  background: #dfd;
  border: 2px solid #333;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  -moz-box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);
  -webkit-box-shadow: .3em .3em .5em rgba(0, 0, 0, .8);
  box-shadow: .3em...

JavaScript

var correctCards = 0;
$( init );

$('.restart').click(function(){ init(); });

function init() {

  // Hide the success message
  $('#successMessage').hide();
  $('#successMessage').css( {
    left: '580px',
    top: '250px',
    width: 0,
    height: 0
  } );

  // Reset the game
  correctCards = 0;
  $('#cardPile').html('');
  $('#cardSlots').html('');

  // out of 50, get 10 random numbers
  var npcs = Array.from({length:50},(v,k)=>k*1);
  var shuffled = npcs.sort(function(){
    return 0.5 - Math.random();
  });
  var numbers = shuffled.slice(0,10);
  
  // Create the pile of shuffled cards.
  
  for ( var i=0; i<10; i++ ) {
    // writing number in div. later add image
    $('<div>' + numbers[i] + '</div>').data( 'number', numbers[i] ).attr( 'class', 'card' ).appendTo( '#cardPile' ).draggable( {
      containment: '#content',
      stack: '#cardPile div',
      cursor: 'move',
      revert: true
    } );
  }

  // Create the card slots, in original order 
  
  var words = numbers;
  
  for ( var j=1; j<=10; j++ ) {
    $('<div>a' + words[j-1] + '</div>').data('number', j ).appendTo( '#cardSlots' ).droppable( {
      accept: '#cardPile div',
      hoverClass: 'hovered',
      drop: handleCardDrop
    } );
  }

}

function handleCardDrop(event, ui) {
  
  //Grab the slot number and card number
  var slotNumber = $(this).data('number');
  var cardNumber = ui.draggable.data('number');
  
  //If the cards was dropped to the correct slot,
  //change the card colour, position it directly
  //on top of the slot and prevent it being dragged again
  if (slotNumber === cardNumber) {
    ui.draggable.addClass('correct');
    ui.draggable.position({
      of: $(this), my: 'left top', at: 'left top'
    });
    ui.draggable.draggable('disable');
    $(this).droppable('disable');
    //This prevents the card from being
    //pulled back to its initial position
    //once it has been dropped
    ui.draggable.draggable('option', 'revert', false);
    correctCards++;...