<HTML><HEAD><TITLE>Game 2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
//
// Samuel's Tile Game.
//    Version 2.0
// Ugly, simple, but...
//       by
// samuelg@fogbound.net
//

/***************************************************************************
COPYRIGHT

Copyright (C) 1999 Samuel Goldstein


This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

The license can also be found at:
http://www.opensource.org/licenses/gpl-license.html
***************************************************************************/

// customize these variables, as needed.
/* First, you'll need to break an image into a collection of smaller rectangles
   or squares. They should be saved in a directory, and named with some base name
   convention, followed by a sequential 3-digit number, eg. ivy000.jpg
   
   If you don't want a time limit or move limit, you might want to remove the status
   fields from the HTML FORM at the bottom of this page!
*/

// Number of columns that the image has been broken up into
var cols=12;
// Number of rows that the image has been broken up into
var rows=3;

// dimensions of the pieces that the image is broken up into:
var tileHeight = 100;
var tileWidth = 50;

// base path from this HTML file to the image directory
var imagePath = './images';

// image name
var imageBaseName = 'ivy';

// image type
var imageExtension = '.jpg';

// when you click on a piece to move it, it will flicker with this image:
var pickedImage = "ivyb.jpg";

// when the Evil Undoer is getting ready to move pieces, they will flicker
// with this image
var undoerImage = "ivyc.jpg";

// Limit the number of moves?
var moveLimit = 100;
var enforceMoveLimit = true;

// Limit the time to play?
var timeLimit = 600; // in seconds!
var enforceTimeLimit = true;

// Allow the game to have the EvilUndoer?
var undoer = true;
var undoerTriggerTime = 5;  // number of idle seconds before undoer triggers
var undoerDelay = 10; // number of seconds before active undoer moves pieces
					  // (thus, total idle time before the undoer acts is the
					  // sum of these two values.)

/***************************************************************************/
// initialize all the images
var counter=0;
var selected = -1;
var moves=0;
var movetime = 0;
var time=0;
var timerSet = false;
var undoerLive = false;
var undoerSource =0;
var undoerDest = 0;
var undoerFlickerState = 0;
var flickerState = 0;
var tileCount=rows*cols;
var undoerCancelTime = undoerTriggerTime + undoerDelay;
var pics = new Array(tileCount);
var pos = new Array(tileCount);

function init()
	{
	for (n=0;n<(tileCount);n++)
		{
		pics[n] = new Image();
		pics[n].src = filespec(n);
		pos[n] = n;
		}
	picked = new Image();
	picked.src = imagePath + "/" + pickedImage;
	undoerPick = new Image();
	undoerPick.src = imagePath + "/" + undoerImage;
	}
	
function stats()
	{
	if (enforceMoveLimit)
		{
		document.stats.movesleft.value = moveLimit - moves;
		}
	if (enforceTimeLimit)
		{
		document.stats.timeleft.value = (timeLimit - time)+ "s.";
		}
	}

function shuffle()
	{
	var count1 = 0;
	var count2 = 0;
	var swap = 0;
	for (count1 = 0;count1<tileCount;count1++)
		{
		for (count2 = 0;count2<tileCount;count2++)
			{
			if ((count1 != count2)&&(Math.random() > 0.5))
				{
				swap = pos[count1];
				pos[count1] = pos[count2];
				pos[count2] = swap;
				}
			}
		}
	for (i=0;i<tileCount;i++)
		{
		eval('document.p'+i+'.src = pics['+pos[i]+'].src');
		}
	}

function buildTable()
	{
	counter = 0;
	for (i=0;i<rows;i++)
		{
		document.write("<T"+"R>\n");
		for(j=0;j<cols;j++)
			{
			document.write("<T"+"D><A HREF=\"Javascript:clickedOn("+counter+");\"><IMG SRC=\"");
			document.write(filespec(counter));
			document.write("\" NAME=\"p"+counter+"\" HEIGHT=\""+tileHeight+"\" WIDTH=\""+tileWidth+"\" BORDER=\"0\"></"+"A></T"+"D>");
			counter++;
			}
		document.write("</T"+"R>\n");
		}
	}

function startTimer()
	{
	timerSet = true;
	setTimeout('tick()',1000);
	}
	
