-1

I just started to learn how to code so please go easy on me :).

I got a project due in which I need to create sudoku with JS, I tried to do the entire thing but I had a hard time, don't know how to randomize the filled area.

I have a var, which has an array of numbers. The user has 3 difficulties to choose from Easy Medium Hard. Easy will show 75 percent of the array in a random location, medium 50 percent, and hard will only show 25 percent

"board" is how I want the array to be after randomizing, solution is the correct solution for the sudoku, it's comparing the board.

How do I do that?
Here is my Code:

let numSelected = null;
let tileSelected = null;
let errors = 0;
let board = [
  "--74916-5",
  "2---6-3-9",
  "-----7-1-",
  "-586----4",
  "--3----9-",
  "--62--187",
  "9-4-7---2",
  "67-83----",
  "81--45---"
]
let solution = [
  "387491625",
  "241568379",
  "569327418",
  "758619234",
  "123784596",
  "496253187",
  "934176852",
  "675832941",
  "812945763"
]

window.onload = function() {
  setGame()
}

function setGame(){
  // 1 - 9 Numbers
  for ( let i = 0 ; i<= 9 ; i++){
    // loop to create div, adding div ="1" + adding Class="number"
    let number = document.createElement("div"); // Creating Div for each number var
    number.id = i;  // Div id = i
    number.innerHTML = i; // inner html = i
    number.addEventListener("click", selectNumber); // on click execute selectNumber() function
    number.classList.add("number"); // add class "number" to each div
    document.getElementById("digits").appendChild(number); // add to div digits the div created "number"
  }
  
  // Board 9x9
  for ( let r = 0 ; r < 9 ; r++){     /// r = Row
    for ( let c = 0 ;c < 9 ; c++){  /// c = Column
      let tile = document.createElement("div");
      tile.id = r.toString() + "-" + c.toString();  // each tile has an id of his location , id = r(0) - c(0)
      if(board[r][c] != "-"){ // if location does not have "-" , add tile.innertext in board at location [r][c]
        tile.innerText = board[r][c]; // add innerText of what is in board[r][c]
        tile.classList.add("tile-start"); // add class tile start for CSS
      }
      if(r == 2 || r == 5){
        tile.classList.add("horizontal-line") // Adding CSS grids for sudoku
      }
      if( c == 2 || c == 5){
        tile.classList.add("vertical-line")  // Adding CSS grids for sudoku
      }
      tile.addEventListener("click" , selectTile) // on click execute selectTile() function
      tile.classList.add("tile");  // add class of tile to all
      document.getElementById("board").append(tile)
    }
  }
}

function selectNumber(){
  if (numSelected != null){ // If numSeleceted is not equal to null , it means a number was already selected and it will remove the class styling
    numSelected.classList.remove("number-selected")
  }
  numSelected = this; // This refers to the Div itself
  numSelected.classList.add("number-selected"); // add background to new number
}

function selectTile(){
  if( numSelected){
    if (this.innerText != ""){
      return;
    }
    
    // ID's look like this - "0-0" , "0-1" .. "3-1"
    let coords = this.id.split("-"); // Creates an array of 2 different strings ["1","1"] for example
    let r = parseInt(coords[0]); // parseInt transforms the array of strings to integar
    let c = parseInt(coords[1]);
    
    if (solution[r][c] == numSelected.id){
      this.innerText = numSelected.id; // "this" is referring to the tile itself
    }
    else{
      errors += 1;
      document.getElementById("errors").innerText = errors; // how many errors were done
    }
  }
} 
   body {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    text-align: center;
  }

  hr{
    width: 500px;
    border-style: dotted;
    border-top: 0;
    border-width: 5px;
    border-color: lightgray;
  }

  h1{
    letter-spacing: 20px;
    
  }

  #errors{
    color: rgb(170, 235, 228);
  }

  #board{
    width: 450px;
    height: 450px;
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
  }

  .tile{
    width: 48px;
    height: 48px;
    border: 1px solid lightgray;

    /* Text */
    font-size:  20px;
    font-weight: bold;
    display: flex;
    justify-content: center;
    align-items: center;
  }

#digits{
    width: 450px;
    height: 50px;
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
}

.number{
    width: 39px;
    height: 39px;
    border: 1px solid black;
    margin: 2px;

    /* Text */
    font-size:  20px;
    font-weight: bold;
    display: flex;
    justify-content: center;
    align-items: center;
}

.number-selected {
    background-color: rgb(170, 235, 228);
}

.tile-start {
    background-color: whitesmoke;
}

.horizontal-line {
    border-bottom: 1px solid black;
}

.vertical-line{
    border-right: 1px solid black;
}
 <h1>Good Luck</h1>
<hr>
<h2 id="errors">0</h2>
<!-- board 9x9 -->
<div id="board"></div>
<br>
<div id="digits"></div>

1 Answers1

1

This code demonstrates the algorithm to randomly select k items from n total items without replacement.

If k items are to be selected, then the probability that the first one is selected is k/n. So perform a random check to see if that item is selected. Then you consider the next item. Depending on whether you selected the first item, you either select k-1 items from the remaining n-1 items, or select k items from the remaining n-1 items. Keep decrementing k when you select an item and decrementing n each time through the loop.

In the example below, k is called toBePlaced and n is called possibilities, for readability.

const N = 9 * 9;
const board = Array(N).fill('0');

const randomly = p => Math.random() < p;

let toBePlaced = 40; // How many you want to modify
let possibilities = N; // How many there are in total.
for (let i = 0; i < N; ++i) {
  if (randomly(toBePlaced / possibilities)) {
    board[i] = '-';
    toBePlaced--;
  }
  possibilities--;
}

const format = board => [...Array(9)].map((_, i) => 
    board.slice(9 * i, 9 * i + 9).join('')).join('\n');
console.log(format(board));
Wyck
  • 10,311
  • 6
  • 39
  • 60
  • The comments section explains to us that the OP - "I still can't randomize the locations of the "-". So, OP wants to randomize the locations of the "-" symbols. Your answer is not related to that. I downvoted. – user14063792468 Jun 21 '22 at 22:27
  • @user14063792468, I respect your downvote. But I'm curious. You think my code does not randomize the locations of the `-` symbols? That's odd. Did you click the _Run code snippet_ button? How do you think a fixed number of `-`'s wind up in random positions if not by randomizing their locations? – Wyck Jun 22 '22 at 01:57
  • Well, now I see that I made a mistake. Your code actually randomizes the locations of '-' characters. Still, I can not remove my downvote. Unless the answer is edited. – user14063792468 Jun 22 '22 at 12:52
  • @user14063792468 it has been edited :) – Wyck Jun 22 '22 at 13:20