0

this is my first post and I'm freshly new to programming.

As prep work for school, I'm designing a match game. I added a reset function that should flip the cards when the match is checked. The problem is the checkForMatch (and the relative alert) and the reset start before the second card image is replaced. Like attached screenshot.

Thank you in advance!

screenshot

var cards = [
    {
    rank:"Queen",
    suit: "Hearts",
    cardImage: "images/queen-of-hearts.png"
    },
    {
    rank: "Queen",
    suit: "Dimonds",
    cardImage: "images/queen-of-diamonds.png"
    },
    {rank: "King",
    suit: "Hearts",
    cardImage: "images/king-of-hearts.png"
    },
    {
    rank: "King",
    suit: "Diamonds",
    cardImage: "images/king-of-diamonds.png"
    }
];
var cardsInPlay = [];

function checkForMatch() {
    if (cardsInPlay[0] === cardsInPlay[1]) {
        alert("You found a match!");
    }
    else {
        alert("Sorry, try again.");
    }
    
}


var flipCard = function () {
    var cardId = this.getAttribute("data-id"); //double check this
    console.log("User flipped over " + cards[cardId].rank);
    console.log(cards[cardId].suit);
    console.log(cards[cardId].cardImage);
    cardsInPlay.push(cards[cardId].rank);
    this.setAttribute('src',cards[cardId].cardImage);// double check
    if (cardsInPlay.length === 2) {
        checkForMatch();
        reset();      
    }
  
}

var createBoard = function () {
    for (var i=0; i < cards.length; i++) {
        var cardElement = document.createElement('img');
        cardElement.setAttribute('src','images/back.png');
        cardElement.setAttribute('data-id',i);
        cardElement.addEventListener('click',flipCard);
        document.getElementById('game-board').appendChild(cardElement);
    }
    
}
createBoard();


var reset = function () {
    var card = document.getElementsByTagName('img');
    cardsInPlay = [];
    for (i = 0; cards.length; i++) {
        if (card[i].getAttribute('src') != 'images/back.png') {
            card[i].setAttribute('src', 'images/back.png');
        }
    }
}
body {
    text-align: center;
    margin: 0;
}

h1 {
    font-family: Raleway;
    color: white;
    letter-spacing: 1px;
    font-weight: 400;
    font-size: 45px;
    margin: 0;
}

a {
    font-family: Raleway;
    letter-spacing: 1px;
    font-weight: 400;
    font-size: 18px;
    border-bottom: 2px solid transparent;
}

a:hover {
   border-bottom: 2px solid white;
  }

h2 {
    font-family: Raleway;
    color: #0d2c40;
    letter-spacing: 1px;
    font-weight: 600;
    font-size: 20;
}

p {
    font-family: "Droid Serif";
    line-height: 26px;
    font-size: 18px; 
}

header {
    background-color: #F15B31;
    padding: 30px 20px;
}

main {
    width: 850px;
    margin: 35px auto;
}

nav {
    background: #00A6B3;
    padding:20px 0;
}

.navlink {
    margin:0 20px;
    color: white;
} 

img {
    margin: 40px 8px;
}

footer {
    background-color:#0D2C40;
    text-transform: uppercase;
    padding: 0 20px;
    color: white;
    font-size: 14px;
    letter-spacing: .08em;
    font-weight: 500;
}

.copyright {
    font-family: Raleway, sans-serif;
    float: left;
}

.message{
    font-family: Raleway, sans-serif;
    float: right;
}

.clearfix:after {
    visibility: hidden;
    display: block;
    content: " ";
    clear: both;
    height: 0;
    font-size: 0;
  }

  .name {
      color:#F15B31;
      font-weight: 700;
  }
<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="style.css" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Droid+Serif|Raleway:400,500,600,700" rel="stylesheet">
    <title>Marco's memory game</title>
</head>

