Идея за судоку, решаване.

RiddleR

Registered
Здравейте, имам един скрипт за судоку:

Код:
	<script type="text/javascript">
		
	var squareObjects = new Array();
	var level = 1;	// 1 is lowest level
	var countSquares = [36,36,34,32,31,30];
	var gameFinished = false;
	function shuffleBoard()
	{
		for(var counter=0;counter<30;counter++){
			var number1 = Math.ceil(Math.random()*9);
			var number2 = Math.ceil(Math.random()*9);
			while(number2==number1){
				number2 = Math.ceil(Math.random()*9);
			}	

			var tmpObjects1 = new Array();
			var tmpObjects2 = new Array();
			
			for(var no=0;no<squareObjects.length;no++){					
				var txtObj = squareObjects[no].getElementsByTagName('SPAN')[0];						
				if(txtObj.innerHTML == number1)tmpObjects1.push(txtObj);	
				if(txtObj.innerHTML == number2)tmpObjects2.push(txtObj);
			}
			
			for(var no=0;no<tmpObjects1.length;no++){
				tmpObjects1[no].innerHTML = number2;	
				tmpObjects2[no].innerHTML = number1;	
			}
		}
		resetVisibleNumberArray();
		showColumnsInGroup();
	}
	
	function resetVisibleNumberArray()
	{
		for(var no=0;no<=9;no++){
			visibleNumberArray[no] = 0;
		}		
	}
	
	function newGame()
	{
		var obj = document.getElementById('sudoku');
		var subObjects = obj.getElementsByTagName('DIV');
		for(var no=0;no<subObjects.length;no++){
			if(subObjects[no].className=='sudokuSquare'){
				subObjects[no].style.backgroundColor='';	
				var spans = subObjects[no].getElementsByTagName('SPAN');
				spans[0].style.display='none';
				spans[1].innerHTML = '';
			}
		}	
		
	}
	
	var visibleNumberArray = new Array();

	function randomizeArray(a,b){
		return Math.random() - Math.random();
	}
		
	function showCell(inputDiv)
	{
		var span = inputDiv.getElementsByTagName('SPAN')[0];
		span.style.display='';
		inputDiv.style.backgroundColor='#DDD';
		span.style.color='#317082';
		var typingSpan = inputDiv.getElementsByTagName('SPAN')[1];
		typingSpan.style.display='none';			
		
	}
	
	function showColumnsInGroup(){		
		var object = document.getElementById('sudoku');
		var cellsRevealed = new Array();
		var numberArray = new Array();
		var groupCountArray = new Array();
		var maxInGroup=5;
		if(level<=0)level=1;
		if(level==1)maxInGroup=4;
		for(var no=0;no<countSquares[level];no++){			
			do{
				var row = Math.floor(Math.random()*9);
				var col = Math.floor(Math.random()*9);
				var obj = document.getElementById('square_' + row + '_' + col);
				var parentID = obj.parentNode.id;
				var span = obj.getElementsByTagName('SPAN')[0];	
				if(!numberArray[span.innerHTML])numberArray[span.innerHTML]=0;
				if(!groupCountArray[parentID])groupCountArray[parentID]=0;
			}while(cellsRevealed[row + '_' + col] || numberArray[span.innerHTML]>(3+Math.ceil(level/2)) || groupCountArray[parentID]>=maxInGroup);
			cellsRevealed[row + '_' + col] = true;
			if(!numberArray[span.innerHTML])numberArray[span.innerHTML]=0;
			numberArray[span.innerHTML]++;
			groupCountArray[parentID]++;
			showCell(obj);
			
		}
	}
	var higlightedCell;
	function highlightSquare(e,inputObj){
		document.getElementById('hintDiv').style.display='none';
		if(!inputObj)inputObj = this;	
		if(inputObj.style.backgroundColor)return;
		if(gameFinished)return;
		inputObj.className='sudokuSquareHighlighted';
		if(higlightedCell && higlightedCell!=inputObj)higlightedCell.className='sudokuSquare';
		higlightedCell = inputObj;
		if(document.all)inputObj.focus();
		
	}
	
	
	function isGameFinished()
	{
		var obj = document.getElementById('sudoku');
		var subDivs = obj.getElementsByTagName('DIV');
		var allOk = true;
		for(var no=0;no<subDivs.length;no++){
			if(subDivs[no].className.indexOf('sudokuSquare')>=0 && !subDivs[no].style.backgroundColor){
				var spans = subDivs[no].getElementsByTagName('SPAN');
				if(spans[0].innerHTML != spans[1].innerHTML){
					allOk=false;
					break;
				}
			}	
		}
		
		if(allOk)alert('Поздравления! Ти успя да го решиш без грешка!');
		
	}
	
	function initSudoku()
	{
		gameFinished = false;
		document.getElementById('hintDiv').style.display='none';
		var matrix = new Array();
		for(var rowCounter=0;rowCounter<9;rowCounter++){
			matrix[rowCounter] = new Array();
			for(var colCounter=0;colCounter<9;colCounter++){
				var number = colCounter/1 + 1 + (rowCounter*3) + Math.floor(rowCounter/3)%3;
				if(number>9)number = number % 9;
				if(number==0)number=9;
				matrix[rowCounter][colCounter] = number;				
			}			
		}
		
		// Switching rows
		
		for(var no=0;no<9;no+=3){
			
			for(var no2=0;no2<3;no2++){
				row1 = Math.floor(Math.random()*3);	
				row2 = Math.floor(Math.random()*3);	
				while(row2==row1){
					row2 = Math.floor(Math.random()*3);	
				}
				row1 = row1 + no;
				row2 = row2 + no;			
				var tmpMatrix = new Array();
				tmpMatrix = matrix[row1];
				matrix[row1] = matrix[row2];
				matrix[row2] = tmpMatrix; 				
			}			
		}
		
		// Switching columns
		
		for(var no=0;no<9;no+=3){
			for(var no2=0;no2<3;no2++){
				col1 = Math.floor(Math.random()*3);	
				col2 = Math.floor(Math.random()*3);	
				while(col2==col1){
					col2 = Math.floor(Math.random()*3);	
				}
				col1 = col1 + no;
				col2 = col2 + no;			

				var tmpMatrix = new Array();
				for(var no3=0;no3<matrix.length;no3++){
					tmpMatrixValue = matrix[no3][col1];
					matrix[no3][col1] = matrix[no3][col2];				
					matrix[no3][col2] = tmpMatrixValue;				
				}
			}	
		}
		
		
		for(var no=0;no<matrix.length;no++){
			for(var no2=0;no2<matrix[no].length;no2++){				
				var obj = document.getElementById('square_' + no + '_' + no2);
				var spanObjects = obj.getElementsByTagName('SPAN');
				
				var span = spanObjects[0];
				span.innerHTML = matrix[no][no2];		
				span.style.display='none';	
				
				spanObjects[1].innerHTML = '';
				spanObjects[1].style.display = '';
				spanObjects[1].style.color='#000';	

				obj.onclick = highlightSquare;
						
				squareObjects.push(obj);						
			}			
		}
		if(document.all){
			document.body.onkeydown = insertNumber;
		}else{
			document.documentElement.onkeydown = insertNumber;
		}

		newGame();
		shuffleBoard();
	}
	function insertNumber(e)
	{
		document.getElementById('hintDiv').style.display='none';

		if(document.all)e = event;
		if(!higlightedCell)return;
		if(gameFinished)return;
		if (e.keyCode) code = e.keyCode; else if (e.which) code = e.which;
		var span = higlightedCell.getElementsByTagName('SPAN')[1];
		
		var numbers = higlightedCell.id.split('_');

		var row = numbers[1]/1;
		var col = numbers[2]/1;
		var nextObject = false;
			
		if(code==39){ // Right arrow
			if(col<8){
				nextObject = document.getElementById('square_' + row + '_' + (col/1+1));
				if(nextObject.style.backgroundColor){
					while(col<8 && nextObject.style.backgroundColor){
						col = col+1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}				
			}
		}
		if(code==37){ // Left arrow
			if(col>0){
				nextObject = document.getElementById('square_' + row + '_' + (col/1-1));
				if(nextObject.style.backgroundColor){
					while(col>0 && nextObject.style.backgroundColor){
						col = col-1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}
				if(nextObject.style.backgroundColor)nextObject = false;
			}
		}
		if(code==38){
			if(row>0){
				nextObject = document.getElementById('square_' + (row-1) + '_' + col);
				if(nextObject.style.backgroundColor){
					while(row>0 && nextObject.style.backgroundColor){
						row = row-1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}				
			}
		}		
		if(code==40){
			if(row<8){
				nextObject = document.getElementById('square_' + (row+1) + '_' + col);
				if(nextObject.style.backgroundColor){
					while(row<8 && nextObject.style.backgroundColor){
						row = row+1;
						nextObject = document.getElementById('square_' + row + '_' + col);
					}
				}	
			}
		}
		
		if(nextObject){
			highlightSquare(false,nextObject);
		}
		
		if(code==46 || code==8){	// Delete
			span.innerHTML = '';
			if(code==8)return false;
		}
		if(code>96 && code<=105)code-=48;
		if(code>48 && code<=57){				
			var theChar = String.fromCharCode(code);
			span.innerHTML = theChar;
		}		
		
		isGameFinished();
	}	
	
	function helpMe()
	{
		if(gameFinished)return false;
		
		if(confirm('Искаш ли да открием едно число?')){
			var allreadyRevealed = true;
			var counter = 0;
			do{
				var row = Math.floor(Math.random()*9);
				var col = Math.floor(Math.random()*9);
				
				var el = document.getElementById('square_'+row+'_'+col);	
				
				var spans = el.getElementsByTagName('SPAN');
				if(spans[1].innerHTML.length==0){
					spans[1].innerHTML = spans[0].innerHTML;
					spans[1].style.color='#FF0000';
					allreadyRevealed =  false;					
				}	
				if(el.style.backgroundColor)allreadyRevealed=true;
				counter++
			}while(allreadyRevealed && counter<500);		
		}
		
		isGameFinished();
		
	}
		
	function isCorrect(divObj)
	{
		var spans = divObj.getElementsByTagName('SPAN');
		if(spans[0].innerHTML==spans[1].innerHTML || spans[1].innerHTML.length==0)return true;
		return false;		
	}
	
	function getTopPos(inputObj)
	{
		
	  var returnValue = inputObj.offsetTop;
	  while((inputObj = inputObj.offsetParent) != null){
	  	returnValue += inputObj.offsetTop;
	  }
	  return returnValue;
	}
	
	function getLeftPos(inputObj)
	{
	  var returnValue = inputObj.offsetLeft;
	  while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
	  return returnValue;
	}
		
	function getPossibleNumbers(inputObj)
	{
		var noArray = new Array();
		var countNumbers = 0;
		var spans = inputObj.getElementsByTagName('SPAN');
		if(spans[0].innerHTML ==spans[1].innerHTML)return 0;
		
		var parentDiv = inputObj.parentNode;
		var subDivs = parentDiv.getElementsByTagName('DIV');
		for(var no=0;no<subDivs.length;no++){
			if(subDivs[no]!=inputObj){
				var spans = subDivs[no].getElementsByTagName('SPAN');
				if(spans[0].innerHTML == spans[1].innerHTML || subDivs[no].style.backgroundColor.length>1){
					if(!noArray[spans[0].innerHTML]){
						noArray[spans[0].innerHTML] = true;		
						countNumbers++;
					}		
				}
			}	
		}
	
		var numbers = inputObj.id.split('_');
		var row = numbers[1];
		var col = numbers[2];
		
		for(var no=0;no<9;no++){			
			
			var obj = document.getElementById('square_' + row + '_' + no);
			if(obj!=inputObj){
				var spans = obj.getElementsByTagName('SPAN');	
				if(spans[0].innerHTML == spans[1].innerHTML || !spans[0].style.display){
					if(!noArray[spans[0].innerHTML]){
						noArray[spans[0].innerHTML] = true;		
						countNumbers++;
					}			
				}
			}
			
			var obj = document.getElementById('square_' + no + '_' + col);
			if(obj!=inputObj){
				var spans = obj.getElementsByTagName('SPAN');	
				if(spans[0].innerHTML == spans[1].innerHTML || !spans[0].style.display){
					if(!noArray[spans[0].innerHTML]){
						noArray[spans[0].innerHTML] = true;	
						countNumbers++;
					}				
				}
			}
		}	

		return countNumbers;
	}
	
	function showHint()
	{
		var hintDiv = document.getElementById('hintDiv');
		var hintDivInner = hintDiv.getElementsByTagName('DIV')[0];
		var maxExistingNo = 0;	
		var objectToTry =false;	
		for(var row=0;row<9;row++){
			for(var col=0;col<9;col++){
				var obj = document.getElementById('square_' + row + '_' + col);
				if(obj.style.backgroundColor)continue;
				if(!isCorrect(obj)){
					hintDivInner.innerHTML = 'Това е грешно';
					hintDiv.style.left = getLeftPos(obj) + 'px';
					hintDiv.style.top = getTopPos(obj) - 50 + 'px';
					hintDiv.style.display='block';		
					return;			
				}	
				
				var existingNumbers = getPossibleNumbers(obj);	
				if(existingNumbers>maxExistingNo){
					maxExistingNo = existingNumbers;
					objectToTry = obj;					
				}	
			}
		}
		
		if(objectToTry){
			hintDivInner.innerHTML = 'Опитайте с друго';
			hintDiv.style.left = getLeftPos(objectToTry) + 'px';
			hintDiv.style.top = getTopPos(objectToTry) - 50 + 'px';
			hintDiv.style.display='block';				
			
		}
		
		
	}
	
	
	function revealAll()
	{
		for(var row=0;row<9;row++){
			for(var col=0;col<9;col++){
				var obj =document.getElementById('square_'+row+'_'+col);
				var spans = obj.getElementsByTagName('SPAN');
				spans[0].style.display='';
				spans[1].style.display='none';	
				spans[1].style.color='#000000';	
			}
		}
		gameFinished=true;
	}
	
	function switchLevel(initLevel,linkObj)
	{
		var confirmSwitch = gameFinished;
		if(!confirmSwitch)confirmSwitch = confirm('Натиснете OK, за да започнете следващата игра.');
		if(confirmSwitch){
			var parentObj = linkObj.parentNode.parentNode;
			var links = parentObj.getElementsByTagName('A');
			for(var no=0;no<links.length;no++){
				links[no].style.fontWeight='normal';
			}
			linkObj.style.fontWeight = 'bold';
			level = initLevel;
			setTimeout('initSudoku()',20);		
		}
	}
	

	
	window.onload = initSudoku;
	</script>



Това е малка част от кода на судокуто, която извършва функциите на играта.
Има ли начин, от даден .txt файл да речем, судокуто да взима числата, за играта и автоматично да решава дадените числа, като записва решението в друг .txt файл?
 
Я виж това:
[js]var data = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
data = xmlhttp.responseText;
}
};
xmlhttp.open("GET","sudoku.txt",true);
xmlhttp.send();
//сега в променливата data ще имаш съдържанието на sudoku.txt
[/js]
http://stackoverflow.com/questions/3582671/how-to-open-a-local-disk-file-with-javascript

Само да отбележа, че sudoku.txt трябва да се намира в същата директория.
 
RiddleR каза:
нищо не записва в файла.
Е ти какво очакваш? Този код не е за записване, а за взимане на информация. Няма как с javascript да записваш файлове. (ако не беше така, щях да мога да сменя всеки файл на всеки сървър :Д)
 
аз нарочно съм пуснал темата в php раздела, тоест това трябва да стане някакси с php :)
 
