JSFiddle - React, Tailwind, and code Playground

by Mert Ener

HTML

<div class="playercontainer">
  <div class="playerone">
    <div class="palyer">
      P1
    </div>
    <div class="score" id="score1">
      0
    </div>
  </div>
  <div class="playertwo">
    <div class="palyer">
      P2
    </div>
    <div class="score" id="score2">
      0
    </div>
  </div>
  <div id="msgbox"></div>
</div>
<div class="container">
  <div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
    </div>
  </div>
</div>
<div class="card">
  <div class="flip-card-inner">
    <div class="flip-card-front">
    </div>
    <div class="flip-card-back">
   ...

CSS

.playercontainer {
   font-family: Impact, sans-serif;
   display: flex;
   gap: 50px
}
.playerone{
  color:red
}
.playertwo{
  color:green
}
.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  gap: 10px;
}

.card {
  background-color: transparent;
  height: 40px;
  width: 40px;
  perspective: 1000px;
  
}

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transform-style: preserve-3d;
}

.flip-card-front, .flip-card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  background-color: lightgray;
  border: 1px solid black;
}

.flip-card-back {
  font-family: Arial, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: rotateY(180deg);
}

@keyframes flip {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(180deg);
  }
}
@keyframes hide {
  0% {
    transform: rotateY(180deg);
  }
  100% {
    transform: rotateY(0deg);
  }
}
.flipped {
  animation: ease-out flip 0.45s both;
}
.hide {
  animation: linear hide 0.25s both;
}

JavaScript

let cards = document.querySelectorAll(".flip-card-inner")
let array
let sharedMemory

function shuffle() {
  array = []
  sharedMemory = []
  let selected
  let number

  for (let i = 0; i < 10; i++) {
    do {
      selected = false
      number = Math.floor(Math.random() * 10) + 1
      for (let j = array.length - 1; j >=0; j--) {
        if (number === array[j]) {
          selected = true
        }
     }
    } while (selected)
    array.push(number)
    cards[i].lastElementChild.textContent = number
  }
}

function playerGuess() {
    let picked
    let pick

    do {
      picked = false
      pick = Math.floor(Math.random() * 10)
      for (let i = 0; i < sharedMemory.length; i++) {
        if (pick === sharedMemory[i][0]) {
          picked = true
        }
      }
    } while (picked)
  return pick
}

async function reveal(sequence) {
  let inSequence

  do {
    inSequence = false
    for (let i = 0; i < sharedMemory.length; i++) {
      if (sharedMemory[i][1] === sequence) {
        inSequence = true
        await flipCardAsync(sharedMemory[i][0])
        sequence++
      }
    }
  } while (inSequence)
  return sequence
}

function updateActivePlayerIndicator(activePlayer) {
  const playerOneDiv = document.querySelector(".playerone")
  const playerTwoDiv = document.querySelector(".playertwo")

  if (activePlayer === 1) {
    playerOneDiv.style.backgroundColor = "yellow"
    playerTwoDiv.style.backgroundColor = ""
  } else {
    playerOneDiv.style.backgroundColor = ""
    playerTwoDiv.style.backgroundColor = "yellow"
  }
}

function flipCardAsync(card) {
  return new Promise((resolve) => {
    const element = cards[card]
    const cleanup = () => {
      clearTimeout(fallback)
      element.removeEventListener("animationend", onAnimationEnd)
      resolve()
    }
    const onAnimationEnd = () => {
      cleanup()
    }
    const fallback = setTimeout(cleanup, 500)
   ...