<!--

//     COPYRIGHT 1998

//     Do not copy, distribute or otherwise re-use this code unless
//     this header is reproduced in full and credit is given to port80
//     the internet consultancy on the page where the slide puzzle
//     game appears. This means visibly. Do not remove the copyright
//     message or the link from above the game grid.

//     This code is protected under international copyright laws and,
//     through the ability to see the source JavaScript code, you must
//     not infer any permission to implement this or a modified
//     version of this code for use by you or another person without
//     due credit to port80. Permission is hereby given to reuse or
//     amend this code for either personal or commercial use on the
//     condition that due credit is given to port80 for the original
//     implementation of this method.

//     FOR THE LATEST VERSION OF THIS CODE AND INFORMATION ON
//     HOW TO RE-USE IT FREE OF CHARGE ON YOUR OWN SITE PLEASE SEE:

//     http://www.port80.co.uk/game.html


// designed and engineered by port80 the internet consultancy limited
// http://www.port80.com  enquire@port80.com    +44 (0)870 050 8080
// the old granary : riccall grange farm : riccall : york : yo4 6ql


///////////////////////////////////////////////////////////////////////////
//            YOU CAN CHANGE THESE FOR YOUR OWN APPLICATION              //
//    note you will need a blank gif graphic for the empty square and    //
//  also copy the dot.gif image which is a single pixel transparent gif  //
//                                                                       //
//    the blank square should be called blankxy.gif where x and y are    //
//  the numbers of the col and row of the blank square (eg blank33.gif)  //
///////////////////////////////////////////////////////////////////////////

// note that the max grid size is 10x10 because the pieces must be
// named blockXY.gif (or jpg).

var Version4 = ( parseInt( navigator.appVersion.substring( 0,1 ) ) >= 4 )

var bgcolor = "ffffe5";           // hex RGB values for grid border
var hwcolor = "FFF3EB";           // Hint window background color
var gridwidth = 4;                // define width..
var gridheight = 4;               // and height of game grid
var piecewidth = 40;              // define pixel width..
var pieceheight = 40;             // and height of puzzle piece graphics

var blankx = 3;                   // set the initial X..
var blanky = 0;                   // and Y position of blank square (0,0) is top left
var WindowName = "Dummy";        // hint window title

var gfxtype = "jpg";              // set type of graphics to jpg or gif
var hintpic = WindowName+".jpg";  // hint picture in graphics directory
var gfxdir = WindowName;          // set graphics directory path
var quiturl = "home.asp";         // page to link to when QUIT pressed
var hintwidth = 163;              // define pixel width..
var hintheight = 163;             // and height of hint picture graphic
var hintbutton = 'yes';
var savex = blankx;
var savey = blanky;

//  Added Functions to Puzzle 2000 (sln)

  var timerID = null;
  var cnt = 0;
  puzzles = new Array(6);
  puzzles[0] = new Array (3,0,"Maggie");
  puzzles[1] = new Array (0,3,"Mathilda");
  puzzles[2] = new Array (0,0,"Candy");
  puzzles[3] = new Array (0,0,"Douglas");
  puzzles[4] = new Array (3,3,"Ronja");
  puzzles[5] = new Array (0,0,"Puppies");

function ChangePuzzleImage(x)
{
  playing = true;
  savex = puzzles[x][0];
  savey = puzzles[x][1];
  WindowName = puzzles[x][2];
  hintpic = WindowName+".jpg";
  gfxdir = WindowName;
  if ( Version4 ) { blank = new Image(piecewidth,pieceheight); }
  blank.src = gfxdir+"/blank"+savex+savey+".gif";
  prevx = -1; prevy = -1;
  Quit();
}

function Quit()
{
  if ( playing ) {
    blankx=savex; blanky=savey; moves=0; playing=false;
    for(y=0;y<gridheight;y++) {
      for(x=0;x<gridwidth;x++) {
        if (x==blankx && y==blanky) { piece=gfxdir+"/blank"+x+y+".gif"; }
        else { piece=gfxdir+"/block"+x+y+"."+gfxtype; }
        replace="at"+x+y;
        putPuzzleImage( replace,piece );		// to be able to work with layers ( sln 2004 )
//        document.images[replace].src=piece;
      }
    }
  }
}

// End added functions (sln)

///////////////////////////////////////////////////////////////////////////
//            DO NOT CHANGE ANY OF THE FOLLOWING JAVASCRIPT              //
//            CODE - SEE THE END OF THE FILE FOR INFORMATION             //
//            ABOUT INSERTING YOUR OWN HTML AROUND THE PUZZLE            //
///////////////////////////////////////////////////////////////////////////

