// =============================================================
// Daily Hitori from MM Multimedia
//
// Copyright MM Multimedia, Crosswords Ltd, Scanraid Ltd 2006
//
// This script is for distribution to any web site participating
// in the MM Multimedia Daily Hitori Subscription
//
// Version 1.01 01-Feb-2006
// =============================================================
var stage = 0, laststage = 0;
var ck=0;
var print_version = false;
var showhints = true;
var steps = 0;
var some_changes = false;
var firsttime = true;


var XSIZE = 8;
var YSIZE = 8;
var MAX_YSIZE = 25;
var MAX_XSIZE = 25;
var used_up=0;
var NUM_STRATS = 6;


// Default board to copy actual boards into. Not found a shorter way to declare and initialize
var g; 		// Holds the cell value if a number
var bw;		// Black or White - holds the fact that a cell is a black cell or a number cell
var reach;
var vis;
var forced;
var ban;
var sur;
var mask,num,xoff,yoff;
var xclue,yclue,xclue_m,yclue_m,used,xpos,ypos;

// Puzzle Japan
var g1 = "4185316881563347114465725843271773684321612158383612348584721655";
var g2 = "4337571827371688738352461652763322816574651724773226475128746361"; // Easy
var g3 = "3677842533371614218687363764518268346521134461541521734682564316"; // Easy
var g4 = "5343621378621634673468612225317743572868156864262613448733748512"; // Easy
var g5 = "8166642834278156762547834284731583725864652187485737166248635272"; // Easy
var g6 = "4946198A243197444895459238746A6A19475332298354AA1658444321754761A83859964A75222372686945A88525761947"; // Medium
var g7 = "21634A7189196244487A3466572188A68536142984A423A967283361A342476A92A52162719843993313876A447548A93216"; // Medium
var g8 = "1A92461354444534229876A38542735A1326A2494863137A2819784A53318261A98567A736661915158427641A23995864A6";
var g9 = "19517853274A7879213589982633A927A9A38614185643571299275A1341751569A4931381856A29527417936AA646328574";
var g10 = "4886942A4586A3A152943884217A19A433829516134764892549881327A2712598A63498117A426342914168546562A93178";

var total_paths=0;
var wallx, wally, wallcount, openings;
var holex, holey;


function bit_count( b )
{
    var n = 0;
	if ( !b ) return 0;
    do { ++n; } while ( b &= (b-1) );
    return  n;
}

function vs_valid_number(item)
{
	var okay = true;
//	item.value = item.value.Trim();
	var num = "0123456789";
	for (var intLoop = 0; intLoop < item.value.length; intLoop++) {
	    if (num.indexOf(item.value.charAt(intLoop)) == -1) okay = false;
	}
	if( !okay ) item.value = '';
	return okay;
}
function set_print_square( x, y, val )
{
	var t, s, nt;
	var oRow;

	nt = ( y < 3 ) ? "A" : (( y < 6 ) ? "B" : "C");
	nt = nt + (( x < 3 ) ? "1" : (( x < 6 ) ? "2" : "3"));

	t = document.getElementById(nt);
	oRow = t.rows[y % 3];
	if( val > 0 )
		 oRow.cells[x % 3].innerHTML = val;
	else oRow.cells[x % 3].innerHTML = '&nbsp;';
	oRow.cells[x % 3].className = ( clues[y][x]==true ) ? 'InnerTClues':'InnerTDone';
}

