2

I'm quite new both to programming and to this community, I'll try to be as clear as possible. I need to create an HTML table 16x16 with a button in every cell that displays a different image - a smiley - per cell, without ever showing the same smiley for different cells. I'm a bit stuck and I would also appreciate a hint, just to try and move on on my own. Thanks! Here is my code that creates the table and displays the image:

function displayImage(){
    var num = Math.floor(Math.random() * 256);
    document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
    document.getElementById("YourImage").style.visibility = "visible";
}
for(var r = 0; r < rows;r++)
{
    table += '<tr>';
    for(var c= 0; c< cols;c++)
    {
        table += '<td style="width:50px" id="(i++)">' + '<button type="button" onclick="displayImage()">' +
        "show me" + '</button>' + '</td>';
     }
     table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');

(ImagesArray is not shown for readability but it simply collects all 256 binary combinations). The problem with this is that each time I click on a button it displays a random image and if I click again on the same button it shows another one, while I'd like it to show me always the same image for the same button. NOTE: I cannot delete the button afterwards or similar tricks, as the player (it's an oTree experiment) needs to be able to go back to a smiley he saw any time. Thanks a lot for your help!

RexE
  • 17,085
  • 16
  • 58
  • 81
DenisDiderot
  • 57
  • 1
  • 9
  • you should create a random array for image numbers (for each row,col) and store them in an array. then use that info when you want to display image on button_click – S.Serpooshan Jan 07 '17 at 10:17
  • Thanks for the reply @S.Serp , but I'm struggling to understand (much likely my fault as it's less than a month that I use HTML and JS). You would suggest to create an array with the row,col coordinates and use it to uniquely connect a binary code (in my case something like 00110011, 01010101,...) to each row,col coordinate? But how? – DenisDiderot Jan 07 '17 at 10:35
  • i have posted an answer, look and say your comment or any question – S.Serpooshan Jan 07 '17 at 11:25

2 Answers2

1

I would change the point where the random number is generated and advance it from the display function to the initialization of the table.

Create an array with the numbers from 0 to 255. While looping through rows and columns to create the table, pick one random number from that array and assign it to the button's id attribute. Be sure to remove this number from the array, so it can't be used again for the following buttons. This way every of the 256 numbers will be used, but in random order. When a user clicks a button, with displayImage(this.id) the button's id is used as a parameter to call displayImage(). Thus always the same number of the button will be used the fetch the according image.

The code:

// call displayImage() with parameter
function displayImage(num){
    document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
    document.getElementById("YourImage").style.visibility = "visible";
}

// create array 'nums' with numbers from 0 to 255 (= rows * cols)
var nums = [];
for (var i = 0; i < (rows * cols); i++) {
    nums.push(i);
};

for(var r = 0; r < rows; r++)
{
    table += '<tr>';
    for(var c = 0; c < cols; c++)
    {
        // get random index in array 'nums'
        var random = Math.floor(Math.random() * nums.length);
        // assign an id to the button with a random number from 'nums' and use this id in displayImage()
        table += '<td style="width:50px" id="(i++)">' + '<button id="' + nums[random] + '" type="button" onclick="displayImage(this.id)">' +
        "show me" + '</button>' + '</td>';
        // remove the already used random number from 'nums'
        nums.splice(random, 1);
     }
     table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');

This way you will have the same image connected to every button. It's randomized while creating the table, so the order is different every time you load the page.

I assume you are using HTML5 because only then it is permitted that id attributes consists only of digits.

Note: I don't know what exactly you want to achieve with id="(i++)" when creating the <td> element. The way you do it just names every id with the string (i++) which contradicts the idea that ids should be unique. If you want to name the ids ascending from for example td-0 to td-255 you should change the line to:

table += '<td style="width:50px" id="td-' + (r * rows + c) + '">' + '<button id="' + nums[random] + '" type="button" onclick="displayImage(this.id)">' + "show me" + '</button>' + '</td>';

You can't just use the numbers without adding something like td-, because the buttons already have pure numbers as id.

FridoDeluxe
  • 186
  • 2
  • 7
  • in your implementation, you may have two or more buttons with same image number! this is not totally unique! – S.Serpooshan Jan 07 '17 at 11:06
  • @S.Serp Really? In the loop numbers used for a button are instantly removed with `nums.splice()` so they can't be used twice (if I'm not missing anything). – FridoDeluxe Jan 07 '17 at 11:31
  • oh yes, i didn't note that – S.Serpooshan Jan 07 '17 at 11:45
  • Great solution! My problem was with the id of the button basically, I was missing the "this.id" part and messing up with the identification (I saw the i++ somewhere but I wasn't super convinced it would have worked. Thanks a lot guys, I hope I will be as useful at some point to reciprocate ;) – DenisDiderot Jan 07 '17 at 15:06
1

try this:

var rows = 16, cols = 16;
var table = '';

function shuffle(array) { // shuffle (randomize) array elements
  var i = array.length, j, x;
  while (i) {
    j = Math.random() * i-- | 0;
    x = array[i];
    array[i] = array[j];
    array[j] = x;
  }
}

var rNums = new Array(rows * cols);
for (var i = 0; i < rows * cols; i++) {
  rNums[i] = i;
}
shuffle(rNums);

function displayImage(num) {
  //var num = Math.floor(Math.random() * 256);
  document.canvas.src = '../../output/'+ imagesArray[num]+ '.png';
  //document.getElementById("canvas").innerHTML = num;
  document.getElementById("YourImage").style.visibility = "visible";
}

var i = 0;

for (var r = 0; r < rows; r++) {
  table += '<tr>';
  for (var c = 0; c < cols; c++) {
    table += '<td style="width:50px" id="' + i + '"><button type="button" onclick="displayImage(' + rNums[i] + ')">show me</button></td>';
    i++; //go to next element of rNums array
  }
  table += '</tr>';
}
document.write('<table id="grid" border="1">' + table + '</table>');
S.Serpooshan
  • 7,608
  • 4
  • 33
  • 61