if ( Version4 ) {
  var prevx=-1; var prevy=-1;     // for tracking previous automatic (random) move
  var moves=0;                    // counter for holding number of moves
  var playing=false;              // define whether or not we are playing yet
  var blank=new Image(piecewidth,pieceheight);    // create a new image object of correct size
  blank.src=gfxdir+"/blank"+blankx+blanky+".gif"; // blank square image is sourced from blankXY.gif
}

// SLIDE:
// clickx, clicky:      define X,Y position where mouse clicked
// forceslide:          during shuffling we are not playing but slide still required

function slide(clickx,clicky,forceslide)
{
        // not shuffling and not playing - prompt us to shuffle the pieces
        if (!playing && !forceslide)
        {
                alert("\n\n\tYou must shuffle the pieces before you begin playing!\t\t\n\n");
                return;
        }
        // if we clicked on the blank square... do nothing
        if ((clickx==blankx) && (clicky==blanky)) return;
        // if we are playing/shuffling AND we clicked in the row/column where the blank is...
        if ((playing || forceslide) && (clickx==blankx) || (clicky==blanky))
        {
                // the next four lines determine where the blank is
                // in respect to the position we clicked on and then
                // move the pieces according: either up, down, left or right
                if (clicky>blanky) slideUp(clickx,clicky);
                if (clicky<blanky) slideDown(clickx,clicky);
                if (clickx>blankx) slideLeft(clickx,clicky);
                if (clickx<blankx) slideRight(clickx,clicky);
                // the blank will now be where we clicked to make the move
                blankx=clickx; blanky=clicky;
                // if we are playing, increment our moves and
                // check to see whether the puzzle has been solved
                if (playing) { moves++; checkSolved(); }
        }
}

// SLIDEUP:
// clickx, clicky:      passed in the position where mouse clicked

function slideUp(clickx,clicky)
{
        // for each position from the blank square down to where we clicked...
        for(movey=blanky;movey<clicky;movey++)
        {
                // set the names so that we can move the piece
                movefrom="at"+clickx+(movey+1); // from below the current position
                moveto="at"+clickx+movey;       // to the current position
                // source the new piece for this position to be
                // the one that was moved from below the current position
                putPuzzleImage( moveto,getPuzzleImage(movefrom) );		// to be able to work with layers  ( sln 2004 )
                // document.images[moveto].src=document.images[movefrom].src;
        }
        // source the final image (where we clicked) from the defined blank square image
        putPuzzleImage( movefrom,blank.src );		// to be able to work with layers  ( sln 2004 )
        // document.images[movefrom].src=blank.src;
}

// SLIDEDOWN:
// clickx, clicky:      passed in the position where mouse clicked

function slideDown(clickx,clicky)
{
        // for each position from the blank square up to where we clicked...
        for(movey=blanky;movey>clicky;movey--)
        {
                // set the names so that we can move the piece
                movefrom="at"+clickx+(movey-1); // from above the current position
                moveto="at"+clickx+movey;       // to the current position
                // source the new piece for this position to be
                // the one that was moved from above the current position
                putPuzzleImage( moveto,getPuzzleImage(movefrom) );		// to be able to work with layers  ( sln 2004 )
                // document.images[moveto].src=document.images[movefrom].src;
        }
        // source the final image (where we clicked) from the defined blank square image
        putPuzzleImage( movefrom,blank.src );		// to be able to work with layers  ( sln 2004 )
        // document.images[movefrom].src=blank.src;
}

// SLIDELEFT:
// clickx, clicky:      passed in the position where mouse clicked

function slideLeft(clickx,clicky)
{
        // for each position from the blank square right to where we clicked...
        for(movex=blankx;movex<clickx;movex++)
        {
                // set the names so that we can move the piece
                movefrom="at"+(movex+1)+clicky; // from the right of the current position
                moveto="at"+movex+clicky;       // to the current position
                // source the new piece for this position to be
                // the one that was moved from the right of the current position
                putPuzzleImage( moveto,getPuzzleImage(movefrom) );		// to be able to work with layers  ( sln 2004 )
                // document.images[moveto].src=document.images[movefrom].src;
        }
        // source the final image (where we clicked) from the defined blank square image
        putPuzzleImage( movefrom,blank.src );		// to be able to work with layers  ( sln 2004 )
        // document.images[movefrom].src=blank.src;
}

// SLIDERIGHT:
// clickx, clicky:      passed in the position where mouse clicked

