1

I am building a simple minesweeper game for the first JavaScript project. What I need to do in the game is that it randomly creates a map,that is randomly assigning a name (1,2,4 if it's terrain and x if it's a bomb) to an html element via a JavaScript function.

I have searched a lot and found out how to actually set the name attribute and further print it out using appendText to the <td> of the table (I think innerHTML would also work fine).

My problem is that the array is actually being randomly sorted out but when I go through that array (after sorting it) in order to set the name for the hmlt element by ID like this document.getElementById(id).setAttribute("name","something") it doesn't work. But as far as I can see, since I can't debug, the array is being sorted out correctly. (Im developing with atom) I really don't understand why the code isn't working as it should be.

I have created a button that calls a function to create that random map like this:

<button type="button" onclick="shuffle();">Start The game!</button>

 <script type="text/javascript">
  //Randomly sorts the array called numbers
    function shuffle()
     {
    var numbers = [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,'x','x','x','x',2,2,2,2,2,1,1,2,2];
    for (var i = numbers.length - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var temp = numbers[i];
            numbers[i] = numbers[j];
            numbers[j] = temp;
        }

//The code below doesn't actually change the name of the element as far as I'm aware, but I can't understand why.
//It should be working and I can't figure out why.
for(var idx = 1; idx <= numbers.length + 1; idx ++)
document.getElementById(idx).setAttribute("name",numbers[idx - 1]);
    }
}
</script>

After the map is created, when a user clicks on a table cell it should do this:

<TABLE>
                <TR>
                    <TD class='terrain' id='1' name="" onclick="scriptPisadela('1');"></TD>
                    <TD class='terrain' id='2' name="" onclick="scriptPisadela('2');"></TD>
                    <TD class='terrain' id='3' name="" onclick="scriptPisadela('3');"></TD>
                    <TD class='terrain' id='4' name="" onclick="scriptPisadela('4');"></TD>
                    <TD class='terrain' id='5' name="" onclick="scriptPisadela('5');"></TD>
                    <TD class='terrain' id='6' name="" onclick="scriptPisadela('6');"></TD>
                    <TD class='terrain' id='7' name="" onclick="scriptPisadela('7');"></TD>
                </TR>

<script type="text/javascript">
        function scriptPisadela(myid){
          var Name = document.getElementById(myid).attributes["name"].value;
            if(Name == 'x') document.getElementById(myid).className = 'bomb';
            else document.getElementById(myid).className = 'livre';
            var td = document.getElementById(myid);
            var text = document.createTextNode(Name);
            td.appendChild(text);
        }
    </script>

//This is supposed to be testing out if the name of the element is a bomb or not and it should print out the name. I did this because if I just did something like TD class='terrain' id='1' onclick="scriptPisadela('1');">TEXT HERE</TD> the user could just ctrl + a and it would be able to see all the elements and win the game.

Here is a link to FiddleJs if it's a little hard to see here, I will be commenting out the code on fiddle as well https://jsfiddle.net/nzgmdf7p/2/

And here is the link for the actual html document https://drive.google.com/file/d/0B1xc1ft-s78NVm5FN0lvckhsVVk/view?usp=sharing

Any help is highly appreciated.

Mr.Toxy
  • 357
  • 4
  • 19

2 Answers2

1

Based on the fiddle provided by you(after correcting the syntax error) only issue i can see is the below line

for(var idx = 1; idx <= numbers.length + 1; idx ++)
      document.getElementById(idx).setAttribute("name",numbers[idx - 1]);
 }

your are looping array till numbers.length + 1 while number have a length of 28. Once the loop goes above 27, you will encounter an error since no such element is present in the html.

you need to change

for(var idx = 1; idx < numbers.length; idx ++)
    document.getElementById(idx).setAttribute("name",numbers[idx - 1]);
    }

Working example : https://plnkr.co/edit/hkdiX1U6G6CWOtE5qdbr?p=preview

Deep
  • 9,594
  • 2
  • 21
  • 33
-1

First of all, since you are new into javascript, it will be much easier to learn how to use jQuery to make things more easy for you and more compatible with older browsers.

Secondly, I see you use the name attribute, which is something you should avoid. name attribute is mostly for form fields get/post data. You should use the data attribute and then get/set these data by using jQuery data function. I have wrote something based on your code.