<body>
    <header>
        <h1>Marco's memory game</h1>
    </header>
        <nav>
            <a class="navlink" href="#instructions">Instructions</a>
            <a class="navlink" href="#facts">Game facts</a>
            <a class="navlink" href="#game-board">Play!</a>

        </nav>

    
    <main>
        <h2 id="instructions">Instructions</h2>
        <p>Concentration, also known as Match Match, Memory, Pelmanism, Shinkei-suijaku, Pexeso or simply Pairs, is a card game
            in which all of the cards are laid face down on a surface and two cards are flipped face up over each turn. The
            object of the game is to turn over pairs of matching cards.</p>

        <h2 id="facts">Game's facts</h2>
        <p>An other popular memory game is called "Kim's game. Kim's Game is a game or exercise played by Boy Scouts, Girl Scouts
            and Girl Guides, and other children's groups.[1] The game develops a person's capacity to observe and remember
            details. The name is derived from Rudyard Kipling's 1901 novel Kim, in which the hero, Kim, plays the game during
            his training as a spy.
            <a href="https://en.wikipedia.org/wiki/Kim%27s_Game">More info...</a>
        </p>

        <div id="game-board" class="board clearfix"></div>
    </main>
    <footer class="clearfix">

        <p class="copyright">Copyright 2017</p>
        <p class="message">Created with &hearts; by <span class="name"> GA </span></p>
        
       
    </footer>


    <script src="js/main.js"></script>
</body>

</html>
HoldOffHunger
  • 10,963
  • 6
  • 53
  • 100
Marco
  • 65
  • 1
  • 8
  • 1
    console log cardsInPlay.length right before you evaluate it and see what the output is. Might also want to console log the array itself. Also, not pertinent to your question but if cardsInPlay is an array of objects then evaluating two objects is generally not consistent and you should check if their IDs match or some other predictable property – Robbie Milejczak Oct 30 '17 at 15:20
  • it will help if you provide a minimal example including the html and css so we can check our own solutions to make sure you get a solid answer. https://stackoverflow.com/help/mcve – Andrew Lohr Oct 30 '17 at 15:29
  • @Marco assuming that the images are already loaded as files, just using a setTimeout should work. `setTimeout(checkForMatch, 10);` would wait for 10 milliseconds. Try that. – TKoL Oct 30 '17 at 15:30
  • If you're talking about waiting for the actual jpg or png file to load, then that's a different issue. You might want to load the files before-hand in preparation, eg put some img elements into a hidden DIV. They will load in the background and be ready most likely by the time you need them. – TKoL Oct 30 '17 at 15:31
  • @AndrewLohr i added the whole code – Marco Oct 30 '17 at 15:39
  • @TKoL no it doesn't work :/ – Marco Oct 30 '17 at 15:42
  • What doesn't work about it? Have you tried increasing the number 10 to 100? 1000? – TKoL Oct 30 '17 at 15:43
  • Also the console report this error Uncaught TypeError: Cannot read property 'getAttribute' of undefined at reset (main.js:67) at HTMLImageElement.flipCard (main.js:45) but it works correctly. – Marco Oct 30 '17 at 15:44
  • 1
    @TKoL there's also `onload` (or `.addEventListener("load", …)`) for images, should be more reliable than using `setTimeout`. – helb Oct 30 '17 at 15:46
  • @Marco Where/how are you calling the `flipCard` function? I don't see it anywhere in your code. – helb Oct 30 '17 at 15:47
  • @TKoL the setTimeOut doesn't at any delay. I'm trying the onload. – Marco Oct 30 '17 at 15:53
  • @helb, I uploaded again the full code, sorry I'm new to SO – Marco Oct 30 '17 at 15:53
  • I agree with @helb. Using an event listener with a callback function is more reliable than just arbitrarily guessing the number of milliseconds the image is going to take to load - that time is going to vary. – Tom O. Oct 30 '17 at 16:05
  • @Marco The problem is probably caused by `this` in your `flipCard` function – it doesn't refer to the image element. It should work if you change the definition to `var flipCard = function (event) {` and then use `event.target` for referring to img (eg. `var cardId = event.target.getAttribute("data-id")`). For more details about 'this' in js, see https://stackoverflow.com/a/3127440/3776299 – helb Oct 30 '17 at 16:19
  • @TKoL thank you, it worked with setTimeout(checkForMatch, 10); at my first try I used a wrong syntax . – Marco Oct 30 '17 at 18:06

0 Answers0