1

Below is the code to create a 6x6 grid that is randomly populated with white/black squares. At the moment when you click on a square, in console it displays the position of within an array of a given square. What I am struggling with is to make it flip the color once you click on a square (eg. when you click on a white square, it becomes black, etc.). The change should also update the array as in the end I will be checking whether the resulting patter has a line of symmetry.

// Create canvas
var canvas = document.getElementById('canvas');
ctx = canvas.getContext("2d");

var canvasCreate = function(w, h) {
    canvas.width = w;
    canvas.height = h;
};

function resetCanvas() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawGrid(genArray(6));

}

// Generate a 6x6 array of 0s or 1s
function genArray(aSize) {
    a = new Array();
    for (var i=0;i<aSize;i++) {
        a[i] = new Array();
        for (var j=0;j<aSize;j++) {
            a[i][j] = Math.floor(Math.random() * 2);
        }
    }
    return a
}

function drawGrid(arr) {
    var n = 6;
    for (var i=0;i<n;i++) {
        for (var j=0;j<n;j++) {
            ctx.beginPath();
            ctx.strokeStyle = '#555';
            if (arr[i][j] === 1) {
                ctx.fillRect(i*50, j*50, 50, 50);
            }
            ctx.rect(i * 50, j * 50, 50, 50);
            ctx.stroke();
        }
    }

    // Get mouse position within canvas
    function mouseClick(e) {
        var mouseX, mouseY;

        if(e.offsetX) {
            mouseX = e.offsetX;
            mouseY = e.offsetY;
        }
        else if(e.layerX) {
            mouseX = e.layerX;
            mouseY = e.layerY;
        }
        var gridX = Math.floor(mouseX / 50);
        var gridY = Math.floor(mouseY / 50);
        console.log(gridX, gridY);

        var xy = arr[gridX][gridY];
        if (xy == 0) {
            xy = 1;
            console.log("white");
        }
        else if (xy == 1) {
            xy = 0;
            console.log("black");
        }
        //
    }
    canvas.addEventListener('mousedown', mouseClick, false);
};



arr = genArray(6);
canvasCreate(300, 300);
drawGrid(arr);

... and corresponding html:

<button onclick="resetCanvas()">Reset</button>
<canvas id="canvas"></canvas>

Edit: to show what I've tried:

var xy = arr[gridX][gridY];
        if (xy == 0) {
            xy = 1;
            console.log("white");
            drawGrid(arr);
        }
        else if (xy == 1) {
            xy = 0;
            console.log("black");
            drawGrid(arr);
        }

As you can see above, the position in the array is identified (eg. (0, 3)), then the value gets changed between 0 and 1 and the whole grid should get redrawn. It changes the colors of some squares, but not in a way I intended. Additionally (after a few clicks, it seems to choke a browser indicating that I'm doing something wrong.

Edit 2: Upon the comment below I've updated it to:

var xy = arr[gridX][gridY];
        if (xy == 0) {
            arr[gridX][gridY] = 1;
            console.log("white");
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            drawGrid(arr);
        }
        else if (xy == 1) {
            arr[gridX][gridY] = 0;
            console.log("black");
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            drawGrid(arr);
        }

Still it malfunctions and gets the browser not responsive.

Wasteland
  • 4,889
  • 14
  • 45
  • 91

1 Answers1

2

Below you will find working bit of code, but let me first go over everything that I changed:

  1. You had to many variables without var - it wasn't the source of the problem here but try to always use var (P.S I didn't go over all methods so check again)

  2. Removed use of new Array() - again wasn't the problem here but try to always use []

  3. Relevant to the problem - moved mouseClick out of drawGrid and the addEventListener so it is not called needlessly with every mouseclick

  4. Relevant to the problem - resetCanvas did not really reset anything since you forgot to save the new generated array in the arr variable.

  5. Saved the 1, 0 in arr not in xy

  6. Last but not least - drawGrid was only drawing black - added drawing white two. And added fun colors as example. Without this change white was flipping to black. But black wasn't flipping to white.

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext("2d");
    
    var canvasCreate = function(w, h) {
      canvas.width = w;
      canvas.height = h;
    };
    
    function resetCanvas() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      arr = genArray(6);
      drawGrid(arr);
    }
    
    // Generate a 6x6 array of 0s or 1s
    function genArray(aSize) {
      var a = [];
      for (i=0;i<aSize;i++) {
        a[i] = [];
        for (j=0;j<aSize;j++) {
          a[i][j] = Math.floor(Math.random() * 2);
        }
      }
      return a;
    }
    
    function drawGrid(arr) {
      var n = 6;
      for (var i=0;i<n;i++) {
        for (var j=0;j<n;j++) {
          ctx.beginPath();
          ctx.strokeStyle = '#555';
          if (arr[i][j] === 1) {
            ctx.fillStyle = '#faf';
            ctx.fillRect(i*50, j*50, 50, 50);
          } else {
            ctx.fillStyle = '#ffa';
            ctx.fillRect(i*50, j*50, 50, 50);
          }
          ctx.rect(i*50, j*50, 50, 50);
          ctx.stroke();
        }
      }
    };
    
    var arr = genArray(6);
    canvasCreate(300, 300);
    drawGrid(arr);
    
    // Get mouse position within canvas
    function mouseClick(e) {
      var mouseX, mouseY;
    
      if(e.offsetX) {
        mouseX = e.offsetX;
        mouseY = e.offsetY;
      }
      else if(e.layerX) {
        mouseX = e.layerX;
        mouseY = e.layerY;
      }
      var gridX = Math.floor(mouseX / 50);
      var gridY = Math.floor(mouseY / 50);
      console.log(gridX, gridY);
    
      var xy = arr[gridX][gridY];
      if (xy == 0) {
        arr[gridX][gridY] = 1;
        console.log("white");
      }
      else if (xy == 1) {
        arr[gridX][gridY] = 0;
        console.log("black");
      }
    
      drawGrid(arr);
    }
    
    canvas.addEventListener('mousedown', mouseClick, false);
    
Lehych
  • 166
  • 1
  • 12
Olga
  • 1,648
  • 1
  • 22
  • 31
  • Thank you. Works great. Love the colors:). Point number 2 - why is that so? – Wasteland Dec 26 '15 at 12:51
  • I think the main argument behind number 2 is that Array constructor is not very intuitive to use - that is how it changes it's behaviour depending on the arguments. So to avoid all this confusion and possible mistakes most agree not to use it. See this http://stackoverflow.com/questions/11500492/what-are-the-best-practices-to-follow-when-declaring-an-array-in-javascript – Olga Dec 26 '15 at 13:01