layout = new Array(
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"),
  new Array("0","0","0","0","0","0","0","0","0","0"));

// Graphic OFFSET
offset = 0;

playerI = 0;
playerJ = 0;
opponentI = 0;
opponentJ = 0;
gameRunning = 0;
exitI = 0;
exitJ = 0;
freezeDevices = 0;
opponentFreeze = 0;
timeRemaining = 0;

function loadImages() {
  catI=new Image(); 
  catI.src="images/mycat.gif";
  
  catFreezeI = new Image();
  catFreezeI.src="images/cfreeze.gif";
  
  freezeDevI = new Image();
  freezeDevI.src="images/myquick.gif";
  
  mouseFreezeI = new Image();
  mouseFreezeI.src="images/mfreeze.gif";
  
  cheeseI = new Image();
  cheeseI.src="images/mycheese.gif";
  
  mouseI = new Image();
  mouseI.src="images/mymouse.gif"
  
  mouseWinI = new Image();
  mouseWinI.src="images/win.gif";
  
  blankI = new Image();
  blankI.src="images/blank.gif";

  wallI = new Image();
  wallI.src="images/wall.gif";

  
}

function startGame() {

  loadImages();
  setInterval("runTimer()", 1000);
  //reset();
}

function redrawLayout() {

  for(var i=0; i < 10; i++) {
  
    for(var j=0; j < 10; j++) {
      
      var bit = layout[i][j];
      
      if (bit == 0) {
      
      	document.images[i*10+j+offset].src=blankI.src;
      	
      } else if (bit == 1) {
      
      	document.images[i*10+j+offset].src=wallI.src;
      
      } else if (bit == 2) {
      
      	document.images[i*10+j+offset].src=freezeDevI.src;
  	
      } else if (bit == 3) {
      
      	document.images[i*10+j+offset].src=cheeseI.src;
      }
    }
  }
  
  document.images[playerI * 10 + playerJ+offset].src=mouseI.src;
  document.images[opponentI * 10 + opponentJ+offset].src=catI.src;
  
  // Check if win
  if (layout[playerI][playerJ] == 3) {
  
    // WIN!
    document.images[playerI * 10 + playerJ+offset].src=mouseWinI.src;
    document.jsgame.messages.value="You won, you got the cheese!";
    doScore();
  }

  // Check if opponent win
  if (layout[opponentI][opponentJ] == 3 && gameRunning == 1) {
  
    // WIN!
    document.jsgame.messages.value="The cat got the cheese!";
    doScore2();
  }

  // Check if cat in quick sand
  if (layout[opponentI][opponentJ] == 2) {
      
    document.images[opponentI * 10 + opponentJ+offset].src=catFreezeI.src;
  }

  // Check if mouse in quick sand
  if (layout[playerI][playerJ] == 2) {
      
    document.images[playerI * 10 + playerJ+offset].src=mouseFreezeI.src;
  }
  
  // Check if time remaining has run out
  if (timeRemaining >= 100) {
    doScore();
    //window.status = "Times up!";
    document.jsgame.time.value="Times up!";
  } else {
     document.jsgame.time.value=timeRemaining  + " second(s)";
  }
  
  document.jsgame.freezedevices.value=freezeDevices + " left";
  
}

function KBEvent(e) {

  var keycode;
  var playerI2 = playerI;
  var playerJ2 = playerJ;
  
  if (e.keyCode) keycode=e.keyCode;
    else keycode=e.which;
    
  var character = String.fromCharCode(keycode);

  if (gameRunning == 1) {
  
    flag = 1;
    
    if (character == 'a') {
      // Move left
      if (playerJ2 > 0) {
        playerJ2--;
      } else {
        flag = 0;
      }
      
    } else if (character == 's') {
    
      // Move down
      if (playerI2 < 9) {
        playerI2++
      } else {
        flag = 0;
      }
      
    } else if (character == 'd') {
    
      // Move right
      if (playerJ2 < 9) {
        playerJ2++
      } else {
        flag = 0;
      }
      
    } else if (character == 'w') {
      // Move up
      if (playerI2 > 0) {
        playerI2--;
      } else {
        flag = 0;
      }

    } else if (character == 'o') {
      // Freeze Device
      if (freezeDevices > 0 && layout[playerI2][playerJ2] == 0) {
      
      	freezeDevices--;
      	layout[playerI2][playerJ2] = 2;
      	flag = 0;
      	
      } 
             
    } else {
    
      flag = 0;
      
    }
    
    if (flag == 1) {
    
      if (layout[playerI2][playerJ2] == 1) {
    
    	// Wall
	document.jsgame.messages.value="Thump! You hit the wall";
      
      } else {
        
        playerI=playerI2;
        playerJ=playerJ2;

	// Did we hit opponent
	if (playerI == opponentI && playerJ == opponentJ) {
	
	  window.status = "You walked into the cat!";
	  doScore2();
	} else if (playerI == exitI && playerJ == exitJ) {
	 
	  redrawLayout();
	  doScore();	  
	} else {      
	
	  // Did you get into quicksand?
	  if (layout[playerI][playerJ] == 2) {
	  
	    // We did
	    // 3 moves
	    document.jsgame.messages.value="You walked into quicksand!";
	    
            moveOpp();
            moveOpp();

	  }
        }
      	moveOpp();
      }
      redrawLayout();
    }
  } else {
  
    window.status = "Game not running!";
  }

}

