/*-----------------------------------------------------------------------
	This script is NOT freeware. Please email if you want to re-use it.
	Your comments on how it could be improved would be appreciated
	Andrew Stuart, 23 May 2005, andrew@scanraid.com
	Version 1.38, 02-Dec-2006
-----------------------------------------------------------------------*/
var stage=0,laststage=0,prevlaststage=0;
var print_version=false;
var showhints=true;
var steps=0;
var save_dstring='';
var some_changes=false;
var firsttime=true;
var some_saved=false;
var cordX;
var cordY;
var rcbname=["Row","Col","Box"];
var abety="ABCDEFGHJ";
var abetx="123456789";
var MAX_STRAT = 5;
var coordmode=1;
var SSIZE=9;
var WHITECELL=0;
var BLACKCELL=1;

// Mask is a 2D array of ints which actually store bit arrays of numbers 1 to 9.
var mask=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var g   =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var jc  =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var save=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var orig=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var last=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var tran=[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var xn  =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var yn  =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var xset =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var yset =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var show =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var tried =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
var rset=[0,0,0,0,0,0,0,0,0];
var cset=[0,0,0,0,0,0,0,0,0];

var str8ts_examples = [
"007000000700200000001500000060000000000004005049007052000000000000900100000000030","007321000780253460871542396062430087123004675349067852235896714056978123000789030","111000111001000001000000000110001100000111000001100011000000000100000100111000111",//g
"803000000100400508000000060000005700009000005000010000060000020000000003000000000","823007650132476598451230867210345789679123045345012076768051324597860213086700430","100110001100100000000001000001001000001000100000100100000100000000001001100011001",//g
"000070001500700000031000000420080000000000500040000006070000000000900030097010000","058670021589760312231856470423087650314208567042300786076435098765924130897013240","100001100100001000001000001000110001000010000100011000100000100000100001001100001",//m
"010090000000000400000754000005020006000000600500009700300040000000005000000000502","017890230756983420689754300045021076478312695560239780302146857023475968034067502","110001001000000001000010011100100100000000000001001001110010000100000000100100011",//m
"000600003000200000200030000000500070000001060070000000060000900500010000000070000","005607803034206780210435098123568479002341560671859324760123945589714230008972100","110010011100010001001000100000000000110000011000000000001000100100010001110010011",//t
"000007000000000002005026000000000000609100000000850000000000030000504000300010000","032007860054068792045326987513240076679132045760853214427681530086574320398710450","100110001100100001100000000000001100001000100001100000000000001100001001100011001",//t
"490036005000000000000200000000000000003004010000000006000000008100090000000000000","497836125678903254780265043564781932003654710315472896230540078142398567021007680","100011001000010000001100100000000000110000011000000000001001100000010000100110001",//d
"020060000000000068004000000000000000010200000000000109000000000700000000270000030","023167890532409768654312087045938276016245300867523149980756012798601423279804530","100010001000010000001000100100000000110000011000000001001000100000010000100010001"];//d


function bit_count( b )
{
    var n=0;
	if ( !b ) return 0;
    do { ++n; } while ( b &= (b-1) );
    return  n;
}
function IsNumeric(strChar)   //  check for valid numeric strings
{
	var strValidChars="123456789";
	var blnResult=true;

	if (strChar.length == 0) return false;

	if (strValidChars.indexOf(strChar) == -1)
	   blnResult=false;
	return blnResult;
}
function mask2str( m )
{
	var i,p=0,str='';
	for(i=0;i<9;i++)
		if( m & (1 << i))
		{
			if( p++ ) str=str + '/';
			str=str + abetx.charAt(i);
		}
	return str;
}
function bit2int( m )
{
	switch( m ) {
	case 1   : return 0;
	case 2   : return 1;
	case 4   : return 2;
	case 8   : return 3;
	case 16  : return 4;
	case 32  : return 5;
	case 64  : return 6;
	case 128 : return 7;
	case 256 : return 8;
	}
	return 0;
}
var BOARD_MASK = 511;

function MASK_LIMIT(x) { return (x<BOARD_MASK); }
function cordit(y,x)
{
	if( coordmode==0 ) return 'r' + abetx.charAt(y) + 'c' + abetx.charAt(x);
	return abety.charAt(y) + abetx.charAt(x);
}
function strat_add( s )
{
	var doc;
	if( !document.ifrm )
		 doc = document.getElementById("ifrm").contentDocument;
	else doc = document.ifrm.document;
	doc.body.innerHTML = doc.body.innerHTML + s
}
/*---------------------------------------------------------------------*/
/* Draws the content of a square on the board							*/
/*---------------------------------------------------------------------*/
function set_square( x, y, val, setup, final_cand )
{
	var t, s;
	var sq_col=['black','#CC0000','blue','blue'];
	var sq_siz=['8pt','14pt','14pt','14pt','8pt','18pt','18pt','18pt'];

	// Get the table cell name out using the coordinates
	t=document.getElementById("a"+y+x);
	if( (setup==0 && showhints) || setup > 0 )
		 t.innerHTML=val;	// Assign the new value to the cell
	else t.innerHTML='&nbsp;';	// Assign the new value to the cell
	t.style.color=(print_version) ? 'black' : sq_col[setup];
	t.style.fontSize=(print_version) ? '20pt' : sq_siz[setup];
	if( !print_version && setup == 3 )
		t.style.backgroundColor = '#ff0000';
	else
	{
		if( jc[y][x]==1 )
		{
			t.style.backgroundColor = "#000000";
			t.style.color = (g[y][x]) ? "#ffffff" : "#000000";
		}
		else
		{
			t.style.borderColor = (final_cand) ? "#00ff00" : "#000000";
			t.style.backgroundColor = (final_cand) ? "#ccffcc" : "#ffffff";
			t.style.color = (g[y][x]) ? "#000000" : "#000000";
		}
	}

	if( print_version ) return;
	s="D" + y.toString()+x.toString();
	if( val == "&nbsp;" )
		document.forms.DataEntry.elements[s].value='';
	else if( setup ) document.forms.DataEntry.elements[s].value=val;
}
function set_print_square( y, x, val )
{
	if( jc[y][x]=='0' ) // White background
	{
		if( val == ' ' || val == '0' || val == 0 )
		{
			document.getElementById('C' + y + x).innerHTML = '&nbsp;';
			document.getElementById('C' + y + x).className = (jc[y][x]==BLACKCELL)?'InnerTClues':'InnerTDone';
		}
		else
		{
			document.getElementById('C' + y + x).innerHTML = val;
			document.getElementById('C' + y + x).className = (jc[y][x]==BLACKCELL)?'InnerTClues':'InnerTDone';
		}
	}
	else
	{
		if( val == ' ' || val == '0' || val == 0 )
			 document.getElementById('C' + y + x).innerHTML = '&nbsp;';
		else document.getElementById('C' + y + x).innerHTML = val;
		document.getElementById('C' + y + x).className = 'InnerBDone';
	}
}


/*----------------------------------------------------------------------*/
/* Converts the bit array to a string of numbers for display			*/
/*----------------------------------------------------------------------*/
function lable_square( y, x, deduct )
{
	var lable, c, i, modfact=3;
	lable='';
	c=0;
	mask[y][x] -= deduct;
	show[y][x] += deduct;
	tran[y][x] += deduct;
	modfact=3;
	lable = '<table id="cl' + y + x + '" class="candtb" cellspacing=0 align=center>';
	for( i=0;i<9;i++ )
	{
		if( (i % modfact) == 0 )
			lable=lable + "<tr>";
		cel = '<td id="w' + y + x + i + '"';
		if( mask[y][x] & (1 << i) )	// i=0 to 8 so first shift is 0 bits
		{
			if( show[y][x] & (1 << i) )
				lable=lable + cel + ' class="fsh">' + (i+1) + '</td>';
			else
				lable=lable + cel + '>' + (i+1) + "</td>";
		}
		else
		{
			if( show[y][x] & (1 << i) )
				lable=lable + cel + ' class="fsh">' + (i+1) + '</td>';
			else lable=lable + cel + '>&nbsp;</td>';
		}
		if( (i % modfact) == 2 )
			lable=lable + "</tr>";
	}
	lable=lable + "</table>";
	set_square(x,y,lable,0,bit_count(mask[y][x])==1);
	some_changes=true;
}
function change_hints()
{
	showhints=!showhints;
	for(var j=0;j<9;j++)
		for(var i=0;i<9;i++)
			if( g[j][i] == 0 )
				lable_square( j, i, 0 );
}
function get_set_lengths()
{
	var i,x,y,cx=0,cy=0,a;

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			if( jc[y][x] == WHITECELL && (x==0 || jc[y][x-1] == BLACKCELL ) )
			{
				for(cx=0,i=x;i<9 && jc[y][i] == WHITECELL;i++) cx++;
				for(i=x;i<9 && jc[y][i] == WHITECELL;i++) xset[y][i] = cx;
			}
			if( jc[y][x] == WHITECELL && (y==0 || jc[y-1][x] == BLACKCELL ) )
			{
				for(cy=0,i=y;i<9 && jc[i][x] == WHITECELL;i++) cy++;
				for(i=y;i<9 && jc[i][x] == WHITECELL;i++) yset[i][x] = cy;
			}
		}
}

