Search code examples
javascriptarraysrandomshuffle2d-games

Set a custom % of 1's into a 2D blank array, where the 1's are randomly shuffled?


I've been a long time lurker on Stack Overflow but I couldn't seem to find a suitable existing solution...

I'm learning JS and HTML, and I've been playing around with 2D arrays to make game board. So far I made a custom # of rows/columns for a game board with all white tiles (represented as 0 for now).

My goal is to use an input field for a % of black tiles (represented as 1) to fill up the board (2D Array), but the black tiles have to be randomly distributed/shuffled among it.

Here's what I've got so far..

https://jsfiddle.net/5pvm4mmy/6/

function generateArray() {

var myNode = document.getElementById("table");
while (myNode.firstChild) {
    myNode.removeChild(myNode.firstChild);
}

rows = $("#rows-field").val();
cols = $("#cols-field").val();

concentration = $("#concentration-field").val()
source = $("#source-field").val();
target = $("#target-field").val();



var table = document.getElementById("table");
for (var i = 0; i < rows; i++) {
    var tr = document.createElement('tr');
    for (var j = 0; j < cols; j++) {
        var td = document.createElement('td');
        if (i%2 == j%2) {
            td.className = "white";
        } else {
            td.className = "black";
        }
        tr.appendChild(td);
    }
    table.appendChild(tr);
}
document.body.appendChild(table);


}

Thanks in advance for any help or advice.


Solution

  • If you need a random selection of a predefined set of values, you can use a stack. Think of it as a deck of cards and you pick a random card each time from the number of card left in the deck. In this case you have only 2 values but you may want to set the number of black and white. For this you can use a pseudo stack.

    var black = 29;  // 29 blacks the rest white
    var white = (rows * cols) - black;
    
    function getRandSquare(){
        var select = Math.floor(Math.random() * (black + white));
        if(select > black){
            white -= 1;
            return "white";
        }
        black -= 1;
        return "black";
    }
    

    If you have many options like a deck of cards you use an array.

    Example of a random stack.

    // create a deck
    var cards = [];
    for(var c = 0; c < 52; c++){
        cards[c] = c;
    }
    function shuffle(cards){
        var shuf = []; // to hold the shuffled deck
        while(cards.length > 0){ // pick a random item, take it from the stack and
                                 // put on the new stack until there are no items
                                 // left
            shuf.push(cards.splice(Math.floor(Math.random() * cards.length),1));
        }
        return shuf;  // return shuffled deck
    }
    
    cards = shuffle(cards); // get shuffled deck.
    

    Which will work for anything where you need to pick randomly from a predefined set. It only takes one pass and the set is as random as the random number generator

    To show psuedo stack working ... Always has 60 black

    var cont;
    function draw(){
        var rows = 15;
        var cols = 15;
        var black = 60;  // 29 blacks the rest white
        var white = (rows * cols) - black;
        
        function getRandSquare(){
            var select = Math.floor(Math.random() * (black + white));
            if(select > black-1){
                white -= 1;
                return "white";
            }
            black -= 1;
            return "black";
        }
     
        var bCount = 0;
        cont = document.createElement("div");
        for(var y = 0; y < rows; y++){
            for(var x = 0; x < cols; x++){
                var s = document.createElement("span");
                s.className = getRandSquare();
                if(s.className === "black"){
                   s.textContent = bCount;
                   bCount += 1;
                }
                s.style.top = ((y+2) * 20) + "px";
                s.style.left = (x * 20) + "px";
                s.style.width = "20px";
                s.style.height = "20px";
                cont.appendChild(s);                                         
            }
          
        }
        document.body.appendChild(cont);
    }
    document.body.onclick = function(){
      document.body.removeChild(cont);
      cont = null;
      draw();
    }
    draw();
        
    span {
      position:absolute;
      border : 1px solid;
      font-size : small;
      text-align : center;
    }
    .black {
      background : black;
      border-color :white;
      color : white;
    }
    .white {
      background : white;
      border-color :black;
    }
    <h3>Click to randomise</h3>