// sudoku engine v2.3
// updated February 1, 2007
// copyright Patrick Lewis (patricklewis.net)

function GenSud () {
trials = 50;
GrAtt = 1;
for (Block=1;Block<11;Block++) {

/////////////////////////////////

	if (Block == 1){
	grid = new Array(9);
	BlAttempts = new Array(0,0,0,0,0,0,0,0,0,0,0);
	for (r=0;r<9;r++) {
		grid[r] = new Array(9);
		}
	Error = "";

	//block 1
	Error += "<br>Block 1 start<br>";
	temp = new Array(1,2,3,4,5,6,7,8,9);
	for (r=0;r<3;r++) {
		for (c=0;c<3;c++) {
			num = Math.floor(Math.random() * 9);
			if (!temp[num]){c--;}
			else {
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		}
	Error += "Block 1 done<br>";
	//alert("1 done");
	BlAttempts[1]++;
	if (BlAttempts[1] > trials) {Error += "Block 1 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 2){
	// block 2
	Error += "<br>Block 2 start<br>";
	for (r=0;r<3;r++) {
		for (c=3;c<6;c++) {
			temp = new Array(1,2,3,4,5,6,7,8,9);
			// remove numbers in block to the left same row
			temp[grid[r][0]-1] = "";
			temp[grid[r][1]-1] = "";
			temp[grid[r][2]-1] = "";
			if (c>3) {
				temp[grid[r][3]-1] = "";
				}
			if (c==5) {
				temp[grid[r][4]-1] = "";
				}
			if (r==1) {
				temp[grid[r-1][3]-1] = "";
				temp[grid[r-1][4]-1] = "";
				temp[grid[r-1][5]-1] = "";
				force = new Array(9);
				// force to take what is left in bottom row block to left
				for (b=0;b<3;b++) {
					bl = grid[r+1][b];
					if (temp.toString().indexOf(bl) > -1) {
						force[bl-1] = bl;
						temp[bl-1] = "";
						}
					}
				//Error +="forced "+ force +" : ";
				if (force.toString().match(/\d/g)) {
					temp = force;
					}
				//Error += "temp : "+temp +"<br>";
				}
			if (r==2) {
				temp[grid[r-1][3]-1] = "";
				temp[grid[r-1][4]-1] = "";
				temp[grid[r-1][5]-1] = "";
				temp[grid[r-2][3]-1] = "";
				temp[grid[r-2][4]-1] = "";
				temp[grid[r-2][5]-1] = "";
				}
			if (temp.toString() == ",,,,,,,,") {Error += "2 breaking (commas)<br>"; Block =1; break;}
			if (!temp.toString().match(/\d/)) {Error += "2 breaking (no # match)<br>"; break;}
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){c--;}
			else {
				//Error += r +","+c+") "+temp +" ["+ num +" - "+ temp[num] +"]<br>";
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		}
	Error += "Block 2 done<br>";
	//alert("2 done");
	BlAttempts[2]++;
	if (BlAttempts[2] > trials) {Error += "Block 2 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 3){
	//block 3
	Error += "<br>Block 3 start<br>";
	for (r=0;r<3;r++) {
	temp = new Array(1,2,3,4,5,6,7,8,9);
		temp[grid[r][0]-1] = "";
		temp[grid[r][1]-1] = "";
		temp[grid[r][2]-1] = "";
		temp[grid[r][3]-1] = "";
		temp[grid[r][4]-1] = "";
		temp[grid[r][5]-1] = "";
		for (c=6;c<9;c++) {
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){c--;}
			else {
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		}
	Error += "Block 3 done<br>";
	//alert("3 done");
	BlAttempts[3]++;
	if (BlAttempts[3] > trials) {Error += "Block 3 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 4){
	// block 4
	Error += "<br>Block 4 start<br>";
	for (c=0;c<3;c++) {
		for (r=3;r<6;r++) {
			temp = new Array(1,2,3,4,5,6,7,8,9);
			// remove numbers in above block, same column
			temp[grid[0][c]-1] = "";
			temp[grid[1][c]-1] = "";
			temp[grid[2][c]-1] = "";
			if (c==1) {
				//remove numbers in same block, previous column
				temp[grid[3][c-1]-1] = "";
				temp[grid[4][c-1]-1] = "";
				temp[grid[5][c-1]-1] = "";
				}
			if (c==2) {
				//remove numbers in same block, previous 2 columns
				temp[grid[3][c-1]-1] = "";
				temp[grid[4][c-1]-1] = "";
				temp[grid[5][c-1]-1] = "";
				temp[grid[3][c-2]-1] = "";
				temp[grid[4][c-2]-1] = "";
				temp[grid[5][c-2]-1] = "";
				}
			// remove numbers in same block/column above current row
			if (r>3) {
				temp[grid[r-1][c]-1] = "";
				}
			if (r==5) {
				temp[grid[r-2][c]-1] = "";
				}
			if (temp.toString() == ",,,,,,,,") {Error += "4 breaking (commas)<br>"; Block=3; break;}
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){r--;}
			else {
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		}
	Error += "Block 4 done<br>";
	//alert("4 done");
	BlAttempts[4]++;
	if (BlAttempts[4] > trials) {Error += "Block 4 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 5){
	// block 5
	Error += "<br>Block 5 start<br>";
	for (r=3;r<6;r++) {
		for (c=3;c<6;c++) {
			temp = new Array(1,2,3,4,5,6,7,8,9);
			// remove numbers in block to the left same row
			temp[grid[r][0]-1] = "";
			temp[grid[r][1]-1] = "";
			temp[grid[r][2]-1] = "";
			if (c>3) {
				temp[grid[r][3]-1] = "";
				}
			if (c==5) {
				temp[grid[r][4]-1] = "";
				}
			if (r==4) {
				temp[grid[r][c-1]-1] = "";
				temp[grid[r-1][3]-1] = "";
				temp[grid[r-1][4]-1] = "";
				temp[grid[r-1][5]-1] = "";
				force = new Array();
				// force to take what is left in bottom row block to left
				for (b=0;b<3;b++) {
					bl = grid[r+1][b];
					if (temp.toString().indexOf(bl) > -1) {
						force[bl-1] = bl;
						temp[bl-1] = "";
						}
					}
				Error +="forced "+ force +" : ";
				if (force.toString().match(/\d/g)) {
					temp = force;
					}
				Error += "temp : "+temp +"<br>";
				}
			if (r==5) {
				temp[grid[r-1][3]-1] = "";
				temp[grid[r-1][4]-1] = "";
				temp[grid[r-1][5]-1] = "";
				temp[grid[r-2][3]-1] = "";
				temp[grid[r-2][4]-1] = "";
				temp[grid[r-2][5]-1] = "";
				temp[grid[r][c-1]-1] = "";
				temp[grid[r][c-2]-1] = "";
				}
			// remove numbers in block above same column
			temp[grid[0][c]-1] = "";
			temp[grid[1][c]-1] = "";
			temp[grid[2][c]-1] = "";
			if (temp.toString() == ",,,,,,,,") {Error += "5 breaking (commas)<br>"; Block = 4; break;}
			if (!temp.toString().match(/\d/)) {Error += "5 breaking (no # match)<br>"; Block = 4; break;}
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){c--;}
			else {
				Error += r +","+c+") "+temp +" ["+ num +" - "+ temp[num] +"]<br>";
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		if (Block == 4 ) {break;}
		}
	Error += "Block 5 done<br>";
	//alert("5 done");
	BlAttempts[5]++;
	if (BlAttempts[5] > trials) {Error += "Block 5 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 6){
	// block 6
	Error += "<br>Block 6 start<br>";
	for (r=3;r<6;r++) {
		for (c=6;c<9;c++) {
			temp = new Array(1,2,3,4,5,6,7,8,9);
			// remove numbers in block to the left same row
			temp[grid[r][0]-1] = "";
			temp[grid[r][1]-1] = "";
			temp[grid[r][2]-1] = "";
			temp[grid[r][3]-1] = "";
			temp[grid[r][4]-1] = "";
			temp[grid[r][5]-1] = "";
			// remove numbers in block above same column
			temp[grid[0][c]-1] = "";
			temp[grid[1][c]-1] = "";
			temp[grid[2][c]-1] = "";
			if (c>6) {
				temp[grid[r][6]-1] = "";
				}
			if (c==8) {
				temp[grid[r][7]-1] = "";
				}
			if (r==4) {
				temp[grid[r][c-1]-1] = "";
				temp[grid[r-1][6]-1] = "";
				temp[grid[r-1][7]-1] = "";
				temp[grid[r-1][8]-1] = "";
				force = new Array();
				// force to take what is left in bottom row block to left
				for (b=3;b<6;b++) {
					bl = grid[r+1][b];
					if (temp.toString().indexOf(bl) > -1) {
						force[bl-1] = bl;
						temp[bl-1] = "";
						}
					}
				Error +="forced "+ force +" : ";
				if (force.toString().match(/\d/g)) {
					temp = force;
					}
				Error += "temp : "+temp +"<br>";
				}
			if (r==5) {
				temp[grid[r-1][6]-1] = "";
				temp[grid[r-1][7]-1] = "";
				temp[grid[r-1][8]-1] = "";
				temp[grid[r-2][6]-1] = "";
				temp[grid[r-2][7]-1] = "";
				temp[grid[r-2][8]-1] = "";
				temp[grid[r][c-1]-1] = "";
				temp[grid[r][c-2]-1] = "";
				Error += r +","+c+") "+temp +" ["+ num +" - "+ temp[num] +"] **<br>";
				}
			if (temp.toString() == ",,,,,,,,") {Error += "6 breaking (commas)<br>"; Block = 5; break;}
			if (!temp.toString().match(/\d/)) {Error += "6 breaking (no # match)<br>"; Block = 5; break;}
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){c--;}
			else {
				Error += r +","+c+") "+temp +" ["+ num +" - "+ temp[num] +"]<br>";
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		//	if (Block == 5 ) {break;}
		}
	Error += "Block 6 done<br>";
	//alert("6 done");
	BlAttempts[6]++;
	if (BlAttempts[6] > trials) {Error += "Block 6 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 7){
	//block 7
	Error += "<br>Block 7 start<br>";
	for (c=0;c<3;c++) {
	temp = new Array(1,2,3,4,5,6,7,8,9);
		temp[grid[0][c]-1] = "";
		temp[grid[1][c]-1] = "";
		temp[grid[2][c]-1] = "";
		temp[grid[3][c]-1] = "";
		temp[grid[4][c]-1] = "";
		temp[grid[5][c]-1] = "";
		for (r=6;r<9;r++) {
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){r--;}
			else {
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		}
	Error += "Block 7 done<br>";
	//alert("7 done");
	BlAttempts[7]++;
	if (BlAttempts[7] > trials) {Error += "Block 7 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 8){
	//block 8
	Error += "<br>Block 8 start<br>";
	for (c=3;c<6;c++) {
		for (r=6;r<9;r++) {
			temp = new Array(1,2,3,4,5,6,7,8,9);
			temp[grid[0][c]-1] = "";
			temp[grid[1][c]-1] = "";
			temp[grid[2][c]-1] = "";
			temp[grid[3][c]-1] = "";
			temp[grid[4][c]-1] = "";
			temp[grid[5][c]-1] = "";
		// remove block 7 numbers in this row.
			temp[grid[r][0]-1] = "";
			temp[grid[r][1]-1] = "";
			temp[grid[r][2]-1] = "";
		// remove numbers above in this row.
			if (r>6) {
				temp[grid[r-1][c]-1] = "";
				}
			if (r==8) {
				temp[grid[r-2][c]-1] = "";
				}
			if (temp.toString() == ",,,,,,,,") {Error += "8 breaking (commas)<br>"; Block = 7; break;}
			if (!temp.toString().match(/\d/)) {Error += "8 breaking (no # match)<br>"; break;}
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){r--;}
			else {
				Error += r +","+c+") "+temp +" ["+ num +" - "+ temp[num] +"]<br>";
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		if (Block == 7 ) {break;}
		}
	Error += "Block 8 done<br>";
	//alert("8 done");
	BlAttempts[8]++;
	if (BlAttempts[8] > trials) {Error += "Block 8 attempted more than "+trials+" times.<br>"; Block=10; }
	}

/////////////////////////////////

	if (Block == 9){
	//block 9
	Error += "<br>Block 9 start<br>";
	for (c=6;c<9;c++) {
		for (r=6;r<9;r++) {
			temp = new Array(1,2,3,4,5,6,7,8,9);
		// remove number in same column
			temp[grid[0][c]-1] = "";
			temp[grid[1][c]-1] = "";
			temp[grid[2][c]-1] = "";
			temp[grid[3][c]-1] = "";
			temp[grid[4][c]-1] = "";
			temp[grid[5][c]-1] = "";
		// remove numbers in sampe row
			temp[grid[r][0]-1] = "";
			temp[grid[r][1]-1] = "";
			temp[grid[r][2]-1] = "";
			temp[grid[r][3]-1] = "";
			temp[grid[r][4]-1] = "";
			temp[grid[r][5]-1] = "";
		// remove numbers in this block
			if (c>6) {
				temp[grid[6][c-1]-1] = "";
				temp[grid[7][c-1]-1] = "";
				temp[grid[8][c-1]-1] = "";
				}
			if (c==8) {
				temp[grid[6][c-2]-1] = "";
				temp[grid[7][c-2]-1] = "";
				temp[grid[8][c-2]-1] = "";
				}
			if (temp.toString() == ",,,,,,,,") {Error += "9 breaking (commas)<br>"; Block = 8; break;}
			if (!temp.toString().match(/\d/)) {Error += "9 breaking (no # match)<br>"; break;}
			num = Math.floor(Math.random() * temp.length);
			if (!temp[num]){r--;}
			else {
				Error += r +","+c+") "+temp +" ["+ num +" - "+ temp[num] +"]<br>";
				grid[r][c] = temp[num];
				temp[num] = "";
				}
			}
		if (Block == 8 ) {break;}
		}
	Error += "Block 9 done<br>";
	//alert("9 done");
	BlAttempts[9]++;
	if (BlAttempts[9] > trials) {Error += "Block 9 attempted more than "+trials+" times.<br>"; Block=10;}
	}

/////////////////////////////////

	if (Block == 10){
		if (grid.toString().indexOf(",,") > -1) {
			// start over
			Block = 0;
			GrAtt ++;
			if (GrAtt == 10) {	alert("Generating random grid");}
			if (GrAtt == 20) {	alert("Still generating grid");}
			if (GrAtt == 30) {	alert("Almost done generating grid");}
			if (GrAtt == 40) {	alert("I promise, I am just about done generating grid");}
			}
		else {
			return grid;
			}
		}
	}
}