/*---------------------------------------------------------------------*/
/* Sets the board up from scratch and draws it. Called from onLoad */
/*---------------------------------------------------------------------*/
function load_board()
{
	var i,j,t,s,nt,k,p,a,doc,bdoc,c;
	var bd=location.search;
	var oRow,sRow,par;
	var content;
	prevlaststage=laststage=stage=0;

	cordX=new Array(81);
	cordY=new Array(81);
	APEstack=new Array(81);


	if( !document.ifrm )
		 doc = document.getElementById("ifrm").contentDocument;
	else doc = document.ifrm.document;
	doc.body.innerHTML='Results will go here!';
	doc.body.style.backgroundColor='#ddeeff';
	doc.body.style.color='#000000';

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
			yn[j][i]=xn[j][i]=yset[j][i]=xset[j][i]=tran[j][i]=jc[j][i]=g[j][i]=show[j][i]=orig[j][i]=mask[j][i]=0;

	w = document.forms.DataEntry.elements["Example"].selectedIndex;

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			if( bd.length==166 && firsttime )
			{
				if( IsNumeric(bd.charAt((j*9)+i+4)) )
				{
					c = bd.charAt((j*9)+i+4);
					g[j][i] = (c=='0')? 0 : c*1;
				}
				if( IsNumeric(bd.charAt((j*9)+i+85)) )
				{
					c = bd.charAt((j*9)+i+85);
					jc[j][i] = (c=='0')? 0 : 1;
				}
				document.forms.DataEntry.elements["D"+j+i].className = ( jc[j][i] ) ? "DE3" : "DE2";
			}
			else
			{
				c = str8ts_examples[w*3].charAt((j*9)+i);
				g[j][i] = (c=='0')? 0 : c*1;
				jc[j][i] = (str8ts_examples[w*3+2].charAt(j*9+i)=='1') ? BLACKCELL : WHITECELL;
				document.forms.DataEntry.elements["D"+j+i].className = ( jc[j][i] ) ? "DE3" : "DE2";
			}

			show[j][i]=orig[j][i]=mask[j][i]=0;
			if( g[j][i] > 0 )
				set_square(i,j,g[j][i],1,false);
			else
			{
				orig[j][i]=mask[j][i]=511;
				lable_square( j,i,0 );
			}
		}


	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
	if( readCookie('scanraidsudokucookie') )
	{
		document.getElementById("reload").className="SButton";
		some_saved=true;
	}
	get_set_lengths();
	some_changes=false;
	firsttime=false;
}