function set_square( y, x )
{
	var Nuri;
	var oRow;

	Nuri = document.getElementById("Nuri");
	oRow = Nuri.rows[y];

	if( XSIZE == 8 )
		switch( bw[y][x] ) {
		case 0: oRow.cells[x].className = 'classWhite8x8'; break;
		case 1: oRow.cells[x].className = 'classBlack8x8'; break;
		case 2: oRow.cells[x].className = 'classCircle8x8'; break;
		}
	else
		switch( bw[y][x] ) {
		case 0: oRow.cells[x].className = 'classWhite10x10'; break;
		case 1: oRow.cells[x].className = 'classBlack10x10'; break;
		case 2: oRow.cells[x].className = 'classCircle10x10'; break;
		}
	oRow.cells[x].innerHTML = g[y][x];
}
function set_arrays()
{
	var y;
	g = new Array(MAX_YSIZE);
	bw = new Array(MAX_YSIZE);
	reach = new Array(MAX_YSIZE);
	vis = new Array(MAX_YSIZE);
	forced = new Array(MAX_YSIZE);
	ban = new Array(MAX_YSIZE);
	sur = new Array(MAX_YSIZE);
	for(y=0;y<MAX_YSIZE;y++)
	{
		g[y] = new Array(MAX_XSIZE);
		bw[y] = new Array(MAX_XSIZE);
		reach[y] = new Array(MAX_XSIZE);
		vis[y] = new Array(MAX_XSIZE);
		forced[y] = new Array(MAX_XSIZE);
		ban[y] = new Array(MAX_XSIZE);
		sur[y] = new Array(MAX_XSIZE);
	}
}
function initialise_board()
{
	var x,y,s;

	stage = 0;


	s = "<table border=0 cellpadding=0 cellspacing=0 name=Nuri id=Nuri>";

	for(y=0;y<YSIZE;y++)
	{
		s = s + "<tr>";
		for(x=0;x<XSIZE;x++)
		{
			s = s + "<td class=InnerT onclick=\"javascript:CL(" + x + "," + y + ");\">&nbsp;</td>";
			g[y][x] = 0;
			bw[y][x] = 0;
			reach[y][x] = 0;
			vis[y][x] = 0;
			forced[y][x] = 0;
			ban[y][x] = 0;
			sur[y][x] = 0;
		}
		s = s + "</tr>";
	}
	s = s + "</table>";
	document.getElementById("OuterT").innerHTML = s;
//	for(y=0;y<YSIZE;y++)
//		for(x=0;x<XSIZE;x++)
//			set_square( y, x );

//	ban_cell2();
}
function load_board(print_version)
{
	var i, j, c;
	var bd = location.search;
	var mySudoku;


	if(window.ActiveXObject)
	{
		var xmlDoc = new ActiveXObject("Msxml2.XMLHTTP");
		xmlDoc.open("GET","http://www.sudokulist.com/player/fetchSudoku.asp?level=m&accid=4295&day=today", false);
		xmlDoc.send();
		mySudoku = xmlDoc.responseXML.xml;
		mySudoku = mySudoku.substring(24,mySudoku.length-2);
	}
	else if(document.implementation && document.implementation.createDocument)
	{
		xmlDoc = new XMLHttpRequest();
		xmlDoc.open("GET", "http://www.sudokulist.com/player/fetchSudokuTXT.asp?level=m&accid=4295&day=today", false);
		xmlDoc.send(null);
		var mySudoku = xmlDoc.responseText;
	}

	if( !print_version )
		switch( mySudoku.charAt(0) ) {
		case 'k' :
			for(i=2;i<=5;i++)
				document.getElementById("devil" + i).src = 'devilfade.gif'; break;
		case 'g' :
			for(i=3;i<=5;i++)
				document.getElementById("devil" + i).src = 'devilfade.gif'; break;
		case 'm' :
			for(i=4;i<=5;i++)
				document.getElementById("devil" + i).src = 'devilfade.gif'; break;
		case 't' :
			for(i=5;i<=5;i++)
				document.getElementById("devil" + i).src = 'devilfade.gif'; break;
		case 'd' :
		}

	stage = 0;

	var d = new Date()

	for(j=0;j<9;j++)
		for(i=0;i<9;i++)
		{
			var c = j*9+i+1;
			if( mySudoku.charAt(c)=='.' )
				g[j][i] = 0;
			else
				g[j][i] = mySudoku.charAt(c)*1;
			sol[j][i] = mySudoku.charAt(c+81)*1;
			if( print_version )
				set_print_square(i,j,g[j][i]);
			else
			{
				if( g[j][i] > 0 )
				{
					clues[j][i] = 1;
					set_square(i,j,g[j][i]);
					document.getElementById('A' + i + j).readOnly = true;
				}
				else
					set_square(i,j,' ');
			}
		}

	if( !print_version ) SWStart();
}
function load_this_board()
{
	var x,y,n,c,s,i;
	var bd = location.search;
	var p = '';

	if( bd.length != XSIZE*YSIZE+4 && bd.length != 0 )
	{
		alert("You need to put a string of numbers and dots that is the length of the current X * Y, this string is " + bd.length + ' long');
		return;
	}
	if( bd.length!=XSIZE*YSIZE+4 )
	{
		switch( document.forms.DataEntry.elements["Example"].selectedIndex ) {
		case 0 : XSIZE=8; YSIZE=8; break;
		case 1 : XSIZE=8; YSIZE=8; break;
		case 2 : XSIZE=8; YSIZE=8; break;
		case 3 : XSIZE=8; YSIZE=8; break;
		case 4 : XSIZE=8; YSIZE=8; break;
		case 5 : XSIZE=10; YSIZE=10; break;
		case 6 : XSIZE=10; YSIZE=10; break;
		case 7 : XSIZE=10; YSIZE=10; break;
		case 8 : XSIZE=10; YSIZE=10; break;
		case 9 : XSIZE=10; YSIZE=10; break;
		}
		switch( document.forms.DataEntry.elements["Example"].selectedIndex ) {
		case 0 : s =  g1; break;
		case 1 : s =  g2;break;
		case 2 : s =  g3;break;
		case 3 : s =  g4;break;
		case 4 : s =  g5;break;
		case 5 : s =  g6;break;
		case 6 : s =  g7;break;
		case 7 : s =  g8;break;
		case 8 : s =  g9;break;
		case 9 : s = g10;break;
		}
	}
	initialise_board();

	for(y=0;y<YSIZE;y++)
		for(x=0;x<XSIZE;x++)
		{
			if( bd.length==XSIZE*YSIZE+4 )
			{
				n = bd.charAt((y*YSIZE)+x+4);
			}
			else
				n = s.charAt( (y*XSIZE)+x ) ;
			//	n = s.charAt( (y*2*XSIZE)+x*2) + s.charAt( (y*2*XSIZE)+x*2+1);
			if( n.charAt(0) == 'A' )
	 			c = 10;
			else c = n;
	//		if( y==0 ) alert(n);
			g[y][x] = c;
			set_square( y, x );
		}
	firsttime = true;
	for(i=1;i<=NUM_STRATS;i++)
		document.getElementById("R" + i).innerHTML = "&nbsp;";


//	check_board();
//	document.getElementById("board").value = p;
	if( !print_version ) SWStart();
}

