0

I'm trying to create a program in processingjs that allows the user to create a square grid of whatever size they want, and whenever you click on a square it turns another color. So far I've done it flawlessly. You can check it out at: https://www.khanacademy.org/computer-programming/tile-creator/5356772601151488

The entire code is:

var fraction = width/gridSize; //divides the width of the canvas by the grid size. this allows us to put squares in each fraction (ej. if the gridsize is 5, then the fraction will divide the width of the canvas by 5, then with this we can draw a square in the first fifth of the canvas, second fifth of the canvas, etc. by multiplying the fraction by 1, 2, 3, 4, etc.)

for (var e = 0; e < gridSize; e++){ //i cant believe this works
    for (var i = 0; i < gridSize; i++){ //first it draws the squares by columns
        rect(i * fraction, fraction*e, fraction, fraction); //however it only draws them column by column, to make it go through all the rows i put it in yet another for loop that increments its variable e by 1, and draw each individual row with that
}}

var squareOnTopOfMouseX = 69;
var squareOnTopOfMouseY = 69;
var foundLocation = 0;

mouseClicked = function() {
    fill(255, 0, 0); //makes the color of the squares red
    
    if(mouseX < 1 * fraction){ //if the mouse X coord is within the FIRST fifth of the fraction
        squareOnTopOfMouseX = 0 * fraction; //sets the coord for the square to be on the 0th tile place. and so on for the rest
        
        } else if(mouseX < 2 * fraction){
        squareOnTopOfMouseX = 1 * fraction;
        
        } else if(mouseX < 3 * fraction){
        squareOnTopOfMouseX = 2 * fraction;
        
        } else if(mouseX < 4 * fraction){
        squareOnTopOfMouseX = 3 * fraction;
        
        } else if(mouseX < 5 * fraction){
        squareOnTopOfMouseX = 4 * fraction;
        }
        
    if(mouseY < 1 * fraction){ //if the mouse Y coord is within the FIRST fifth of the fraction
        squareOnTopOfMouseY = 0 * fraction; //sets the coord for the square to be on the 0th tile place. and so on for the rest
        
        } else if(mouseY < 2 * fraction){
        squareOnTopOfMouseY = 1 * fraction;
        
        } else if(mouseY < 3 * fraction){
        squareOnTopOfMouseY = 2 * fraction;
        
        } else if(mouseY < 4 * fraction){
        squareOnTopOfMouseY = 3 * fraction;
        
        } else if(mouseY < 5 * fraction){
        squareOnTopOfMouseY = 4 * fraction;
        }
        
    rect(squareOnTopOfMouseX, squareOnTopOfMouseY, fraction, fraction);
};

Now, I don't think you need to understand my code to answer my question. If you look at the very end of the code, I have a sequence of if statements that essentially is checking for: if the user clicked on the first division of the canvas (ej. if the grid is 5x5, then its looking for if you clicked in the first fifth of the canvas), then put the X coordinate of the red square on the first fifth of the canvas. If the user clicked on the second fifth, then put the X coordinate on the second fifth of the canvas, etc. It also does the exact same thing but for the Y coordinates.

Once again, I think its ok if you dont understand that. But not only is my code at the end inefficient, it breaks if you set the grid size any higher than 5 (because I manually need to add more statements to it)

I've tried to create things like

for (var i = 0; i < gridSize; i++){
        if(mouseX < 1 * fraction){
            squareOnTopOfMouseX = i * fraction;
        }
    }

(for simplicity lets ignore the Y coordinates right now because it should be the exact same code once fixed anyways)

But this code above just doesn't work. No matter what I do I just can't get the same code I pasted in the beginning to work properly once written as a for or while loop. Can anyone help point me towards the right direction? I think that for loops are what I should be using, because all of the code after the initial if statement is the same:

else if(mouseX < (SomeGivenNumber) * fraction){
        squareOnTopOfMouseX = (SomeGivenNumber-1) * fraction;

(SomeGivenNumber should go all the way up to whatever the gridSize is set to)

And as the title of my question says, something I think would work is for me to keep adding else if statements as many as are needed. Something like, if the grid is set to something like 90x90, then the 'else if' statements will go all the way up to 90. But I don't know how to do this.

pepesito1
  • 15
  • 4
  • is this a code review or is there an actual issue with the code? – Bravo May 12 '22 at 04:39
  • well, the code works fine, theres no issues with it, i just want to change the "else if" loops at the end to automatically go as high as needed (as high as whatever the gridSize is set to), and I don't know how to do that. like, if I set the gridSize to 99 then i would have to write 99 else if statements checking for where the user clicked. that's not efficient. – pepesito1 May 12 '22 at 04:42
  • oh, but `else if` are not loops – Bravo May 12 '22 at 04:43
  • 1
    seems like `if (mouseX < n * fraction) squareOnTopOfMouseX = (n-1) * fraction;` could be written something like like `squareOnTopOfMouseX = (Math.floor(mouseX/5) - 1) * fraction` - my maths may be a little wrong, but a little tweak here and there and you can do it in one line each for X and Y – Bravo May 12 '22 at 04:46
  • It seems to me that it can be just `squareOnTopOfMouseX = (~~(MouseX / fraction) - 1) * fraction`, no need for any `if`. – Gerardo Furtado May 12 '22 at 04:46
  • 1
    oooh @GerardoFurtado ... double tilde for the win!! of course, you could do better ... `~-(MouseX/fraction)` since that'll do the -1 for you :p (I think!!) – Bravo May 12 '22 at 04:47
  • @Bravo that's because I'm used to write double tildes, but `Math.floor` not only makes the intent clear but also works with big numbers (double tilde doesn't). – Gerardo Furtado May 12 '22 at 04:52
  • thanks to all of you guys. i find it extremely funny how you all understand my code better after looking at it for 1 minute than i do after writing it for 2 hours. i have one final question though: in the `squareOnTopOfMouseX = (~~(MouseX / fraction)) * fraction` statement, if you remove the math.floor operator or the 2 wavy lines, algebraically thats just (mouseX/fraction)*fraction) which is just mouseX. how does it then round the squareOnTopOfMouseX coords to be set exactly to what the proper grid coordinates are? – pepesito1 May 12 '22 at 05:06

1 Answers1

1

an user named Gerardo Furtado replied in the comments with a flawless line of code which was just what i wanted. i replaced all of the messy if and else if statements for

squareOnTopOfMouseX = (~~(mouseX / fraction)) * fraction

and it works like a charm. the other users answers also kinda worked but gerardo was the simplest one. ngl idk what that statement is doing at all but it works!

edit: i also cant mark my own answer as an answer for the question (with the green checkmark thing) for some reason so unless another user wants to reply with what i just wrote above, i could mark that as answered and that way stackoverflow is kept cleaner. thanks to all who helped

pepesito1
  • 15
  • 4
  • [~~](https://stackoverflow.com/questions/5971645/what-is-the-double-tilde-operator-in-javascript) – Lain May 12 '22 at 05:14