0

I'm trying to create a simple memory game with Javascript and I've created an array of letters to match for the game however, I'm having trouble figuring out how to actually assign a single letter to each cell of the table which functions as the board.

<html>
<head>
    <style>
    td {
        background-color: red;
        width:100px;
        height:100px;
        border:1px solid black
    }
    </style>
    <table>
        <tr>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
        </tr>
        <tr>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
        </tr>
        <tr>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
        </tr>
        <tr>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
            <td id = "tile" onClick = "revealLetter()"></td>
        </tr>
    </table>
<script>
var letters = ['A','A','B','B','C','C','D','D','E','E','F','F','G','G','H','H'];
var square_values = [];
var square_ids = [];
var i = letters.length, j, temp;
while(--i > 0) {
    j = Math.floor(Math.random() * (i+1));
    temp = letters[j];
    letters[j] = letters[i];
    letters[i] = temp;
}

</script>
</head>
<body>

</body>
</html>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Glaz
  • 109
  • 1
  • 3
  • 10
  • Are you getting errors? Rather than leaving it to use to parse through the code, please try to be more specific about what is and isn't working. Please revise the question. – Difster Jul 27 '17 at 23:13
  • Also, you don't have a function called `revealLetter()` in your javascript code. – Difster Jul 27 '17 at 23:16
  • I'm asking if it's possible to assign a single element from my array to each cell of the table, so say when the user clicks a cell it would reveal a letter from the array. – Glaz Jul 27 '17 at 23:16
  • you shouldn't use the same `id` attribute on different elements. If you need to do that, use `class` – aug Jul 27 '17 at 23:17

2 Answers2

1

I would suggest a slightly different approach. Rather than building the table and then putting in the letters, I've written a function that builds your grid based on a a randomised array. I borrowed a function from this question to randomise the array. Then I've added event listeners to 'turn over' the cards, by changing their values to their data-letter property.

I've not written the rest of the game logic - I didn't want to tread on your toes! obviously you'd want to make it so that if you turned two over that didn't match, they go back and you try again, but if they did, they'd stay showing - I'm sure you can work the logic and amend my function which adds event listeners.

buildGrid();

//global
var a, b = '';


function buildGrid() {
  var letters = ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'F', 'G', 'G', 'H', 'H'];
  var randomised = shuffle(letters);
  var num_letters = randomised.length;
  var str_tbl = '';

  while (num_letters >= 4) {
    str_tbl += '<tr>';
    for (var i = 0; i < 4; i++) {
      str_tbl += '<td data-letter="' + randomised[i] + '">?</td>';
    }
    str_tbl += '</tr>';
    ranomdised = randomised.splice(0, 4);
    num_letters -= 4;
  }

  var tbl = document.createElement('table');
  tbl.innerHTML = str_tbl;
  document.getElementsByClassName('grid')[0].appendChild(tbl);
  addEventListeners();
}

function addEventListeners(){

 var tds = document.getElementsByTagName( 'td' );
  
  for( var i = 0; i < tds.length; i++  ){
   tds[i].addEventListener( 'click', function(){
     this.innerHTML = this.getAttribute( 'data-letter');
      this.className += ' chosen';
    });
  }

}


// borrowed from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
function shuffle(array) {
  var currentIndex = array.length,
    temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}
td {
  background-color: #cccccc;
  text-align: centre;
  padding: 20px;
  height: 100px;
  width: 100px;
  color: #333333;
  font-family: helvetica, arial, sans-serif;
  font-size: 30px;
  font-weight: bold;
  cursor: pointer;
}

td:hover {
  background-color: #dddddd;
}

td.chosen {
  background-color: lightblue;
}
<div class="grid"></div>
sauntimo
  • 1,531
  • 1
  • 17
  • 28
  • okay I actually quite enjoyed having a go at some of the logic. Hear's a fiddle with a basic workable game and move counter https://jsfiddle.net/sauntimo/dhmmLujp/ – sauntimo Jul 28 '17 at 01:15
0

You need to pass parameters from clicking on the table to your click handler code, to indicate which table element has been clicked and its position in the letter array.

There are many ways of doing this, including using Event objects, but here's a simple idea to start out with.

  1. Remove all the id attributes. They should not be duplicated anyway.
  2. Change each "onclick=" code snippet to send what element has been clicked and the subscript to use. So the "onclick" specifications look like

    onclick="revealLetter( this, 0)"
    // through to
    onclick="revealLetter( this, 15)"
    

Then code revealLetter to take them as parameters:

function revealLetter( tdElement, subscript) {
// where tdElement is the table data element clicked, and
// subscript is a subscript to look its letter up in an array
// ... insert code here

As stated there are many ways of doing this but you may be able to use this fairly simple approach whilst gaining more experience.

Don't forget to look up "innerHTML" and "textContent" on, say, MDN or W3Schools if you haven't heard of them. (They are properties of HTML elements)

traktor
  • 17,588
  • 4
  • 32
  • 53