function load_print_board()
{
	var i,j,t,s,nt,k,p,a,doc,bdoc,c;
	var bd=location.search;
	var oRow,sRow,par;
	var content;
	prevlaststage=laststage=stage=0;

	cordX=new Array(81);
	cordY=new Array(81);
	APEstack=new Array(81);

/*
007000000
700200000
001500000
060000000
000004005
049007052
000000000
000900100
000000030
111000111001000001000000000110001100000111000001100011000000000100000100111000111
*/


	par=parent.opener.document;

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			jc[j][i]=g[j][i]=show[j][i]=orig[j][i]=mask[j][i]=0;
		}

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			if( bd.length==166 && firsttime )
			{
				if( IsNumeric(bd.charAt((j*9)+i+4)) )
				{
					c = bd.charAt((j*9)+i+4);
					g[j][i] = (c=='0')? 0 : c*1;
				}
				if( IsNumeric(bd.charAt((j*9)+i+85)) )
				{
					c = bd.charAt((j*9)+i+85);
					jc[j][i] = (c=='0')? 0 : 1;
				}
			}
			else
			{
				c = str8ts_examples[w*3].charAt((j*9)+i);
				g[j][i] = (c=='0')? 0 : c*1;
				jc[j][i] = (str8ts_examples[w*3+2].charAt(j*9+i)=='1') ? BLACKCELL : WHITECELL;
				document.forms.DataEntry.elements["D"+j+i].className = ( jc[j][i] ) ? "DE3" : "DE2";
			}

			show[j][i]=orig[j][i]=mask[j][i]=0;
			if( g[j][i] > 0 )
				set_print_square(j,i,g[j][i]);
			else
			{
				orig[j][i]=mask[j][i]=511;

				t=document.getElementById("C" + j + i);
				s=par.getElementById("a" + j + i);
				content=s.innerHTML;
				if( content != '&nbsp;' )
				{
					var tb='';
					rExp=/<font color=#ddeeff>0<\/font>/gi;
					content=content.replace(rExp,'&nbsp;&nbsp;');
				}
		//		t.className=s.className;
				t.innerHTML=s.innerHTML;
				t.style.backgroundColor=s.style.backgroundColor;
		//		alert(sRow.cells[i % 3].innerHTML);
			}
		}

}