function print_board()
{
	var x,y,done=0;
	var board = 'bd=';
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
			board = board + g[y][x];

	SGW = window.open('SudokuPrintable.htm?' + board,'_blank','resizable=yes,toolbar=1,scrollbars=yes,left=100,top=10,screenX=100,screenY=10,width=660,height=660');
	if (!SGW.opener) SGW.opener = self;
}
function print_solution()
{
	var x,y,done=0;
	var board = 'bd=';
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
			board = board + g[y][x];

	SGW = window.open('MMSolution.htm','_blank','resizable=yes,toolbar=1,scrollbars=yes,left=100,top=10,screenX=100,screenY=10,width=660,height=660');
	if (!SGW.opener) SGW.opener = self;
}
function email_board()
{
	var x,y,done=0;
	var board = 'bd=';
	for(y=0;y<9;y++)
		for(x=0;x<9;x++)
		{
			if( g[y][x]>0 ) done++;
			board = board + g[y][x];
		}
	if( !done )
		alert("This board is empty!");
	else
	{
		SGW = window.open('SudokuEmail.htm?' + board,'_blank','resizable=no,scrollbars=no,left=300,top=200,screenX=300,screenY=200,width=500,height=250');
    	if (!SGW.opener) SGW.opener = self;
	}
}
function sum_nos_around( y, x )
{
	var c=0;
	if( x+1 < XSIZE && g[y][x+1] > 0 ) c++;
	if( y+1 < YSIZE && g[y+1][x] > 0 ) c++;
	if( x-1 >= 0 && g[y][x-1] > 0 ) c++;
	if( y-1 >= 0 && g[y-1][x] > 0 ) c++;
//	if( x==8 && y==5 ) alert(c);
	return c;
}
function surrounded( y, x )
{
	sur[y][x]=1;
	set_square( y, x );
	return true;
}
function make_circle( y, x )
{
	if( bw[y][x]!=2 )
	{
		bw[y][x]=2;
		set_square( y, x );
		some_changes = true;
	}
	return true;
}
function make_wall( y, x )
{
	if( bw[y][x]!=2 )
	{
		bw[y][x]=1;
		set_square( y, x );
	}
	if( y>0 ) make_circle( y-1, x );
	if( y<YSIZE-1 ) make_circle( y+1, x );
	if( x>0 ) make_circle( y, x-1 );
	if( x<YSIZE-1 ) make_circle( y, x+1 );
	some_changes = true;
	return true;
}
function neightbour_vis( y, x, which )
{
	switch( which ) {
	case 0 : if( x>0  	 && bw[y][x-1]==0 && g[y][x-1]>0 && vis[y][x-1]==0 ) return true; break;
	case 1 : if( y>0 	 && bw[y-1][x]==0 && g[y-1][x]>0 && vis[y-1][x]==0 ) return true; break;
	case 2 : if( x<XSIZE && bw[y][x+1]==0 && g[y][x+1]>0 && vis[y][x+1]==0 ) return true; break;
	case 3 : if( y<YSIZE && bw[y+1][x]==0 && g[y+1][x]>0 && vis[y+1][x]==0 ) return true; break;
	}
	return false;
}
function neightbour_ban( y, x, which )
{
	switch( which ) {
	case 0 : if( x>0  	 && bw[y][x-1]==0 && g[y][x-1]>0 && ban[y][x-1]==0 ) return true; break;
	case 1 : if( y>0 	 && bw[y-1][x]==0 && g[y-1][x]>0 && ban[y-1][x]==0 ) return true; break;
	case 2 : if( x<XSIZE && bw[y][x+1]==0 && g[y][x+1]>0 && ban[y][x+1]==0 ) return true; break;
	case 3 : if( y<YSIZE && bw[y+1][x]==0 && g[y+1][x]>0 && ban[y+1][x]==0 ) return true; break;
	}
	return false;
}
function neightbour_free( y, x, which )
{
	switch( which ) {
	case 0 : if( x>0  	 && bw[y][x-1]==0 && g[y][x-1]==0 ) return true; break;
	case 1 : if( y>0 	 && bw[y-1][x]==0 && g[y-1][x]==0 ) return true; break;
	case 2 : if( x<XSIZE && bw[y][x+1]==0 && g[y][x+1]==0 ) return true; break;
	case 3 : if( y<YSIZE && bw[y+1][x]==0 && g[y+1][x]==0 ) return true; break;
	}
	return false;
}
function neightbour_free_vis( y, x, which )
{
	switch( which ) {
	case 0 : if( x>0  	 && bw[y][x-1]==0 && g[y][x-1]==0 && vis[y][x-1]==0 ) return true; break;
	case 1 : if( y>0 	 && bw[y-1][x]==0 && g[y-1][x]==0 && vis[y-1][x]==0 ) return true; break;
	case 2 : if( x<XSIZE && bw[y][x+1]==0 && g[y][x+1]==0 && vis[y][x+1]==0 ) return true; break;
	case 3 : if( y<YSIZE && bw[y+1][x]==0 && g[y+1][x]==0 && vis[y+1][x]==0 ) return true; break;
	}
	return false;
}
function lowest_number( y, x )
{
	var lowest, l;
	lowest = g[y][x];
	vis[y][x] = 1;
	if( neightbour_vis(y,x,0) ) { l = lowest_number( y, x-1 ); if( l < lowest ) lowest = l; }
	if( neightbour_vis(y,x,1) ) { l = lowest_number( y-1, x ); if( l < lowest ) lowest = l; }
	if( neightbour_vis(y,x,2) ) { l = lowest_number( y, x+1 ); if( l < lowest ) lowest = l; }
	if( neightbour_vis(y,x,3) ) { l = lowest_number( y+1, x ); if( l < lowest ) lowest = l; }
	return lowest
}
function wall_the_group( y, x )
{
	ban[y][x] = 1;
	sur[y][x] = 1;
//	set_square( y, x );

	if( neightbour_free(y,x,0) ) make_wall( y, x-1 );
	if( neightbour_free(y,x,1) ) make_wall( y-1, x );
	if( neightbour_free(y,x,2) ) make_wall( y, x+1 );
	if( neightbour_free(y,x,3) ) make_wall( y+1, x );

	if( neightbour_ban(y,x,0) ) wall_the_group( y, x-1 );
	if( neightbour_ban(y,x,1) ) wall_the_group( y-1, x );
	if( neightbour_ban(y,x,2) ) wall_the_group( y, x+1 );
	if( neightbour_ban(y,x,3) ) wall_the_group( y+1, x );
}
function num_openings( y, x )
{
	var c = 0;
	ban[y][x] = 1;

	if( neightbour_free(y,x,0) ) c++;
	if( neightbour_free(y,x,1) ) c++;
	if( neightbour_free(y,x,2) ) c++;
	if( neightbour_free(y,x,3) ) c++;

	if( neightbour_ban(y,x,0) ) c += num_openings( y, x-1 );
	if( neightbour_ban(y,x,1) ) c += num_openings( y-1, x );
	if( neightbour_ban(y,x,2) ) c += num_openings( y, x+1 );
	if( neightbour_ban(y,x,3) ) c += num_openings( y+1, x );
	return c;
}
var loopcount=0;