Ахааааа...
Значи за взимане на данни ползваш горния код. За запис правиш така:

[js]var data = 'тук е това, което ще се запише в file.txt';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
if( xmlhttp.responseText == 0 )
alert('възникна грешка!');
else
alert('промените са записани!');
}
};
xmlhttp.open("GET","sudoku.php?data=" + data,true);
xmlhttp.send();[/js]

и sudoku.php:

PHP:
$data = $_GET['data'];
if(file_put_contents("sudoku.txt", $data, FILE_APPEND) !== FALSE)//това ще ДОписва в sudoku.txt. Ако искаш да ЗАписва, махни file_append
die(1);//ако има запис
die(0);//ако няма запис

Разбира се в случая приемаме, че няма да пращаш "лоши" данни.
 
Код:
var data = 'gameFinished';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
  if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
    if( xmlhttp.responseText == 0 )
      alert('възникна грешка!');
    else
      alert('промените са записани!');
  }
};
xmlhttp.open("GET","sudok.php?data=" + data,true);
xmlhttp.send();

излиза ми възникна грешка
 
Я пробвай така:
[js] if(xmlhttp.responseText != 1 )
alert('възникна грешка!\nsudokyu.php върна: ' + xmlhttp.responseText);
else
alert('промените са записани!');[/js]
за да видиш какво ти е върнал sudoku.php. Освен това на предпоследния ред сигурен ли си, че нямаш грешка?
[js]xmlhttp.open("GET","sudok.php?data=" + data,true);
[/js]файлът не се ли казва sudoku.php
 
не, така се казва файла.

ся в файла записва :

Код:
gameFinishedgameFinishedgameFinishedgameFinished
 
По - добре за тези заявки(ajax) използвай Jquery, голяма част от бъговете са отстранени.
 
RiddleR каза:
не, така се казва файла.

ся в файла записва :

Код:
gameFinishedgameFinishedgameFinishedgameFinished
Тогава замести функцията с това:
file_put_contents("sudoku.txt", $data . "\n", FILE_APPEND)
И ще слага нови редове при всяко записвне.
 
Тук има клас за решаване на судоко: https://github.com/austinsmorris/sudoku-solver-php

Виж example-а, ще ти помогне.
 

Back
Горе