jQuery(function($) {

    function scriptPisadela(myid) {
        //var Name = document.getElementById(myid).getAttribute("name");
        var Name = $('#' + myid).data("name");
        if (Name == "x") {
            document.getElementById(myid).className = "bomb";
        } else {
            document.getElementById(myid).className = "livre";
        }
        var td = document.getElementById(myid);
        var text = document.createTextNode(Name);
        td.appendChild(text);
    }

    //Randomly sorts the array called numbers
    function shuffle() {
        var numbers = [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "x", "x", "x", "x", 2, 2, 2, 2, 2, 1, 1, 2, 2, 2];
        for (var i = numbers.length - 1; i > 0; i--) {
            var j = Math.floor(Math.random() * (i + 1));
            var temp = numbers[i];
            numbers[i] = numbers[j];
            numbers[j] = temp;
        }

        //The code below doesn"t actually change the name of the element as far as I"m aware, but I can"t understand why.
        //It should be working and I can"t figure out why.
        for (var idx = 1; idx <= numbers.length + 1; idx++) {
            //document.getElementById(idx).setAttribute("name", numbers[idx - 1]);
            $('#' + idx).data("name", numbers[idx - 1]);
        }
    }

    for (var i = 1; i <= 30; i++) {
        $('#mines tr').append(
            $('<td class="terrain" id="' + i + '" data-name=""></td>')
            .on('click', function() {
                scriptPisadela($(this).attr('id'));
            })
        );
    }

    shuffle();
});
table td {
    width:20px;
    height:20px;
    margin: 2px;
    background-color: blue;
    color:#fff;
    text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="mines">
 <tr>
 </tr>
</table>
<button type="button" onclick="shuffle();">Start The game!</button>

Just run the snippet and click on the blue table cells.

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • that looks really neat. Jquery can I used straight up or do I need to get from NuGet or something like that? I really like your point, it does seem to be a lot simpler. the thing is that sine I'm new I would feel a lot conofortable to first understand all js aspects so then I could use nodeJS and angular and so on. Is this a wrong perception? – Mr.Toxy Nov 19 '16 at 16:57
  • *Node.js* and *angular* have nothing to do with *jQuery*. *jQuery* is a framework to make things easier and most importantly compatible with most of the browsers. If you use plain javascript, soon you will face browser compatibility issues mostly on older browsers. – Christos Lytras Nov 19 '16 at 17:00
  • oh I understand :) thx a lot for the adice. I wish I could select two answers :\ I will defenitly vote yours up. thx – Mr.Toxy Nov 19 '16 at 17:03
  • Please don't suggest jQuery solutions unless the OP has tagged the question jQuery, or you have confirmed with him that he is OK with a jQuery solution. What older browsers are you worried about compatibility with? –  Nov 19 '16 at 17:09
  • If Node.js or Angular are your goals, you may not want to use jQuery too much. Many beginners who learn jQuery don't take the time to learn how to do things without it, and it becomes a crutch. Plain JavaScript will better prepare you for Node.js and Angular, which often times don't have access to jQuery. – 4castle Nov 19 '16 at 17:16
  • @torazaburo I got a downvote for an answer that I spent at least 10 minutes to debug and write a proper working example just to help new person that needs help, just because I proposed them to use the most widely used javascript framework *jQuery*. Well, as I already state to my comments, plain javascript has incompatibilities with **older** browsers that you should already know. You think every device on this planet has the latest versions of Chrome, Safari and Mozilla? Well, that is not happening and there are still many oldies out there that need to be updated. – Christos Lytras Nov 19 '16 at 17:19
  • @torazaburo also read these articles that debate on jQuery usage: [Why jQuery?](http://mmikowski.github.io/why-jquery/), [Why would I want to use jQuery?](http://stackoverflow.com/questions/708040/why-would-i-want-to-use-jquery). And you can find many more on this subject for yourself. – Christos Lytras Nov 19 '16 at 17:22
  • Sorry, the rule about not providing jQuery solutions if not asked for is quite clear. When you say "widely used", you need to distinguish between widely used in existing code--which is the case, since it was so widely adopted starting a decade ago--and widely used in modern web development or new applications, which is decidedly not the case--the adoption rate is zero. The point of jQuery was never to smooth over differences between versions of Chrome or Mozilla. Those browsers are assumed, by all major application developers, to be kept up to date (they are updated automatically) to within –  Nov 19 '16 at 17:27
  • (cont'd) three or four versions. The point was primarily to deal with versions of IE which are now obsolete and not supported by new apps (and not even supported by the manufacturer). –  Nov 19 '16 at 17:29
  • The second reference you give was written seven years ago. –  Nov 19 '16 at 17:32
  • What about the first one? You can search for yourself. See some usage statistics: [Drupal Usage statistics for jQuery Update](https://www.drupal.org/project/usage/jquery_update), [jQuery Usage Statistics](https://trends.builtwith.com/javascript/jQuery). It still looks like quite popular to me. jQuery is still massively used by developers and it will continue to be used by new developers. Many people also consider it is easier than plain javascript, which means less time to make things working. Also there is a huge amount of jQuery plugins ready to be used. – Christos Lytras Nov 19 '16 at 17:47
  • @torazaburo also, can you provide the link with all these rules, so to read and know what I should avoid please? – Christos Lytras Nov 19 '16 at 17:48