function reachable( x, y, distance )
{
	if( x<0 || y<0 || x>=XSIZE || y>=YSIZE ) return false;
	if( vis[x][y]>0 ) return false;
	if( g[y][x]>0 && bw[y][x]==0 && distance <= g[y][x] ) return true;// found a number
	vis[y][x] = distance;
	return false;
}

function recurse_reachable( x, y, y1, x1, y2, x2, y3, x3, y4, x4, distance )
{
	loopcount++;
	if( distance==1 && vis[x][y]>0 ) return false;

	if( reachable( x1, y1, distance ) ) return true;
	if( reachable( x2, y2, distance ) ) return true;
	if( reachable( x3, y3, distance ) ) return true;
	if( reachable( x4, y4, distance ) ) return true;

	if( vis[x1][y1]==0 && recurse_reachable( y1, x1, y1-1, x1-1, y1-1, x1+1, y1+1, x1-1, y1+1, x1+1, distance*1+1 ) ) return true;
	if( vis[x2][y2]==0 && recurse_reachable( y2, x2, y2-1, x2-1, y2-1, x2+1, y2+1, x2-1, y2+1, x2+1, distance*1+1 ) ) return true;
	if( vis[x3][y3]==0 && recurse_reachable( y3, x3, y3-1, x3-1, y3-1, x3+1, y3+1, x3-1, y3+1, x3+1, distance*1+1 ) ) return true;
	if( vis[x4][y4]==0 && recurse_reachable( y4, x4, y4-1, x4-1, y4-1, x4+1, y4+1, x4-1, y4+1, x4+1, distance*1+1 ) ) return true;

	return false;
}