function slideRight(clickx,clicky)
{
        // for each position from the blank square left to where we clicked...
        for(movex=blankx;movex>clickx;movex--)
        {
                // set the names so that we can move the piece
                movefrom="at"+(movex-1)+clicky; // from the left of the current position
                moveto="at"+movex+clicky;       // to the current position
                // source the new piece for this position to be
                // the one that was moved from the left of the current position
                putPuzzleImage( moveto,getPuzzleImage(movefrom) );		// to be able to work with layers  ( sln 2004 )
                // document.images[moveto].src=document.images[movefrom].src;
        }
        // source the final image (where we clicked) from the defined blank square image
        putPuzzleImage( movefrom,blank.src );		// to be able to work with layers  ( sln 2004 )
        // document.images[movefrom].src=blank.src;
}

// HINT:

function hint()
{
        // this routine will open up a new window and write some HTML code into
        // it that will display the small version of the completed puzzle for
        // ten seconds and then it will close the window
        hintparams="toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width="+(hintwidth+20)+",height="+(hintheight+20);
        hintwindow=open('','hintwindow',hintparams);
        hintwindow.document.writeln('<html>');
        hintwindow.document.writeln('<head>');
        hintwindow.document.writeln('<title>'+WindowName+'</title>');
        hintwindow.document.writeln('</head>');
        hintwindow.document.writeln('<body Leftmargin="0" Topmargin="0" bgcolor="#'+hwcolor+'" onLoad="window.focus(); timeout=setTimeout(\'window.close()\',10000);">');
        hintwindow.document.writeln('<table cellspacing=0 cellpadding=0 border=0 bgcolor="#'+hwcolor+'" width="100%" height="100%"><tr><td Align=Center VAlign=Middle><table cellspacing=0 cellpadding=0 border=1><tr><td><img alt="completed puzzle" src="'+gfxdir+'/'+hintpic+'" width='+hintwidth+' height='+hintheight+'></td></tr></table></td></tr></table>');
        hintwindow.document.writeln('</body>');
        hintwindow.document.writeln('</html>');
        hintwindow.document.close();
}

// RANDOMSLIDE:
// iterations:          the number of times to do a single random move

function randomSlide(iterations)
{
        {
                // suspend play while we do it
                playing=false;
                // count down the iterations
                while (iterations--)
                {
                        // initially we set an invalid move because this routine
                        // just fakes mouse clicks at randomly selected positions
                        // and we want to select a valid move randomly from the start
                        clickx=blankx;
                        clicky=blanky;
                        // choose randomly whether to fake a move in the
                        // same row or the same column as the blank
                        // .. note that we could have just gone on picking
                        // completely random moves until we got a valid one,
                        // but when we can be sensible about it, what's the point?!
                        if (Math.random()>.5)   // fake a move in the same column as the blank
                        {
                                // keep selecting a new X position until we get one
                                // that is neither the blank square nor going to give
                                // us a result the same as the previous move
                                while ((clickx==blankx) || (clickx==prevx))
                                {
                                 clickx=Math.floor(Math.random()*gridwidth);
                                }
                                // we set the column to be the same as the blank square
                                clicky=blanky;
                        }
                        else                    // fake a move in the same row as the blank
                        {
                                // keep selecing a new Y position until we get one
                                // that is neither the blank square nor going to give
                                // us a result the same as the previous move
                                while ((clicky==blanky) || (clicky==prevy))
                                {
                                 clicky=Math.floor(Math.random()*gridheight);
                                }
                                // we set the row to be the same as the blank square
                                clickx=blankx;
                        }
                        // set variables so that when we do another random move we can
                        // make sure that we don't end up just shuffling the same pieces
                        // back and forth continually
                        prevx=blankx;
                        prevy=blanky;
                        // we picked our place, let's fake the move - the true value is
                        // passed so that our slide function knows it is being faked
                        slide(clickx,clicky,true);
                }
                // check to see if we solved it by shuffling
                checkSolved();
                // resume (or start) play as we have finished shuffling
                playing=true;
        }
}

// CHECKSOLVED:

