user3737812 user3737812 - 3 months ago 11
Javascript Question

My if statement returns unexpected results, making random Sudoku with Javascript

I've been trying to make a program that creates Sudoku's randomly using Javascript. I've included both the code and pictures of that code in Atom to make it somewhat more readable.

Basically from line 16-20 I add 9 numbers to row, then shuffle them and store the result in newRow.

From line 25 onwards I start a loop that goes through all the past rows, which are stored in the array called 'actualRow'. So row gets shuffled into newRow, newRow is stored in actualRow. From the second newRow onwards I want to check whether there are any duplicate values. This is why I start loop1 and loop2. Loop1 to loop through all previous rows, and loop2 within that to loop through all the values.

The if statement is intended to catch duplicates, but doesn't ever evaluate to true, which it obviously should because there are always many duplicates.If it would be true, mistake = true, and thus I would not add that particular newRow to actualRow, but start the loop over until it does not encounter duplicates.

So really the problem lies in the if-statement in line 32. What am I missing here?



<script>
var row = [];
var newRow = [];
var actualRow = [];
var mistake;

function makeSudoku() {
for (var j = 0; j < 9; j++) {
row = [1,2,3,4,5,6,7,8,9];
newRow = [];
mistake = false;

for (var i = 1; i < 10; i++) {
newRow.push( row.splice( Math.floor( Math.random() * row.length) , 1) );
}

if ( j !== 0) { // no need to check for duplicates in first row

loop1:
for (var k = j-1; k > -1 ; k--) { // for every row that came before..
loop2:
for (var l = 0; l < 9; l++) { // for every value in that row..
if ( actualRow[j-1][l] == newRow[l] ) { // issue here!!!
mistake = true;
console.log("duplicate row value");
} else {
console.log("Why does this if statement always evaluate to else?");
}
}
}
}

if ( mistake == false) {
actualRow.push(newRow);
} else if ( mistake == true) {
j -= 1;
} else {
}
}

console.log(actualRow);
}

makeSudoku();




enter image description here

enter image description here

Answer

The answer posted by tagelicht is the first thing I thought of, too. But the actual problem is something simpler. When you compare the two values, they don't seem to have the same type (I'm not entirely sure just yet why this is the case). You can simply parse the integer of the objects using parseInt() (find the documentation here).This code works for me (only edited the code from line 22 onward):

for (var l = 0; l < 9; l++) {
  console.log('actualRow: ' + actualRow[j-1][l]);
  console.log('newRow: ' + newRow[l]);
  console.log(parseInt(actualRow[j-1][l]) == parseInt(newRow[l]));

  if ( parseInt(actualRow[j-1][l]) == parseInt(newRow[l]) ) {
    mistake = true;
    console.log("duplicate row value");
  } else {
    console.log("Why does this if statement always evaluate to else?");
}

Hope this helps.

EDIT: Also already pointed out by trincot the problem is in line 23, with the splice() method. Since this method returns an array (see here fore more information), the comparison to an integer always fails. A better approach then my original solution above is to just push the actual value into the newRow array in line 14 by adding a [0] after the splice() call:

newRow.push( row.splice( Math.floor( Math.random() * row.length) , 1)[0] );