function forth_corner( y, x )
{
	var c=0;
	if( y+1 < YSIZE && bw[y+1][x] == 1 ) c++;
	if( x+1 < XSIZE && bw[y][x+1] == 1 ) c++;
	if( c==2 && bw[y+1][x+1] == 1 ) c++;
	if( c==3 ) return true;

	c=0;
	if( y-1 >= 0 && bw[y-1][x] == 1 ) c++;
	if( x-1 >= 0 && bw[y][x-1] == 1 ) c++;
	if( c==2 && bw[y-1][x-1] == 1 ) c++;
	if( c==3 ) return true;

	c=0;
	if( y-1 >= 0 && bw[y-1][x] == 1 ) c++;
	if( x+1 < XSIZE && bw[y][x+1] == 1 ) c++;
	if( c==2 && bw[y-1][x+1] == 1 ) c++;
	if( c==3 ) return true;

	c=0;
	if( y+1 < YSIZE && bw[y+1][x] == 1 ) c++;
	if( x-1 >= 0 && bw[y][x-1] == 1 ) c++;
	if( c==2 && bw[y+1][x-1] == 1 ) c++;
	if( c==3 ) return true;

	return false;
}

function recurse_wall( y, x, d )
{
	var c=0;
	vis[y][x] = 1;
	wallcount++;
	reach[y][x] = d;
//	set_square( y, x );
	if( x>0 	  && (g[y][x-1]==0 && bw[y][x-1]!=1) && !forth_corner( y, x-1 ) ) { c++; wallx=x-1; wally=y;   }
	if( y>0 	  && (g[y-1][x]==0 && bw[y-1][x]!=1) && !forth_corner( y-1, x ) ) { c++; wallx=x;   wally=y-1; }
	if( x<XSIZE-1 && (g[y][x+1]==0 && bw[y][x+1]!=1) && !forth_corner( y, x+1 ) ) { c++; wallx=x+1; wally=y;   }
	if( y<YSIZE-1 && (g[y+1][x]==0 && bw[y+1][x]!=1) && !forth_corner( y+1, x ) ) { c++; wallx=x;   wally=y+1; }

	if( c==1 ) openings++;
	if( c>1 ) openings=XSIZE*YSIZE+1;
//	if( c==1 )	alert('cos of ' + y + ' ' + x + ' ' + c + ' ' + openings)

	if( x>0 	  && (bw[y][x-1]==1) && vis[y][x-1]==0 ) recurse_wall( y, x-1, d+1 );
	if( y>0 	  && (bw[y-1][x]==1) && vis[y-1][x]==0 ) recurse_wall( y-1, x, d+1 );
	if( x<XSIZE-1 && (bw[y][x+1]==1) && vis[y][x+1]==0 ) recurse_wall( y, x+1, d+1 );
	if( y<YSIZE-1 && (bw[y+1][x]==1) && vis[y+1][x]==0 ) recurse_wall( y+1, x, d+1 );
}