function checkSolved()
{
        // This routine works by virtue of the fact that we have named
        // the images using the convention atXY (where X and Y are the numbers
        // of the row and column so that at00 is the top left square position)
        // and that the actual graphics are sourced from images with the name
        // blockXY (where X and Y are the numbers of the row and column where
        // the image is originally found). Therefore the puzzle is solved when
        // all atXY positions are filled by the corresponding blockXY graphic.
        // For example, if position at00 held block30.gif then we know the puzzle
        // has not been solved.
        // start off by assuming the puzzle has been solved
        solved=true;
        // sweep down the rows of the board..
        for(y=0;y<gridheight;y++)
        {
                // ..and across the columns in the current row
                for(x=0;x<gridwidth;x++)
                {
                        // work out the name that we assigned to this row and column pair on the board
                        name1="at"+x+y;
                        // this is the source name of the image currently at this position 
                        // block=document.images[name1].src;
			var blockName = getPuzzleImage( name1 );		// to be able to work with layers  ( sln 2004 )
                        // grab the index in the string of the two digit part (eg block12.gif -> 12)
                        start=blockName.lastIndexOf(".")-2;
                        // work out the name where this image starts out
                        name2="at"+blockName.substring(start,start+2);
                        // if this image didn't start out here, we've not solved the puzzle
                        if (name1!=name2) solved=false;
                }
        }
        // got through all the positions without declaring that the
        // puzzled had not been solved, therefore by a simple process
        // of elimination.. we've solved it!
        if (solved)
        {
                // alert us to the fact we completed the puzzle and tell us
                // how many moves were counted - JavaScript is held at this
                // statement until the OK box is clicked in the alert window
                replace="at"+blankx+blanky;
                putPuzzleImage( replace,gfxdir+"/block"+blankx+blanky+"."+gfxtype );		// to be able to work with layers  ( sln 2004 )
                // document.images[replace].src=gfxdir+"/block"+blankx+blanky+"."+gfxtype;
                alert("\n\n\tCONGRATULATIONS!\n\tYou solved the slide puzzle in "+moves+" moves.\n\n\tPress the OK button, then shuffle the pieces if you want to try again.\t\t\n\n");
                // reset the move counter to zero and indicate that we've finished playing
                moves=0; playing=false;
        }
}

// DISPLAYGRID:

function displaygrid()
{
        var piece="";

        document.writeln('<Form Action="',quiturl,'">');
        document.writeln('\t    <Table Align=Center CellSpacing=0 CellPadding=0 Border=0>\n\t\t<tr>\n\t\t    <Td Class=navigate Align=Center>\n\t\t\t<Font Face="Comic Sans MS" Size=1>\n\t\t\t    <A Href="Http://www.port80.co.uk/slide/" onMouseOver="display(\'Find out how to make your own puzzle\'); window.status=\'\'; return true" onMouseOut="display(\'\')" Target="_Top">GAME CODE COPYRIGHT PORT80</A>\n\t\t\t</Font>\n\t\t    </Td>\n\t\t</Tr>');
        document.writeln('\t\t<Tr>\n\t\t    <Td Align=Center>\n\t\t\t<Table CellSpacing=0 CellPadding=0 Border=1 BgColor="#',bgcolor,'">');
        document.writeln('\t\t\t    <Tr>\n\t\t\t\t<Td>\n\t\t\t\t    <Table CellSpacing=1 CellPadding=0 Border=0>');

        // sweep down the rows of the board..
        for(y=0;y<gridheight;y++)
        {
                document.writeln('\t\t\t\t\t<Tr>');

                // ..and across the columns in the current row
                for(x=0;x<gridwidth;x++)
                {
                        if (x==blankx && y==blanky) { piece=gfxdir+"/blank"+x+y+".gif"; }
                        else { piece=gfxdir+"/block"+x+y+"."+gfxtype; }
                        document.writeln('\t\t\t\t\t    <Td><A Href="#TopOfPage" onMouseOver="window.status=\'\'; return true;"  onClick="slide('+x+','+y+',false);"><Img Alt="('+x+','+y+')" Src="'+piece+'" Name="at'+x+y+'" Width='+piecewidth+' Height='+pieceheight+' Border=0></A></Td>' );
                }
                document.writeln('\t\t\t\t\t</Tr>');
        }

        document.writeln('\t\t\t\t    </Table>\n\t\t\t\t</Td>\n\t\t\t    </Tr>');
        document.writeln('\t\t\t</Table>\n\t\t    </Td>\n\t\t</Tr>');
        document.writeln('\t\t<Tr>');
        document.writeln('\t\t    <Td Align=Center>');
        document.writeln('\t\t\t<Img Src="../global/dot.gif" Width=1 Height=5><Br>');
        document.writeln('\t\t\t<Input Type="Button" Value="Shuffle" onClick="randomSlide(',gridwidth*gridheight*3,');">');
        document.writeln('\t\t\t<Input Type="Button" Value="&nbsp;Hint&nbsp;" onClick="hint();">');
        document.writeln('\t\t\t<Input Type="Button" Value="&nbsp;Quit&nbsp;" onClick="Quit()">\n\t\t    </Td>');
        document.writeln('\t\t</Tr>');
        document.writeln('\t    </Table>');
        document.writeln('\t</Form>');
}

// that's all folks -->
///////////////////////////////////////////////////////////////////////////
//            DO NOT CHANGE ANYTHING ABOVE THIS POINT OTHER              //
//            THAN THE VARIABLE BLOCK IF REQUIRED TO CHANGE              //
//            THE SIZE OF THE GAME GRID OR THE PIECES                    //
///////////////////////////////////////////////////////////////////////////

//    SLIDE PUZZLE END
// -->