function import_str8ts()
{
	var dstring;
	var actualstr='';
	var c,i,j,s,t;

	dstring=window.prompt("Enter a string of 81 numbers (you can express blanks as 0, *, _ or '.')",save_dstring);
	if( dstring == null ) return;
	if( dstring.length == 0 ) return;

	save_dstring=dstring;

	for(i=0;i<dstring.length;i++)
	{
		c=dstring.charAt(i);
		if( IsNumeric(c) || c=='0' )
			actualstr=actualstr + dstring.charAt(i);
		else if( c=='.' || c=='*' || c=='_' )
			actualstr=actualstr + '0';
	}
	if( actualstr.length != 81 )
	{
		okay=false;
		alert("Your submission contained " + actualstr.length + " numbers. Please check it and press 'Import' again");
		return;
	}
	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			t=document.getElementById("a"+j+i);
			t.style.backgroundColor='#ddeeff';
			t.style.color='black';
			t.style.fontSize='8pt';
			show[j][i]=mask[j][i]=0;
			g[j][i]=parseInt(actualstr.charAt((j*9)+i));
			if( g[j][i] > 0 )
				set_square(i,j,g[j][i],1,false);
			else
			{
				orig[j][i]=mask[j][i]=511;
				lable_square( j,i,0 );
				s="D" + j.toString()+i.toString();
				document.forms.DataEntry.elements[s].value='';
			}
		}
	for(i=1;i<MAX_STRAT+1;i++)
		document.getElementById("R" + i).innerHTML='&nbsp;';
	some_changes=false;
	firsttime=false;
	prevlaststage=laststage=stage=0;
}
function clear_board()
{
	var i,t,x,y,nt;
	prevlaststage=laststage=stage=0;
	t=document.getElementById("TestT");
	for(i=0;i<MAX_STRAT;i++)
		t.rows[i].cells[0].style.backgroundColor="black";
	document.getElementById("backstep").className='GButton';
	for(x=0;x<9;x++)
		for(y=0;y<9;y++)
		{
			// get the call name again. maybe I should have used a better naming convention ;-)
			t=document.getElementById("a"+y+x);
			t.style.backgroundColor='#ddeeff';
			t.style.color='black';
			t.style.fontSize='8pt';
			orig[x][y]=mask[x][y]=511;	// This is the key: numbers 1-9 in bits=511,
			g[x][y]=0;					// .. and there are no picked squares
			set_square(y,x,"&nbsp;",0,false);		// nbsp it so the borders show up
		}
	for(i=1;i<MAX_STRAT+1;i++)
		document.getElementById("R" + i).innerHTML='&nbsp;';
}
function save_board()
{
	var i,j,s='';
	for( j in g )
		for( i in g[j] ) { s = s + g[j][i]; save[j][i]=g[j][i]; }
	document.getElementById("reload").className="SButton";
	some_saved=true;

	var date = new Date();
	date.setTime(date.getTime()+(30*24*60*60*1000));

	document.cookie ='scanraidsudokucookie=' + s + '; expires=' + date.toGMTString() + '; path=/'

	alert("Current Board Saved (as a cookie)");
}
function readCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}
function reload_board()
{
	var i,j,x;
	if( some_saved == false ) return;

	x = readCookie('scanraidsudokucookie')
	if (x)
	{
		clear_board();
		for( j=0;j<9;j++ )
			for( i=0;i<9;i++ )
			{
				g[j][i]=x.charAt((j*9)+i)*1;
				orig[j][i]=mask[j][i]=0;
				if( g[j][i] > 0 )
					set_square(i,j,g[j][i],1,false);
				else
				{
					orig[j][i]=mask[j][i]=511;	// This is the key: numbers 1-9 in bits=511,
										// so its saying on the empty board all squares have all numbers
					lable_square( j,i,0 );
				//	set_square(i,j,"&nbsp;",0,false);
				}
			}
		for(i=1;i<MAX_STRAT+1;i++)
			document.getElementById("R" + i).innerHTML='&nbsp;';
	}
	else
		document.getElementById("reload").className="GButton";
}
/*----------------------------------------------------------------------*/
/* First of the analyser functions - simply checks for single values	*/
/* which means a number MUST be the solution for that square			*/
/*----------------------------------------------------------------------*/
function check_for_single()
{
	var i,x,y,done=0;
	for( y=0;y<9;y++ )
		for( x=0;x<9;x++ )	// for every square on the board
		{
			for(i=0;i<9;i++)	// if the bit array contains only one bit
				if( mask[y][x] == (1 << i) )
				{
					g[y][x]=i+1;		// we have a single number and a solution
					mask[y][x]=0;		// ...wipe the mask
					set_square(x,y,g[y][x],2,false);	// and draw the number
					done++;
			//		some_changes=true;
				}
		}
	return done;
}
function check_for_one_single( y,x )
{
	var n;
	for(n=0;n<9;n++)
		if( mask[y][x] == (1 << n) )
		{
			g[y][x]=n+1;		// we have a single number and a solution
			mask[y][x]=0;		// ...wipe the mask
			set_square(x,y,g[y][x],2,false);	// and draw the number
			some_changes=true;
			return true;
		}
	return false;
}

function show_candidates()
{
	var changes;
	var x,y,i,a,b,j,zz,yy,n;


	/*----------------------------------------------------------------------*/
	/* check the rows and columns of each square							*/
	/* and to remove any bits for numbers that are found. Ie,we start with	*/
	/* 123456789 and zero any numbers in the array in each row/column		*/
	/*----------------------------------------------------------------------*/
	for( y=0;y<9;y++ )
		for( x=0;x<9;x++ )	// for every square on the board
			if( !g[y][x] && !jc[y][x] )	// if it is an unknown square...
			{
				changes=false;
				for( i=0;i<9;i++) // for the size of the board
				{
					if( i != x && g[y][i] > 0 ) // check values in row
						if( (mask[y][x] & (1 << (g[y][i]-1))) )
						{
							mask[y][x] -= (1 << (g[y][i]-1));	// remove that bit
							changes=true;
						}
					if( i != y && g[i][x] > 0 ) // check values in column
						if( (mask[y][x] & (1 << (g[i][x]-1))) )
						{
							mask[y][x] -= (1 << (g[i][x]-1));	// remove that bit
							changes=true;
						}
				}
				if( changes ) lable_square( y,x,0 );
			}

}
function range( n, m )
{
	var i, j, o=0;
	for(i=0;i<9;i++)
		if( n & (1 << i) )
		{
			for(j=i;j<i+m && j<9;j++) o |= (1 << j);
			for(j=i;j>i-m && j>=0;j--) o |= (1 << j);
		}
//	alert("before: " + mask2str(n) + " after: " + mask2str(o));
	return o;
}