function recurse_contiguous_white( y, x )
{
	var c = 1;
	if( y<0 || x<0 || y>YSIZE-1 || x>XSIZE-1 )
		return 0;

	if( vis[y][x] == 1 ) return 0;
	if( bw[y][x]==1 ) return 0;
	vis[y][x] = 1;

	c += recurse_contiguous_white( y-1, x );
	c += recurse_contiguous_white( y+1, x );
	c += recurse_contiguous_white( y, x-1 );
	c += recurse_contiguous_white( y, x+1 );

	return c;
}

function contiguous_white( y, x )
{
	var must_be_white = false;
	var whites = 0;
	var c=0;

	if( y>1 && y<YSIZE-1 && x>1 && x<XSIZE-1 )
		if( bw[y-1][x] == 0 && bw[y-1][x] == 0 && bw[y][x+1] == 0 && bw[y][x-1] == 0 ) return false;

	// temporarily make this cell black
	bw[y][x] = 1;

	for(j=0;j<YSIZE;j++)
		for(i=0;i<XSIZE;i++)
			if( bw[j][i]!=1 ) whites++;

	for(j=0;j<YSIZE;j++)
		for(i=0;i<XSIZE;i++) vis[j][i] = 0;

	    c = recurse_contiguous_white( y-1, x );
	if( c == 0 )
		c = recurse_contiguous_white( y+1, x );
	if( c == 0 )
		c = recurse_contiguous_white( y, x-1 );
	if( c == 0 )
		c = recurse_contiguous_white( y, x+1 );
	if( c < whites )
		must_be_white = true;

//	alert(c + ' ' + whites);

	bw[y][x] = 0;
	return must_be_white;
}
function take_step()
{
	var x,y,z,w,i,j,c,fx,fy, n;
	var multiple = false;

	for(y=0;y<YSIZE;y++)
		for(x=0;x<XSIZE;x++)
		{
			reach[y][x] = vis[y][x] = 0;
//			set_square( y, x );
		}

	t = document.getElementById("TestT");
	for(i=0;i<NUM_STRATS;i++)
		t.rows[i].cells[0].style.backgroundColor = (stage==i) ? "#ffff00" : "";
	some_changes = false;

	switch( stage ) {
	case 0 :
		//1 - Unique in row and column";
		for(y=0;y<YSIZE;y++)
			for(x=0;x<XSIZE;x++)
			{
				multiple = false;
				for(z=0;z<XSIZE;z++)
					if( x!=z && g[y][x] == g[y][z] ) multiple = true;

				for(z=0;z<XSIZE;z++)
					if( y!=z && g[y][x] == g[z][x] ) multiple = true;

				if( multiple == false )
					make_circle( y, x );
			}
			break;

	case 1 :
		//1 - look for triples";
		for(y=0;y<YSIZE;y++)
			for(x=0;x<XSIZE-2;x++)
				if( g[y][x] == g[y][x+1] && g[y][x] == g[y][x+2] )
				{
					make_wall( y, x );
					make_wall( y, x+2 );
				}
		for(y=0;y<YSIZE-2;y++)
			for(x=0;x<XSIZE;x++)
				if( g[y][x] == g[y+1][x] && g[y][x] == g[y+2][x] )
				{
					make_wall( y, x );
					make_wall( y+2, x );
				}
		break;


	case 2 :
		//4 - Corner 4s";
		x = XSIZE-1;
		y = YSIZE-1;
		if( g[0][0]==g[1][0] && g[0][0]==g[0][1] && g[0][0]==g[1][1] ) { make_wall( 0, 0 ); make_wall( 1, 1 ); }
		if( g[0][x]==g[1][x] && g[0][x]==g[0][x-1] && g[0][x]==g[1][x-1] ) { make_wall( 0, x ); make_wall( 1, x-1 ); }
		if( g[y][0]==g[y-1][0] && g[y][0]==g[y][1] && g[y][0]==g[y-1][1] ) { make_wall( y, 0 ); make_wall( y-1, 1 ); }
		if( g[y][x]==g[y-1][x] && g[y][x]==g[y][x-1] && g[y][x]==g[y-1][x-1] ) { make_wall( y, x ); make_wall( y-1, x-1 ); }
		break;

	case 3: // Pair and Single
		for(y=0;y<YSIZE;y++)
			for(x=0;x<XSIZE;x++)
				if( bw[y][x]==0 )
				{
					for(z=0;z<XSIZE;z++)
						if( z!=x && g[y][z] == g[y][x] && (z==x+1 || z==x-1) ) // if adjacent cell is same number
						{
							for(w=0;w<XSIZE;w++)
								if( z!=w && x!=w && g[y][w] == g[y][x] && bw[y][w]==0 )
									make_wall( y, w );
						}
					for(z=0;z<YSIZE;z++)
						if( z!=y && g[z][x] == g[y][x] && (z==y+1 || z==y-1) ) // if adjacent cell is same number
						{
							for(w=0;w<YSIZE;w++)
								if( z!=w && y!=w && g[w][x] == g[y][x] && bw[w][x]==0 )
									make_wall( w, x );
						}
				}
		break;


	case 4:
		//2 - safe/unsafe";
		for(y=0;y<YSIZE;y++)
			for(x=0;x<XSIZE;x++)
				if( bw[y][x]==2 )
				{
					for(z=0;z<XSIZE;z++)
						if( z!=x && g[y][z] == g[y][x] && bw[y][z]==0 )
							make_wall( y, z );
					for(z=0;z<YSIZE;z++)
						if( z!=y && g[z][x] == g[y][x] && bw[z][x]==0 )
							make_wall( z, x );
				}
		for(y=0;y<YSIZE;y++)
			for(x=0;x<XSIZE;x++) if( bw[y][x] == 0 )
			{
				multiple = false;
				for(z=0;z<XSIZE;z++)
					if( x!=z && g[y][x] == g[y][z] && bw[y][z] != 2 ) multiple = true;

				for(z=0;z<XSIZE;z++)
					if( y!=z && g[y][x] == g[z][x] && bw[z][x] != 2 ) multiple = true;

				if( multiple == false )
					make_circle( y, x );
			}
		break;

	case 5:
		//3 - contiguous white";
		for(y=0;y<YSIZE;y++)
			for(x=0;x<XSIZE;x++)
				if( bw[y][x] == 0 && contiguous_white(y,x) )
					make_circle( y, x );
		firsttime = false;
		break;

	}

	stage++;
	if( stage == 4 && !firsttime )
		for(i=1;i<=NUM_STRATS;i++)
			document.getElementById("R" + i).innerHTML = "&nbsp;";
	document.getElementById("R" + stage).innerHTML = (some_changes)? '<font color=#00ff00><b>Yes</b></font>' : '<font color=#ff0000><b>No</b></font>';
	if( stage == NUM_STRATS ) stage = 3;

}

