0

I thought that this onClick event in a For loop would help me but when I tried it, it still didn't work.

I am making a simple Battleship game, and while I'm trying to have the user click on only 4 squares to place on ship, the loop keeps going and doesn't stop after 4 tries. I have my onclick even handler in a for loop, but after 4 tries it doesn't stop. I've tried adding a count variable after the end, and even tried adding a break statement but can't get it to work.

Here's my code:

    function placeShips() {
        var playerTable = document.getElementById("mainPlayer");
        var playerCells = playerTable.getElementsByTagName("td");
        var count = 1;

        alert("Please place the first ship. Click on 4 squares.");
        while (count <= 4) {
            for (i = 0; i < playerCells.length; i++) {
                playerCells[i].onclick = placeBattleship;
            }
            count++;
        }
    }

The placeBattleship function contains the code to change the grid square to a background color of red to mark it. My problem is that once the user clicks 4 squares, you can keep going and click on more and more. I can't get the above for loop that calls the placeBattleship function to stop after the user clicks on 4 squares. I've tried putting it in a while loop, and even the solution in the above link, as well as moving the assignment of count, but can't get it to stop after x amount of times (in this case, 4).

Any ideas on what I'm doing wrong, or a better way to do it?

Community
  • 1
  • 1
WitchKing17
  • 185
  • 3
  • 21
  • 1
    Every time you run the loop you are resetting count to 1 – pathfinder Apr 11 '16 at 02:34
  • OP. Aren't you just attaching placeBattleShip function to onclick of every single cell? Don't you instead want to "unattach" the handler after player has clicked on 4 cells? – stripathi Apr 11 '16 at 02:38
  • @pathfinder Do I declare count inside the while loop? I've tried moving the count++ inside the for loop, but that didn't seem to work either. – WitchKing17 Apr 11 '16 at 02:39
  • @stripathi I guess I don't know how to do that. Is there a way to do that? – WitchKing17 Apr 11 '16 at 02:39
  • try assigning onclick = null after you count the number of cells already clicked to be 4. Your count has to be a variable on a higher lifetime scope than the function that subscribes/unsubscribes event. I'd pull up an example but I'm too tired for it right now. Will post an answer tomorrow if no one else does. – stripathi Apr 11 '16 at 02:43
  • @stripathi I tried to add the onclick = null, but then that doesn't let me click anything at all. I'll wait for you answer, and keep trying in the mean time. – WitchKing17 Apr 11 '16 at 02:47
  • OP You want to allow user to click only 4 times, after 4 clicks user is not allowed to click anymore right? – itzmukeshy7 Apr 11 '16 at 04:37

4 Answers4

1

Wouldn't you consider to use jQuery?

Look your function much shorter:

function placeShips() {
    $("td:lt(4)").click(placeBattleship);
}

You can testify on the code below:

  <table>
    <tr>
      <td>1.1</td><td>2.1</td>
    </tr>
    <tr>
      <td>1.2</td><td>2.2</td>
    </tr>
    <tr>
      <td>1.3</td><td>2.3</td>
    </tr>
  </table>
  <div id="console"></div>
  <script>
  $("td:lt(4)").each(function(){
    $("#console").append("Content of "+ $(this).html() + "<br/>");
  });

  $("td:lt(4)").click(function(){
    $("#console").append("Clicking "+ $(this).html() + "<br/>");
  });
  </script>

...or on my Plunker: https://plnkr.co/edit/yNZw6ZhkNfA9E0NdQg7V

Diego Polido Santana
  • 1,425
  • 11
  • 19
0

You should separate priorities in your logic and removeEventListener when counter hits 4 , hopefully this helps you :

//defined outside the function
var counter = 0;
playerCells.addEventListener("click" , placeShips );

Then

 function placeShips() {
    if(counter <= 4){
      //Move ship
      placeBattleship();

//add to counter

       counter++

}else{

//Remove click event if counter reaches 4 .

playerCells.removeEventListener("click" , doSomethingElse)

}

}
KpTheConstructor
  • 3,153
  • 1
  • 14
  • 22
0

You question needs a bit clarification. To my current understanding, you need to move the checking of count to placeBattleship.

What you are doing is binding click to same tds 4 times, not limiting the number of event triggering to 4 times.

// pseudo code
var count = 4; // this is global
var currentCount = 0;

initFunc() {
  // bind click events ONCE
}

startPlacing() {
  // accept user click and place ship
  // set currentCount to zero
}

placeShip() {
  // the callback of user `click`
  // check for currentCount == count then move on (no more placement)
  // increase currentCount by 1
  // place ship
}

Note that after an event is triggered, the listener will not be removed. Until you removeEventListener() from it, it will always be listening.

dz902
  • 4,782
  • 38
  • 41
0

So, now we have a solution that stop for 4th click on the squares:

function placeBattleship() {
  var $shipDisplay = $("#shipDisplay");
  var counter = $shipDisplay.data("counter");
  if(counter++ < 4) {
    $(this).css("background-color", "red");  
    $shipDisplay.data("counter", counter);
  }

}
function placeShips() {
    $("td").click(placeBattleship);
}
$(document).ready(function(){
  placeShips();
});

I use a div with id shipDisplay to store a data-attribute for count the clicks.

Look at the plunker: http://plnkr.co/edit/PEba15PSLv2LK6qjY7AD?p=preview

Diego Polido Santana
  • 1,425
  • 11
  • 19