function reset() {

  // Reset the board
  for(var i=0; i < 10; i++) {
  
    for(var j=0; j < 10; j++) {

      layout[i][j] = 1;
    }
    
  }
    
  // Select random starting position
  playerI = Math.round(Math.random() * 9);
  playerJ = Math.round(Math.random() * 9);
  
  layout[playerI][playerJ] = 0;
 
  var squares = 60 + Math.round(Math.random() * 15);
  
  var i;
  var tmpi;
  var tmpj;
  
  for (i = 0; i < squares; i++) {

    tmpi = Math.round(Math.random() * 9);
    tmpj = Math.round(Math.random() * 9);
    
    if (layout[tmpi][tmpj] != 0) {
    	layout[tmpi][tmpj] = 0;
    } else {
    
    	i--;
    }
    	
  }

  // Test it is solvable - Warshall's algorithm
  
  // Create matrix (100 x 100)
  var matrix = new Array(100);
  
  for (i = 0; i < 100; i++) {
  
    matrix[i] = new Array(100);

    for (j = 0; j < 100; j++) {
      matrix[i][j] = 0;
    }    
  }
  for (i = 0; i < 10; i++) {
  
    for (j = 0; j < 10; j++) {
    
      // Check if this node is connected
      if (layout[i][j] != 1) {
      
        // Yes it is
        
        // Up
        if (i > 0) {
        
          // We could go up
          if (layout[i-1][j] != 1) {
          
            // Up possible, mark
            matrix[i*10+j][(i-1)*10+j] = 1;
          }
          
        }

        // Down
        if (i < 9) {
        
          // We could go down
          if (layout[i+1][j] != 1) {
          
            // Down possible, mark
            matrix[i*10+j][(i+1)*10+j] = 1;
          }
          
        }
        // Left
        if (j > 0) {
        
          // We could go left
          if (layout[i][j-1] != 1) {
          
            // Left possible, mark
            matrix[i*10+j][i*10+(j-1)] = 1;
          }
          
        }

        // Right
        if (j < 9) {
        
          // We could go right
          if (layout[i][j+1] != 1) {
          
            // Right possible, mark
            matrix[i*10+j][i*10+(j+1)] = 1;
          }
          
        }

      }
    }
  }
  // Run Warshall's algorithm
  for (i = 0; i < 100; i++) {
  
    for (j = 0; j < 100; j++) {
    
      if (matrix[j][i] == 1) {
      
        for (k=0; k < 100; k++) {
        
          if (matrix[i][k] == 1) {
          
            matrix[j][k] = 1;
          
          }
        }
        
      }
    }
    
  }

  posGen();

  while (!posCheck(matrix)) {
    posGen();
    
  }
  layout[exitI][exitJ]=3;
  gameRunning = 1;
  freezeDevices = 3;
  opponentFreeze = 0;
  timeRemaining = 0;
  redrawLayout();
  document.jsgame.messages.value="Your time starts now!";
  
  
  
}



function posGen() {
  // Randomly choose a starting position
  playerI = Math.round(Math.random() * 9);
  playerJ = Math.round(Math.random() * 9);
  while (layout[playerI][playerJ] != 0){
    playerI = Math.round(Math.random() * 9);
    playerJ = Math.round(Math.random() * 9);
    
  }
  
  // Opponent position
  opponentI = Math.round(Math.random() * 9);
  opponentJ = Math.round(Math.random() * 9);
  while (layout[opponentI][opponentJ] != 0){
    opponentI = Math.round(Math.random() * 9);
    opponentJ = Math.round(Math.random() * 9);
    
  }
  
  // Exit position
  exitI = Math.round(Math.random() * 9);
  exitJ = Math.round(Math.random() * 9);
  while (layout[exitI][exitJ] != 0){
    exitI = Math.round(Math.random() * 9);
    exitJ = Math.round(Math.random() * 9);
    
  }

}