function CL( x, y )
{
	var x1,y1;
	var s='';

	if( bw[y][x] == 1 )
	{
		bw[y][x] = 2;
	}
	else if( bw[y][x] == 2 )
	{
		bw[y][x] = 0;
	}
	else
	{
		bw[y][x] = 1;
	}
	set_square( y, x );
}

function SWUpdateTimer()
{
	if(timerID) {
	  clearTimeout(timerID);
	  clockID  = 0;
	}

	if(!tStart)
	  tStart   = new Date();

	var hours, mins, secs;
	var   tDate = new Date();
	var   tDiff = tDate.getTime() - tStart.getTime();

	tDate.setTime(tDiff);

	hours = tDate.getHours();
	if( hours >= 18 ) hours = 0;
	mins = tDate.getMinutes();
	secs = tDate.getSeconds();
	if( mins < 10 ) mins = '0' + mins
	if( secs < 10 ) secs = '0' + secs
	document.getElementById('theTimer').value = "" + hours + ":" + mins + ":" + secs;

	timerID = setTimeout("SWUpdateTimer()", 1000);
}
function SWStart()
{
	tStart   = new Date();

	document.getElementById('theTimer').value = "0:00:00";

	timerID  = setTimeout("SWUpdateTimer()", 1000);
}
function SWStop()
{
   if(timerID) {
      clearTimeout(timerID);
      timerID  = 0;
   }

   tStart = null;
}
function SWReset()
{
	tStart = null;

	document.getElementById('theTimer').value = "0:00:00";
}
function openAWindow( pageToLoad, winName, width, height, center)
{
	xposition=0; yposition=0;
	if ((parseInt(navigator.appVersion) >= 4 ) && (center)){
		xposition = (screen.width - width) / 2;
		yposition = (screen.height - height) / 2;
	}
	args = "width=" + width + ","
	+ "height=" + height + ","
	+ "location=0,"
	+ "menubar=0,"
	+ "resizable=1,"
	+ "scrollbars=1,"
	+ "status=0,"
	+ "titlebar=0,"
	+ "toolbar=0,"
	+ "hotkeys=0,"
	+ "screenx=" + xposition + ","  //NN Only
	+ "screeny=" + yposition + ","  //NN Only
	+ "left=" + xposition + ","     //IE Only
	+ "top=" + yposition;           //IE Only
	window.open( pageToLoad,winName,args );
}
