How to flip the cards in this game if there is no match? It tells me, random is not a function

0

I would like to know how to do so that the cards are returned IF THERE IS NO MATCH, the game draws cards random once it is clicked. But I do not know why he tells me that mistake. The same if I do

cardsInPlay[0].setAttribute('src', 'images/back.png') 

and

cardsInPlay[1].setAttribute('src', 'images/back.png') 

does not work either. Also (in a primitive way) I tried to pass the this as a parameter stored in a variable to be able to turn it over since it is the only way it works (BUT ONLY IT TURNS TO THE LAST LETTER TO WHICH I DO CLICK), I tried this since the envelope this (the current element) is the only way to let me do setAttribute , but I want both letters to turn over. I'm new to this, could someone help me? Thank you very much

//GLOBAL VARIABLES
var box = document.getElementById('box');
var cardElement;
var cardsInPlay= [];
var random;
//1. OBJETOS DE CARTAS EN ARRAY
var cards = [
  {
    rank: 'king',
    pic: 'images/king-of-diamonds.png'
  },
  {
    rank: 'king',
    pic: 'images/king-of-hearts.png'
  },
  {
    rank: 'queen',
    pic: 'images/queen-of-diamonds.png'
  },
  {
    rank: 'queen',
    pic: 'images/queen-of-hearts.png'
  }
];

//1. CREAR LA MESA
function createBoard(){
  for (var i = 0; i < cards.length; i++) {
    cardElement = document.createElement('img');
    cardElement.setAttribute('src', 'images/back.png');
    box.appendChild(cardElement);
    cardElement.addEventListener('click', flipCardAndRandomize);
  }
}
createBoard();

//2. DAR LA VUELTA A LAS CARTAS YA DE FORMA RANDOM
function flipCardAndRandomize(){
  //Randomizar baraja =>
  random = Math.floor(Math.random()*cards.length);
  console.log(random);
  this.setAttribute('src', cards[random].pic);
  cardsInPlay.push(cards[random].rank);
  var miThis = this;
  match(miThis);
}
//3. VER SI HAY MATCH
function match(miThis){
  if (cardsInPlay.length === 2) {
    if (cardsInPlay[0] === cardsInPlay[1]) {
      alert('MATCH');
    } else {
      alert('TRY AGAIN');
      darVuelta(miThis);

      // random.setAttribute('src', 'images/back.png'); //// QUIERO VOLTEAR DE NUEVO SI NO HAY MATCH
      // random.setAttribute('src', 'images/back.png'); //// QUIERO VOLTEAR DE NUEVO SI NO HAY MATCH

    }
  }
  function darVuelta(miThis){
    miThis.setAttribute('src', 'images/back.png')
  }

}
#box{
  background-color: lightblue;
  height: 250px;
  width: 700px;
  margin: 0 auto;
  margin-top: 50px;
}
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="css/style.css">
    <meta charset="utf-8">
    <title>CARDS</title>
  </head>
  <body>
    <div id="box">
    </div>
    <script src="js/main.js" charset="utf-8"></script>
  </body>
</html>
    
asked by fran 06.12.2017 в 19:51
source

1 answer

1

There are quite a few problems in your code.

On the one hand, you randomly calculate the card to be shown at the moment you click on it, so each time you click on the card it will be recalculated, showing a different card in the same position each time.

On the other hand, in the array cardsInPlay you only store the letter types shown (the property rank ) so you can not know what img concrete elements are being displayed. This way you can not turn them over again.

Here is an example of how you could put your code.

To establish the images of the cards (the back or the front) I use css classes.

To identify each of the elements img and maintain a correspondence with the elements of the array board I set in the elements img a data-attribute cardIndex .

In the cardsInPlay array I keep, for each letter, both the img element and the index in the array board .

I hope it serves you.

//GLOBAL VARIABLES
var cardsInPlay= [];
var cards = ['minion1', 'minion2', 'minion3', 'minion4'];
var board;

//1. CREAR LA MESA
function createBoard(){
  // Crea un array con dos elementos de cada carta
  var allcards = cards.reduce((prev, item) => { prev.push(item); prev.push(item); return prev; },
    []);
  // randomize. Crea un array con todas las cartas repartidas de forma aleatoria
  board = [];
  while(allcards.length){
    board.push(allcards.splice(Math.floor(Math.random() * allcards.length), 1)[0]);
  }
  // Crea los elementos del DOM
  var box = document.getElementById('box');
  for (var i = 0; i < board.length; i++) {
    cardElement = document.createElement('img');
    // Se establece la clase para mostrar las cartas dadas la vuelta
    cardElement.className = 'back';
    // Establecemos un data-atributo "cardIndex" para identificar la carta
    // con el índice del array board
    cardElement.dataset.cardIndex = i;
    box.appendChild(cardElement);
    // Al hacer click llama a filpCard
    cardElement.addEventListener('click', flipCard);
  }
}

// Da la vuelta a la carta "clickada"
function flipCard(){
  // Recuperamos el índice de la carta pulsada del data-atributo "cardIndex"
  var cardIndex = parseInt(this.dataset.cardIndex);
  // Coge la clase a utilizar (imagen a mostrar) del array board
  this.className = board[cardIndex];
  // Añade la carta a las actualmente seleccionadas
  cardsInPlay.push({cardElement: this, cardIndex: cardIndex});
  // Comprueba si hay "match"
  // Se llama con setTimeout para dejar que el navegador muestre la carta girada primero
  setTimeout(testMatch, 100);
}

// Comprueba si hay pareja
function testMatch(){
  // Si no se han seleccionado dos cartas no hace nada
  if (cardsInPlay.length < 2) return;
  // Comprueba si las cartas seleccionadas son iguales y llama
  // a la función correspondiente
  if (board[cardsInPlay[0].cardIndex] === board[cardsInPlay[1].cardIndex]){
    match();
  }
  else{
    tryAgain();
  }
}

// Hay pareja
function match(){
  alert('match');
  // Eliminamos el controlador del evento click de las cartas 
  cardsInPlay[0].cardElement.removeEventListener('click', flipCard);
  cardsInPlay[1].cardElement.removeEventListener('click', flipCard);
  // Inicia una nueva jugada
  cardsInPlay = [];
}

// No hay pareja
function tryAgain(){
  alert('try again');
  // Se da vuelta a las dos cartas
  cardsInPlay[0].cardElement.className = 'back';
  cardsInPlay[1].cardElement.className = 'back';
  // Inicia una nueva jugada
  cardsInPlay = [];
}

createBoard();
#box{
  background-color: lightblue;
  height: 205px;
  width: 410px;
  margin: 0 auto;
  margin-top: 50px;
}

#box img{
  width: 100px;
  height: 100px;
  border: solid 1px #333333;
}
#box img.minion1{
  content: url('http://www.abc.net.au/news/image/6473316-3x2-940x627.jpg');
}
#box img.minion2{
  content: url('https://images-na.ssl-images-amazon.com/images/I/81NVMGw45QL._SL1500_.jpg');
}
#box img.minion3{
  content: url('http://vignette3.wikia.nocookie.net/despicableme/images/1/1d/Kevin_minions.png/revision/latest?cb=20160929061515');
}
#box img.minion4{
  content: url('https://vignette.wikia.nocookie.net/despicableme/images/2/2b/Stuart.png/revision/latest?cb=20161108162855');
}
#box img.back{
  content: url('https://n6-img-fp.akamaized.net/vector-gratis/textura-de-papel-arrugado_1100-12.jpg?size=338c&ext=jpg');
}
<div id="box">
</div>
    
answered by 22.12.2017 в 10:47