function posCheck(matrix) {

  // Check if player == oponent
  if (playerI == opponentI && playerJ == opponentJ) {
  
    return 0;
    
  }

  // Check if player == exit
  if (playerI == exitI && playerJ == exitJ) {
  
    return 0;
    
  }

  // Check if opponent == exit
  if (opponentI == exitI && opponentJ == exitJ) {
  
    return 0;
    
  }
  
  // Check that there is a path from player to opponent
  if (matrix[playerI*10+playerJ][opponentI*10+opponentJ] == 0) {
  
    // No path
    return 0;
    
  }
  
  // Check if path from player to cheese
  // Assumes then that there is path from opponent to cheese
  if (matrix[playerI*10+playerJ][exitI*10+exitJ] == 0) {
  
    // No path
    return 0;
    
  }

  // Check if mouse is too close to cat
  if (Math.sqrt(Math.pow(playerI-opponentI,2)+Math.pow(playerJ-opponentJ,2)) < 5) {
  
    return 0;
    
  }

  // Check if mouse is too close to exit
  if (Math.sqrt(Math.pow(playerI-exitI,2)+Math.pow(playerJ-exitJ,2)) < 5) {
  
    return 0;
    
  }

  // Check if cat is too close to exit
  if (Math.sqrt(Math.pow(opponentI-exitI,2)+Math.pow(opponentJ-exitJ,2)) < 5) {
  
    return 0;
    
  }
  
  
  return 1;
}

function getOppProb(i, j) {

  // Check if in range
  if (i > 9 || i < 0 || j < 0 || j > 9) {
  
    return 10000;
    
  }
  
  // Check if valid
  if (layout[i][j] == 1) {
  
    // NO
    
    return 10000;
    
  }
    
  var prob1 = Math.sqrt(Math.pow((i)-(playerI),2) + Math.pow((j)-(playerJ),2));
  var prob2 = Math.sqrt(Math.pow((i)-(exitI),2) + Math.pow((j)-(exitJ),2));
  
  if (prob1 < prob2) {
  
    return prob1;
    
  } else {
  
    return prob2;
    
  }

}

function moveOpp() {

  
  // Are we currently in quicksand?
  if (opponentFreeze == 0) {
  
    // Move the opponent
    var moves = new Array(5);
  
    moves[0] = getOppProb(opponentI,opponentJ+1);
    moves[1] = getOppProb(opponentI-1,opponentJ);
    moves[2] = getOppProb(opponentI,opponentJ-1);
    moves[3] = getOppProb(opponentI+1,opponentJ);
    moves[5] = 10000;
    //window.status = moves[0] + " " + moves[1] + " " + moves[2] + " " + moves[3];
    // Select the highest prob
    var move = 5;
    for (var i = 0; i < 4; i++) {
    
      if (moves[i] < moves[move]) {
    
        move = i;
      
      }
    
    }
  
    if (move == 0) {
  
      // Right
      opponentJ++;
    
    } else if (move == 1) {
  
      // Up
      opponentI--;
    
    } else if (move == 2) {
  
      // Left
      opponentJ--;
    } else if (move == 3) {
  
      // Down
      opponentI++;
    
    } else {
  
      gameRunning = 0;
      doScore2();
    }
    
    // Did we hit quicksand?
    if (layout[opponentI][opponentJ] == 2) {
    
      // We have
      opponentFreeze=3;
      document.jsgame.messages.value="The cat walked into some quicksand!";
      
    } else if (playerI == opponentI && playerJ == opponentJ) {
	
      // Cat got player
      document.jsgame.messages.value="The cat got you!";
      doScore2();
      
    }
 
  } else {
  
    opponentFreeze--;
    document.jsgame.messages.value="The cat is start to get free, " + opponentFreeze + " turn(s) should do it!";
    
  }
}  

function runTimer() {

  if (gameRunning == 1) {
 
    timeRemaining++;

    if (timeRemaining >= 100) {
      //window.status = "Times up!";
      document.jsgame.time.value="Times up!";
      doScore();
    
    } else {
      document.jsgame.time.value=timeRemaining  + " second(s)";
    }
  }
}


function doScore() {
	
  document.jsgame.messages.value+=" Score: " + (100 - timeRemaining);
  gameRunning = 0;
}

function doScore2() {
	
  document.jsgame.messages.value+=" Score: 0";
  gameRunning = 0;
}