function tick()
	{
	time++;
	movetime++;
	stats();
	if (undoer && (movetime == undoerTriggerTime))
		{
		undoerLive = true;
		activateUndoer();
		}
	if (undoer && (movetime == undoerCancelTime))
		{
		undoerLive = false;
		undoerSwap();
		}
	if (time == timeLimit)
		{
		alert("Nope. You're out of time!");
		}
	else
		{
		setTimeout('tick()',1000);
		}
	}

function activateUndoer()
	{
	if (undoerLive)
		{
		undoerSource = Math.round(Math.random() * (tileCount-1));
		undoerDest = Math.round(Math.random() * (tileCount-1));
		setTimeout('flashUndoer()',200);
		}
	}

function flashUndoer()
	{
	if (undoerLive && (undoerFlickerState == 1))
		{
		eval('document.p'+undoerSource+'.src = undoerPick.src');
		eval('document.p'+undoerDest+'.src = undoerPick.src');
		}
	else
		{
		eval('document.p'+undoerSource+'.src = pics['+pos[undoerSource]+'].src');
		eval('document.p'+undoerDest+'.src = pics['+pos[undoerDest]+'].src');
		}
	undoerFlickerState = 1-undoerFlickerState;
	if (undoerLive)
		{
		setTimeout('flashUndoer();',200);
		}
	}
	
function undoerSwap()
	{
	movetime = 0;
	swap = pos[undoerSource];
	pos[undoerSource] = pos[undoerDest];
	pos[undoerDest] = swap;
	eval('document.p'+undoerSource+'.src = pics['+pos[undoerSource]+'].src');
	eval('document.p'+undoerDest+'.src = pics['+pos[undoerDest]+'].src');
	check();
	}


function flicker(position)
	{
	if (selected != -1)
		{
		if (flickerState == 1)
			{
			eval('document.p'+position+'.src = picked.src');
			}
		else
			{
			eval('document.p'+position+'.src = pics['+pos[position]+'].src');
			}
		flickerState = 1-flickerState;
		setTimeout('flicker('+position+')',200);
		}
	}

function check()
	{
	ordered = 1;
	for (swap=0;swap<tileCount;swap++)
		{
		if (pos[swap] != swap)
			{
			ordered = 0;
			}
		}
					
	if (ordered == 1)
		{
		// They Won!
		alert("You did it!");
		}
	}


function clickedOn(theNumber)
	{
	if (!timerSet && enforceTimeLimit)
		{
		startTimer();
		}
		
	if (selected == -1)
		{
		selected = theNumber;
		eval('document.p'+theNumber+'.src = picked.src');
		flickerState = 0;
		setTimeout('flicker('+theNumber+')',200);
		}
	else
		{
		moves++;
		undoerLive = false;
		movetime = 0;
		swap = pos[theNumber];
		pos[theNumber] = pos[selected];
		pos[selected] = swap;
		eval('document.p'+theNumber+'.src = pics['+pos[theNumber]+'].src');
		eval('document.p'+selected+'.src = pics['+pos[selected]+'].src');
		selected = -1;
		
		if (enforceTimeLimit || enforceMoveLimit)
			{
			stats();
			}
			
		check();
				
		if (enforceMoveLimit && (ordered != 1) && (moves == moveLimit))
			{
			// too late!
			alert("Nope. You lose.");
			}
		}
	}

function filespec(num)
	{
	var spec = imagePath + "/" + imageBaseName;
	if (num < 10)
		{
		spec = spec + "0" + num + imageExtension;
		}
	else
		{
		spec = spec + num + imageExtension;
		}
	return spec;
	}

//-->
</SCRIPT>
<BODY>
<CENTER>
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0">
<SCRIPT>init();</SCRIPT>
<SCRIPT>buildTable();</SCRIPT>
<SCRIPT>shuffle();</SCRIPT>
</TABLE>
<FORM NAME="stats">
<TABLE>
<TR><TD ALIGN="CENTER">Moves Remaining:</TD><TD ALIGN="CENTER">Time Remaining</TD></TR>
<TR><TD ALIGN="CENTER"><INPUT TYPE="TEXT" NAME="movesleft" SIZE="11" VALUE="loading..."></TD>
<TD ALIGN="CENTER"><INPUT TYPE="TEXT" NAME="timeleft" SIZE="10"></TD></TR>
</TABLE>
</FORM>
<SCRIPT>stats();</SCRIPT>
</CENTER>
</BODY>
</HTML>