function reset_candidates()
{
	var x,y;
	var tmpxn, tmpyn, cx, cy, new_xmm, new_ymm, band, b, i, off, a;

	for(y=0;y<9;y++) rset[y] = 0;
	for(x=0;x<9;x++) cset[x] = 0;

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			rset[y] += (1 << (g[y][x]-1));
			cset[x] += (1 << (g[y][x]-1));
			mask[y][x] = (g[y][x])? 0 : 511;
		}

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			if( jc[y][x] == WHITECELL && (x==0 || jc[y][x-1] == BLACKCELL ) )
			{
				for(cx=0,i=x;i<9 && jc[y][i] == WHITECELL;i++)
					if( g[y][i] ) cx += (1 << (g[y][i]-1));

				for(i=x;i<9 && jc[y][i] == WHITECELL;i++) xn[y][i] = cx;
			}
			if( jc[y][x] == WHITECELL && (y==0 || jc[y-1][x] == BLACKCELL ) )
			{
				for(cy=0,i=y;i<9 && jc[i][x] == WHITECELL;i++)
					if( g[i][x] ) cy += (1 << (g[i][x]-1));

				for(i=y;i<9 && jc[i][x] == WHITECELL;i++) yn[i][x] = cy;
			}
		}

	for(y=0;y<9;y++)
		for(x=0;x<9;x++) if( jc[y][x]==WHITECELL && !g[y][x] )
		{
			tmpxn = xn[y][x];
			off = xset[y][x];
			band = 511 >> (9-off);
			for(new_xmm=i=0;i<=9-off;i++)
			{
				b = band << i;
				if( bit_count(tmpxn | b) == off ) new_xmm |= b;
			}

			tmpyn = yn[y][x];
			off = yset[y][x];
			band = 511 >> (9-off);
			for(new_ymm=i=0;i<=9-off;i++)
			{
				b = band << i;
				if( bit_count(tmpyn | b) == off ) new_ymm |= b;
			}

			a = (new_xmm & new_ymm);
			if( a & rset[y] ) a -= (a & rset[y]);
			if( a & cset[x] ) a -= (a & cset[x]);
			if( a & tran[y][x] ) a -= (a & tran[y][x]);
			mask[y][x] = a;
//strat_add("here: " + g[y][x] + ' ' + mask2str(new_xmm) + "-" + mask2str(new_ymm) + " at " + cordit(y,x) + "<br>");

		}

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
			if( orig[y][x]!=mask[y][x] )
				lable_square( y,x,0 );


}
function min_max_column( which )
{
	var a=[0,0,0,0,0,0,0,0,0];
	var bb,cc,n,c,i,j,k;
	var d =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
	var c,m,suma;

	for(x=0;x<9;x++)
		for(y=0;y<9;y++)
			if( !d[y][x] && !jc[y][x] )
			{
				c = m = suma = 0;
				for(y2=y;y2<9 && !jc[y2][x];y2++,m++)
				{
					a[m] = (g[y2][x])? (1 << (g[y2][x]-1)) : mask[y2][x];
					c |= a[m];
					d[y2][x] = 1;
				}
				if( m == 1 || bit_count(c)==m ) continue;

				switch( which ) {
				case 1 :
					lowest = 99;
					highest = 0;
					for(k=i=0;i<m;i++)
						if( (j=g[y+i][x]) )
						{
							if( j < lowest ) lowest = j;
							if( j > highest) highest = j;
							k++;
						}
					if( k && k<m )
					{
				//		strat_add(cordit(y,x) + ' K=' + k + ' m=' + m + '<br>');
				//		strat_add(lowest + ' -- ' + highest + '<br>');

						r = highest - lowest + 1;
						if( r < m ) { lowest -= m-r; highest += m-r; }
						if( lowest < 1 ) lowest = 1;
						if( highest > 9 ) highest = 9;

				//		strat_add(lowest + ' -- ' + highest + '<br>');
						lowest = (1 << (lowest-1));
						highest = (1 << (highest-1));
						for(i=0;i<m;i++)
							if( mask[y+i][x] )
								for(j=1;MASK_LIMIT(j);j<<=1)
									if( (mask[y+i][x] & j) && ((j < lowest) || (j>highest)) )
									{
										lable_square( y+i,x,j );
										strat_add("MIN/MAX: " + mask2str(j) + " at " + cordit(y+i,x) + " can be removed (column)<br>");
									}
					}
					break;
				case 2 :
					suma = range(a[0],m);
					for(i=1;i<m;i++) suma &= range(a[i],m);
					for(i=0;i<m;i++)
						if( mask[y+i][x] )
							for(j=1;MASK_LIMIT(j);j<<=1)
								if( (mask[y+i][x] & j) && !(suma & j) )
								{
									lable_square( y+i,x,j );
									strat_add("MIN/MAX: " + mask2str(j) + " at " + cordit(y+i,x) + " can be removed (column)<br>");
								}

					for(i=1;MASK_LIMIT(i);)
					{
						for(k=0,j=i;MASK_LIMIT(j) && (c & j);j<<=1) k++;
						if( k && k < m ) for(k=0,j=i;MASK_LIMIT(j) && (c & j);j<<=1) c-=j;
						for(j=0;j<k+1;j++) i<<=1;
					}
					for(i=0;i<m;i++)
						if( mask[y+i][x] )
							for(j=1;MASK_LIMIT(j);j<<=1)
								if( (mask[y+i][x] & j) && !(c & j) )
								{
									lable_square( y+i,x,j );
									strat_add("MIN/MAX: " + mask2str(j) + " at " + cordit(y+i,x) + " can be removed (column)<br>");
								}
				}
			}

}
function min_max_row( which )
{
	var a=[0,0,0,0,0,0,0,0,0];
	var bb,cc,n,c,i,j,k,r;
	var d =[[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0]];
	var c,m,suma;

	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
			if( !d[y][x] && !jc[y][x] )
			{
				c = m = suma = 0;
				for(x2=x;x2<9 && !jc[y][x2];x2++,m++)
				{
					a[m] = (g[y][x2])? (1 << (g[y][x2]-1)) : mask[y][x2];
					c |= a[m];
					d[y][x2] = 1;
				}

				switch( which ) {
				case 1 :
					lowest = 99;
					highest = 0;
					for(k=i=0;i<m;i++)
						if( (j=g[y][x+i]) )
						{
							if( j < lowest ) lowest = j;
							if( j > highest) highest = j;
							k++;
						}
					if( k && k<m )
					{
				//		strat_add(cordit(y,x) + ' K=' + k + ' m=' + m + '<br>');
				//		strat_add(lowest + ' -- ' + highest + '<br>');

						r = highest - lowest + 1;
						if( r < m ) { lowest -= m-r; highest += m-r; }
						if( lowest < 1 ) lowest = 1;
						if( highest > 9 ) highest = 9;

				//		strat_add(lowest + ' -- ' + highest + '<br>');
						lowest = (1 << (lowest-1));
						highest = (1 << (highest-1));
						for(i=0;i<m;i++)
							if( mask[y][x+i] )
								for(j=1;MASK_LIMIT(j);j<<=1)
									if( (mask[y][x+i] & j) && ((j < lowest) || (j>highest)) )
									{
										lable_square( y,x+i,j );
										strat_add("MIN/MAX: " + mask2str(j) + " at " + cordit(y,x+i) + " can be removed (row)<br>");
									}
					}
					break;
				case 2 :
					if( m == 1 || bit_count(c)==m ) break;

					suma = range(a[0],m);
					for(i=1;i<m;i++) suma &= range(a[i],m);
					for(i=0;i<m;i++)
						if( mask[y][x+1] )
							for(j=1;MASK_LIMIT(j);j<<=1)
								if( (mask[y][x+i] & j) && !(suma & j) )
								{
									lable_square( y,x+i,j );   // .. we don't need it in the bit array
									strat_add("MIN/MAX: " + mask2str(j) + " at " + cordit(y,x+i) + " can be removed (row)<br>");
								}
					for(i=1;MASK_LIMIT(i);)
					{
						for(k=0,j=i;MASK_LIMIT(j) && (c & j);j<<=1) k++;
						if( k && k < m ) for(k=0,j=i;MASK_LIMIT(j) && (c & j);j<<=1) c-=j;
						for(j=0;j<k+1;j++) i<<=1;
					}
					for(i=0;i<m;i++)
						if( mask[y][x+i] )
							for(j=1;MASK_LIMIT(j);j<<=1)
								if( (mask[y][x+i] & j) && !(c & j) )
								{
									lable_square( y,x+i,j );
									strat_add("MIN/MAX: " + mask2str(j) + " at " + cordit(y,x+i) + " can be removed (row)<br>");
								}

				}

			}

}
/*----------------------------------------------------------------------*/
/* Function to check for conflicts with the rules						*/
/*----------------------------------------------------------------------*/
function sanity_check()
{
	var bb,cc,n,i,j,c,x,y,zz,yy,failed=0;

	for( x in g )
		for( y in g[x] )	// for every square on the board...
			if( g[x][y]==0 && mask[x][y]==0 )	// if it is an known square...
			{
				set_square(y,x,g[x][y],3,false);	// hightlight conflicting squares
				return true;
			}

	for( x in g )
		for( y in g[x] )	// for every square on the board...
			if( g[x][y] && !jc[x][y] )	// if it is an known square...
			{
				for( i=0;i<9;i++ ) // check values in row
				{
					if( i != y && g[x][i] == g[x][y] )
					{
						set_square(i,x,g[x][i],3,false);	// hightlight conflicting squares
						set_square(y,x,g[x][y],3,false);	// hightlight conflicting squares
						failed+=2;
					}
					if( i != x && g[i][y] == g[x][y] )
					{
						set_square(y,i,g[i][y],3,false);	// hightlight conflicting squares
						set_square(y,x,g[x][y],3,false);	// hightlight conflicting squares
						failed+=2;
					}
				}
			}


	return failed;
}
/* Function to reset the board to its normal blue background */
function blue_board()
{
	var x,y,done=0;
	for(y=0;y<9;y++)		// Redraw the board to clear any user highlighting
		for(x=0;x<9;x++)
		{
			if( some_changes==false ) t=document.getElementById("a"+y+x);
		//	if( some_changes==false ) t.style.backgroundColor='#ddeeff';
			if( jc[y][x]==WHITECELL && g[y][x]>0 ) done++;
		}
	return done;
}
function wcells_count()
{
	var x,y,wcells=0;
	for(y=0;y<9;y++)		// Redraw the board to clear any user highlighting
		for(x=0;x<9;x++)
		{
			if( some_changes==false ) t=document.getElementById("a"+y+x);
		//	if( some_changes==false ) t.style.backgroundColor='#ddeeff';
			if( jc[y][x]==WHITECELL ) wcells++;
		}
	return wcells;
}
function post_to_form() {
	var x,y,s='',jcs='';
	for(y=0;y<9;y++)		// Redraw the board to clear any user highlighting
		for(x=0;x<9;x++)
		{
			if( g[y][x] )
				 s = s + ',' + (1 << (g[y][x]-1));
			else if( jc[y][x]==WHITECELL )
				s = s + ',' + mask[y][x];
			else
				s = s + ',0'
			jcs = jcs + jc[y][x]
		}
	var frm = document.forms.servsolv;
	frm.elements['coordmode'].value = coordmode;
	frm.elements['colourmap'].value = jcs;
	frm.elements['board'].value = s.substr(1,s.length-1);
	frm.submit();

}
function take_step()
{
	var i,j,done=0,t,found=0,x,y;

	done=blue_board();

	if( done == 0 )
	{
		alert("Put some numbers in the small board first.");
	}
	else if( done == wcells_count() )
	{
		if( sanity_check()>0 )
			 alert("Opps. Not a valid Sudoku solution");
		else alert("Thats it! All done");
	}
	else
	{
		if( stage == 0 ) some_changes=false;

		if( stage!=0 && !some_changes )
		{
			for( x in g )
				for( y in g[x] ) last[x][y]=mask[x][y];
			prevlaststage=stage;
			laststage=stage;
		}
		if( some_changes ) stage=0;
		else
		{
			if( stage==MAX_STRAT ) stage=1
			if( stage<MAX_STRAT ) stage++;
		}

		if( stage == 0 )
		{
			found=check_for_single();
			document.getElementById("R0").innerHTML=(found)? '<font color=#00ff00><b>' + found + '</b></font>' : '<font color=#ff0000><b>0</b></font>';
			some_changes=false;
		}
		else
		{
			if( !document.ifrm )
				 doc = document.getElementById("ifrm").contentDocument;
			else doc = document.ifrm.document;
			doc.body.innerHTML='';
			doc.body.style.backgroundColor='#ddeeff';
			doc.body.style.color='#000000';

			if( stage == 1 )
				for(i=1;i<MAX_STRAT+1;i++)
					document.getElementById("R" + i).innerHTML='&nbsp;';

			if( sanity_check() )
				alert("Oops - you've got an error on the board");

// yyy

			if( stage == 1  ) show_candidates(); //show_candidates();
			if( stage == 2  ) reset_candidates(); //show_candidates();
			if( stage == 3  ) post_to_form();


			if( stage == 1 )
				for( x in g )
					for( y in g[x] ) if( mask[y][x] && show[y][x] ) { show[y][x]=0; lable_square(y,x,0); }
			if( stage < 3  )
				document.getElementById("R" + stage).innerHTML=(some_changes)? '<font color=#00ff00><b>Yes</b></font>' : '<font color=#ff0000><b>No</b></font>';
			else
				document.getElementById("R" + stage).innerHTML=(some_changes)? '<font color=#00ff00><b>Yes</b></font>' : '<font color=#ffff00><b>Wait</b></font>';

			for( x in g )
				for( y in g[x] ) orig[x][y]=mask[x][y];
		}
		if( sanity_check() )
			alert("Oops - you've got an error on the board");

		t=document.getElementById("TestT");
		for(i=0;i<MAX_STRAT+1;i++)
			t.rows[i*1].cells[1].style.backgroundColor=(stage==i) ? "#777700" : ((((i*1)%2)==0)?"#333333":"black");
		document.getElementById("backstep").className='SButton';
		if( stage==MAX_STRAT && some_changes == false )
			alert("No more known logical steps to take...");
	}
}
function back_step()
{
	var i,j,s;
	if( document.getElementById("backstep").className == 'GButton' ) return;
	for( j in g )
		for( i in g[j] )
		{
			if( last[j][i]>0 )
			{
				show[j][i]=g[j][i]=0;
				orig[j][i]=mask[j][i]=last[j][i];
				lable_square( j,i,0 );
				s="D" + j.toString()+i.toString();
				document.forms.DataEntry.elements[s].value='';
			}
		}
	some_changes=false;
	stage=(stage==0)?prevlaststage:laststage;
	t=document.getElementById("TestT");
	for(i=0;i<MAX_STRAT;i++)
		t.rows[i*1].cells[1].style.backgroundColor=(stage==i) ? "#777700" : ((((i*1)%2)==0)?"#333333":"black");
	for(i=stage;i<MAX_STRAT+1;i++)
		document.getElementById("R" + i).innerHTML='';

	document.getElementById("backstep").className='GButton';
	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
	blue_board();
}
/*------------------------------------------------------------------------*/
/* Function to colour the board according to what the user has clicked on */
/*------------------------------------------------------------------------*/
var inside_cell=false;
function convert_str2mask( astr )
{
	var c,n=0;
	for(var i=0;i<astr.length;i++)
	{
		c=parseInt(astr.charAt(i));
		if( IsNumeric(c) ) n |= (1 << (c-1));
	}
	return n;
}
function Sudoku1( afield,y,x )
{
	var i,j,cell,t;
	var fval=convert_str2mask(afield.value);

	if( fval == 0 )
	{
		g[y][x]=0;
		mask[y][x]=511;
		lable_square( y,x,0 );
	}
	else
	{
		if( bit_count(fval) == 1 )
		{
			g[y][x]=bit2int(fval)+1;
			mask[y][x]=0;
			set_square( x,y,g[y][x],2,false );
		}
		else
		{
			g[y][x]=0;
			mask[y][x]=fval;
			lable_square( y,x,0 );
		}
	}
	cell=document.getElementById("a"+y+x);
	cell.onclick=color_same;
	stage=0;
	t=document.getElementById("TestT");
	for(i=0;i<MAX_STRAT;i++)
		t.rows[i*1].cells[1].style.backgroundColor=(stage==i) ? "#777700" : ((((i*1)%2)==0)?"#333333":"black");
}
function color_same(e)
{
	var targ,x,y,i,t;
	var inputbox,ival='';
	if (!e) var e=window.event;
	if (e.target) targ=e.target;
	else if (e.srcElement) targ=e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ=targ.parentNode;

	x=targ.id.charAt(2);
	y=targ.id.charAt(1);


	targ.onclick=null;

	if( g[y][x] )	// If user clicked on an unknown square..
		ival=g[y][x];
	else
		for(i=0;i<9;i++) if( mask[y][x] & (1 << i) )
			ival=ival + (i*1+1)

	targ.innerHTML="<input type=\"text\" value=\"" + ival + "\" size=9 class=\"iput2\" maxlength=9 id=\"iput\" onblur=\"javascript:Sudoku1(this," + y + "," + x + ");\">"

	document.getElementById("iput").focus();
}
function assign_clicks()
{
	var t,x,y;
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			t=document.getElementById("a"+y+x);
			t.onclick=color_same;
			if (t.captureEvents) t.captureEvents(Event.CLICK);
		}
}
/* Function to put a number on the board from the data entry form 		 */
function add_data(t)
{
	var x,y;
	blue_board();
	x=t.id.charAt(1);	// Coordinate found in the input field name
	y=t.id.charAt(2);
	if( IsNumeric(t.value) )	// If the value is numeric
	{
		if( orig[x][y] & (1 << (t.value-1)) )	// ..Check if its a possible number for that square
		{
			g[x][y]=t.value;				// .. it is, so put it on the board
			mask[x][y]=0;
			set_square(y,x,g[x][y],2,false);
		}
		else t.value=( g[x][y] && !orig[x][y] ) ? g[x][y] : '';
	}
	else t.value='';
	if( t.value == '' )
	{
		if( orig[x][y]==0 ) orig[x][y]=511;
		mask[x][y]=orig[x][y];
		g[x][y]=0;
		lable_square(x,y,0)
	}
	stage=0;
	sanity_check();
}
function email_board()
{
	var x,y,done=0,SGW;
	var board='bd=';
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			if( g[y][x]>0 ) done++;
			if( g[y][x]>0 ) board=board + ',' + (1 << (g[y][x]-1));
			else board=board + ',' + mask[y][x];
		}
	if( !done )
		alert("This board is empty!");
	else
	{
		SGW=window.open('Str8tsEmail.htm?' + board,'_blank','resizable=no,scrollbars=no,left=300,top=200,screenX=200,screenY=200,width=750,height=420');
    	if (!SGW.opener) SGW.opener=self;
	}
}
function print_board()
{
	var x,y,done=0,SGW;
	var board='bd=';
	for(y=0;y<9;y++) for(x=0;x<9;x++)
		board=board + g[y][x];
	for(y=0;y<9;y++) for(x=0;x<9;x++)
		board=board + jc[y][x];

	SGW=window.open('Str8tsPrintable.htm?' + board,'_blank','resizable=yes,toolbar=1,scrollbars=yes,left=100,top=10,screenX=100,screenY=10,width=670,height=680');
	if (!SGW.opener) SGW.opener=self;
}
function grn_blue_color( s, highlight, m )
{
	var i,x,y,n,f;
	for(i=0;i<s.length;i+=3)
	{
		y = s.charAt(i)-m;
		x = s.charAt(i+1)-m;
		n = s.charAt(i+2)-m;
		f = document.getElementById("w"+y+x+n);
		if(f) f.className = highlight;
	}
}
function paint_yes_no( endstage )
{
	var i;
	for(i=1;i<MAX_STRAT;i++)
	{
		if( i == endstage ) break;
		document.getElementById("R" + i).innerHTML='<font color=#ff0000><b>No</b></font>';
	}
	if(endstage!=0)
	{
		var d = document.getElementById("R" + endstage);
		if( d )
			d.innerHTML='<font color=#00ff00><b>Yes</b></font>';
	}
}
function fired_event()
{
	var s,c,y,x,n,t,stratname;
	var doc,d,d2;

	if( !document.ifrm )
		 doc = document.getElementById("ifrm").contentDocument;
	else doc = document.ifrm.document;
	d = doc.getElementById("kbin")
	if( !d ) return;
	s = d.value;
	stage = doc.getElementById("nstage").value;
	t=document.getElementById("TestT");

	if( stage > 0 )
	{
		for(i=0;i<s.length;i+=3)
		{
			c = s.charAt(i);
			if( c == '{' ) break;
			y = s.charAt(i)-1;
			x = s.charAt(i+1)-1;
			n = s.charAt(i+2)-1;

			mask[y][x] -= (1 << n);
			show[y][x] += (1 << n);
			tran[y][x] += (1 << n);

		//	lable_square(y,x,(1 << n));
			some_changes = true;
		}
		if( s.length ) grn_blue_color(s,"fsh",1);

		for(y=0;y<9;y++)
			for(x=0;x<9;x++)
			{
				switch( s.charAt(y*9+x+i+1) ){
				case '1' : document.getElementById("a"+y+x).style.backgroundColor='#ffff55'; break;
				case '2' : document.getElementById("a"+y+x).style.backgroundColor='#eeaa55'; break;
				case '3' : document.getElementById("a"+y+x).style.backgroundColor='#55ff55'; break;
				case '4' : document.getElementById("a"+y+x).style.backgroundColor='#55ffcc'; break;
				}
			}
//		alert(stratname + ' ' + stage);
		for(i=0;i<MAX_STRAT+1;i++)
			t.rows[i*1].cells[1].style.backgroundColor=(stage*1==i*1) ? "#777700" : ((((i*1)%2)==0)?"#333333":"black");
		paint_yes_no( stage );

		some_changes = true;
	}
	else
	{
		for(i=0;i<MAX_STRAT+1;i++)
			t.rows[i*1].cells[1].style.backgroundColor=((((i*1)%2)==0)?"#333333":"black");
	}

	document.getElementById("takestep").onclick=take_step;
	document.getElementById("takestep").className = 'SButton';
}
