
//***************************************************************************
//    CLASS LABYRINTH
//---------------------------------------------------------------------------
function Labyrinth(rows, cols, hall_len, circles)
{
//-- DATA ------
   this.n_rows      = rows;
   this.n_cols      = cols;
   this.hall_length = hall_len;
   this.n_circles   = circles;
   this.curr_row    = 0;
   this.curr_col    = 0;
   this.positions   = new Table(rows, cols);
   this.orientation = "South";
   this.moveCounter = 0;
   this.start_row   = 0;
   this.start_col   = 0;
   this.visibles    = new Array();
   this.oldVisibles = null;
   this.noArrows    = false;


//-- METHODS ---
   this.getWalls      = LabyrinthGetWalls;
   this.goForward     = LabyrinthGoForward;
   this.turnLeft      = LabyrinthTurnLeft;
   this.turnRight     = LabyrinthTurnRight;
   this.displayLayers = LabyrinthDisplayLayers;
   this.display       = LabyrinthDisplay;
   this.initPosition  = LabyrinthInitPosition;
   this.addVisible    = LabyrinthAddVisible;
   this.clearVisibles = LabyrinthClearVisibles;
   this.hideOldLayers = LabyrinthHideOldLayers;
   this.close         = LabyrinthClose;

//-- CONSTRUCTOR -----
   var labyrBuilder = new LabyrinthBuilder(this);
   labyrBuilder = null;
}


function LabyrinthClose() {
   for (var aaa = 0; aaa < this.visibles.length; aaa++) {
     hideLayer(this.visibles[aaa]);
   }
}

function LabyrinthInitPosition() {
   this.curr_row = this.start_row;
   this.curr_col = this.start_col;
}

function LabyrinthClearVisibles() {
  //this is not to have the screen blinking.
   this.oldVisibles = this.visibles;
   this.visibles = new Array();
}

function LabyrinthHideOldLayers() {
   var LayerName, hideTest;

   //Hide the layers we don't need from oldVisible.
   var toHide = new Array();
   for (var jjj = 0; jjj < this.oldVisibles.length; jjj++) {
     LayerName = this.oldVisibles[jjj];
     hideTest = true;

     for (var kkk = 0; kkk < this.visibles.length; kkk++) {
       if (this.visibles[kkk] == LayerName) {
         hideTest = false; break;
       }
     }
     if (hideTest) { toHide[toHide.length] = LayerName; }
   }
   for (var bbb = 0; bbb < toHide.length; bbb++) {
     hideLayer(toHide[bbb]);
   }
}

function LabyrinthAddVisible(toAdd) {
   this.visibles[this.visibles.length] = toAdd;
   showLayer(toAdd);
}

//---------------------------------------------------------------------------
//    LABYRYNTH : DISPLAY
//---------------------------------------------------------------------------
function LabyrinthDisplay() { 
   
   this.clearVisibles();
   this.moveCounter++;
   var cnt = this.moveCounter;
   this.noArrows = false;

   if ( this.curr_row >= this.n_rows ) {
      if (this.orientation == "North") { 
        this.addVisible("WallFL1");
        this.addVisible("DoorF1");
        this.addVisible("WallFR1");
      }
      else {
        this.addVisible("startMessage");
        this.noArrows = true;
      }
   }
   else if ( this.curr_row < 0 ) {
      if (this.orientation == "South") { 
        this.addVisible("WallFL1");
        this.addVisible("DoorF1");
        this.addVisible("WallFR1");
      }
      else {
        this.addVisible("winMessage");
        this.noArrows = true;
      }
   }
   else { 
     this.displayLayers(); 
   }
   
   if (this.orientation == "North") {
      showLayer("compasNorth");
      hideLayer("compasSouth");
      hideLayer("compasWest");
      hideLayer("compasEast");
   }
   else if (this.orientation == "South") {
      showLayer("compasSouth");
      hideLayer("compasNorth");
      hideLayer("compasWest");
      hideLayer("compasEast");
   }
   else if (this.orientation == "West") {
      showLayer("compasWest");
      hideLayer("compasNorth");
      hideLayer("compasSouth");
      hideLayer("compasEast");
   }
   else if (this.orientation == "East") {
      showLayer("compasEast");
      hideLayer("compasNorth");
      hideLayer("compasSouth");
      hideLayer("compasWest");
   }
   this.hideOldLayers();
}

//---------------------------------------------------------------------------
//    LABYRYNTH : GET WALLS
// Returns an integer value that represents the position of the walls at
//  the passed-in relative position (depends on the orientation).
//  The returned value is read as frontWall=+1, leftWall=+2, rightWall=+4.
//  (right<0 means left)
//---------------------------------------------------------------------------
function LabyrinthGetWalls(forward, right) {

   var target_row = this.curr_row;
   var target_col = this.curr_col;
        if (this.orientation == "North")  { target_row -= forward;  target_col += right; }
   else if (this.orientation == "South")  { target_row += forward;  target_col -= right; }
   else if (this.orientation == "West")   { target_row -= right;  target_col -= forward; }
   else if (this.orientation == "East")   { target_row += right;  target_col += forward; }
   var walls = this.positions[target_row][target_col];

   var result = 0;
   if (this.orientation == "North")
   {  if (walls & 1)  result += 1;
      if (walls & 4)  result += 2;
      if (walls & 8)  result += 4;
      if (walls & 16) result += 16; }
   else if (this.orientation == "South")
   {  if (walls & 2)  result += 1;
      if (walls & 8)  result += 2;
      if (walls & 4)  result += 4;
      if (walls & 32) result += 16; }
   else if (this.orientation == "West")
   {  if (walls & 4)  result += 1;
      if (walls & 2)  result += 2;
      if (walls & 1)  result += 4;
      if (walls & 32) result += 32;
      if (walls & 16) result += 64; }
   else if (this.orientation == "East")
   {  if (walls & 8)  result += 1;
      if (walls & 1)  result += 2;
      if (walls & 2)  result += 4;
      if (walls & 16) result += 32;
      if (walls & 32) result += 64; }
   return(result);
}

//---------------------------------------------------------------------------
//    LABYRYNTH : DISPLAY LAYERS
//---------------------------------------------------------------------------
function LabyrinthDisplayLayers() { 
   var cnt = this.moveCounter;

   //*** CENTRAL PART
   //------------------------------------------------------------------------------------
   if      (this.getWalls(0,0) & 1)            { this.addVisible("WallF1");   }
   else if (this.getWalls(0,0) & 16)           { this.addVisible("DoorF1");   }
   else
   {  if      (this.getWalls(1,0) & 2)         { this.addVisible("WallL2");   }
      else if (this.getWalls(1,0) & 32)        { this.addVisible("DoorL2");   }
      else                                     { this.addVisible("NoWallL2"); }
      if      (this.getWalls(1,0) & 4)         { this.addVisible("WallR2");   }
      else if (this.getWalls(1,0) & 64)        { this.addVisible("DoorR2");   }
      else                                     { this.addVisible("NoWallR2"); }
   // -------
      if      (this.getWalls(1,0) & 1)         { this.addVisible("WallF2");   }
      else if (this.getWalls(1,0) & 16)        { this.addVisible("DoorF2");   }
      else
      {  if      (this.getWalls(2,0) & 2)      { this.addVisible("WallL3");   }
         else if (this.getWalls(2,0) & 32)     { this.addVisible("DoorL3");   }
         else                                  { this.addVisible("NoWallL3"); }
         if      (this.getWalls(2,0) & 4)      { this.addVisible("WallR3");   }
         else if (this.getWalls(2,0) & 64)     { this.addVisible("DoorR3");   }
         else                                  { this.addVisible("NoWallR3"); }
   //    ------- 
         if      (this.getWalls(2,0) & 1)      { this.addVisible("WallF3");   }
         else if (this.getWalls(2,0) & 16)     { this.addVisible("DoorF3");   }
         else
         {  if      (this.getWalls(3,0) & 2)   { this.addVisible("WallL4");   }
            else if (this.getWalls(3,0) & 32)  { this.addVisible("DoorL4");   }
            else                               { this.addVisible("NoWallL4"); }
            if      (this.getWalls(3,0) & 4)   { this.addVisible("WallR4");   }
            else if (this.getWalls(3,0) & 64)  { this.addVisible("DoorR4");   }
            else                               { this.addVisible("NoWallR4"); }
   //       ------- 
            if      (this.getWalls(3,0) & 1)   { this.addVisible("WallF4");   }
            else if (this.getWalls(3,0) & 16)  { this.addVisible("DoorF4");   }
            else                               { this.addVisible("NoWallF4"); }
   }  }  }

   //*** LEFT PART
   //------------------------------------------------------------------------------------
   if      (this.getWalls(0,0) & 2)             { this.addVisible("WallL1");      }
   else if (this.getWalls(0,0) & 32)            { this.addVisible("DoorL1");      }
   else
   {  if      (this.getWalls(0,-1) & 1)         { this.addVisible("WallFL1");     }
      else if (this.getWalls(0,-1) & 16)        { this.addVisible("DoorFL1");     }
      else
   // -------
      {  if      (this.getWalls(1,-1) & 2)      { this.addVisible("WallLL2");     }
         else if (this.getWalls(1,-1) & 32)     { this.addVisible("DoorLL2");     }
         else if (this.getWalls(1,-2) & 1)      { this.addVisible("WallFLL2");    }
         else if (this.getWalls(1,-2) & 16)     { this.addVisible("DoorFLL2");    }
         else if (this.getWalls(2,-2) & 1)      { this.addVisible("WallFLL3bis"); }
         else if (this.getWalls(2,-2) & 16)     { this.addVisible("DoorFLL3bis"); }
         else                                   { this.addVisible("NoWallLL2");   }
   //    -------
         if      (this.getWalls(1,-1) & 1)      { this.addVisible("WallFL2");     }
         else if (this.getWalls(1,-1) & 16)     { this.addVisible("DoorFL2");     }
         else
         {  if      (this.getWalls(2,-1) & 2)   { this.addVisible("WallLL3");     }
            else if (this.getWalls(2,-1) & 32)  { this.addVisible("DoorLL3");     }
            else if (this.getWalls(2,-2) & 1)   { this.addVisible("WallFLL3");    }
            else if (this.getWalls(2,-2) & 16)  { this.addVisible("DoorFLL3");    }
            else if (this.getWalls(3,-2) & 1)   { this.addVisible("WallFLL4bis"); }
            else if (this.getWalls(3,-2) & 16)  { this.addVisible("DoorFLL4bis"); }
            else                                { this.addVisible("NoWallLL3");   }
   //       -------
            if      (this.getWalls(2,-1) & 1)   { this.addVisible("WallFL3");     }
            else if (this.getWalls(2,-1) & 16)  { this.addVisible("DoorFL3");     }
            else if (this.getWalls(3,-1) & 2)   { this.addVisible("WallLL4");     }
            else if (this.getWalls(3,-1) & 32)  { this.addVisible("DoorLL4");     }
            else if (this.getWalls(3,-2) & 1)   { this.addVisible("WallFLL4");    }
            else if (this.getWalls(3,-2) & 16)  { this.addVisible("DoorFLL4");    }
            else                                { this.addVisible("NoWallLL4");   }
   }  }  }

   //*** RIGHT PART
   //------------------------------------------------------------------------------------
   if      (this.getWalls(0,0) & 4)            { this.addVisible("WallR1");      }
   else if (this.getWalls(0,0) & 64)           { this.addVisible("DoorR1");      }
   else
   {  if      (this.getWalls(0,1) & 1)         { this.addVisible("WallFR1");     }
      else if (this.getWalls(0,1) & 16)        { this.addVisible("DoorFR1");     }
      else
   // -------
      {  if      (this.getWalls(1,1) & 4)      { this.addVisible("WallRR2");     }
         else if (this.getWalls(1,1) & 64)     { this.addVisible("DoorRR2");     }
         else if (this.getWalls(1,2) & 1)      { this.addVisible("WallFRR2");    }
         else if (this.getWalls(1,2) & 16)     { this.addVisible("DoorFRR2");    }
         else if (this.getWalls(2,2) & 1)      { this.addVisible("WallFRR3bis"); }
         else if (this.getWalls(2,2) & 16)     { this.addVisible("DoorFRR3bis"); }
         else                                  { this.addVisible("NoWallRR2");   }
   //    -------
         if      (this.getWalls(1,1) & 1)      { this.addVisible("WallFR2");     }
         else if (this.getWalls(1,1) & 16)     { this.addVisible("DoorFR2");     }
         else
         {  if      (this.getWalls(2,1) & 4)   { this.addVisible("WallRR3");     }
            else if (this.getWalls(2,1) & 64)  { this.addVisible("DoorRR3");     }
            else if (this.getWalls(2,2) & 1)   { this.addVisible("WallFRR3");    }
            else if (this.getWalls(2,2) & 16)  { this.addVisible("DoorFRR3");    }
            else if (this.getWalls(3,2) & 1)   { this.addVisible("WallFRR4bis"); }
            else if (this.getWalls(3,2) & 16)  { this.addVisible("DoorFRR4bis"); }
            else                               { this.addVisible("NoWallRR3");   }
   //       -------
            if      (this.getWalls(2,1) & 1)   { this.addVisible("WallFR3");     }
            else if (this.getWalls(2,1) & 16)  { this.addVisible("DoorFR3");     }
            else if (this.getWalls(3,1) & 4)   { this.addVisible("WallRR4");     }
            else if (this.getWalls(3,1) & 64)  { this.addVisible("DoorRR4");     }
            else if (this.getWalls(3,2) & 1)   { this.addVisible("WallFRR4");    }
            else if (this.getWalls(3,2) & 16)  { this.addVisible("DoorFRR4");    }
            else                               { this.addVisible("NoWallRR4");   }
   }  }  }
}

//---------------------------------------------------------------------------
//    LABYRYNTH : GO FORWARD
//---------------------------------------------------------------------------
function LabyrinthGoForward() { //alert("goForward");
  if ( this.curr_row >= this.n_rows ) {  // Starting point.
    if (this.orientation == "North") this.curr_row--;
    this.orientation = "North";
  }
  else if ( this.curr_row < 0 ) {        // Winning Point.
    return; 
  }
  else if ((this.orientation == "North") && !(this.positions[this.curr_row][this.curr_col] & 1))  { this.curr_row--; }
  else if ((this.orientation == "South") && !(this.positions[this.curr_row][this.curr_col] & 2))  { this.curr_row++; }
  else if ((this.orientation == "West")  && !(this.positions[this.curr_row][this.curr_col] & 4))  { this.curr_col--; }
  else if ((this.orientation == "East")  && !(this.positions[this.curr_row][this.curr_col] & 8))  { this.curr_col++; }
  this.display(); 
}

//---------------------------------------------------------------------------
//    LABYRYNTH : TURN LEFT
//---------------------------------------------------------------------------
function LabyrinthTurnLeft() {// alert("turnLeft");
  if (this.curr_row >= this.n_rows) {
    if (this.orientation == "South") this.goForward(); //click on startMessage
    return;
  }
  else if (this.curr_row < 0)            { return; }
  else if (this.orientation == "North")  { this.orientation = "West";  }
  else if (this.orientation == "East" )  { this.orientation = "North"; }
  else if (this.orientation == "South")  { this.orientation = "East";  }
  else if (this.orientation == "West" )  { this.orientation = "South"; }
  this.display(); 
}

//---------------------------------------------------------------------------
//    LABYRYNTH : TURN RIGHT
//---------------------------------------------------------------------------
function LabyrinthTurnRight() {// alert("turnRight");
  if (this.curr_row >= this.n_rows) {
    if (this.orientation == "South") this.goForward(); //click on startMessage
    return;
  }
  else if (this.curr_row < 0)            { return; }
  else if (this.orientation == "North")  { this.orientation = "East";  }
  else if (this.orientation == "East" )  { this.orientation = "South"; }
  else if (this.orientation == "South")  { this.orientation = "West";  }
  else if (this.orientation == "West" )  { this.orientation = "North"; }
  this.display(); 
}

//***************************************************************************
//    CLASS TABLE
//---------------------------------------------------------------------------
function Table(row, col) { for (var i=0; i<row; i++)  { this[i]= new Array(col);} }

//***************************************************************************
//    CLASS LABYRINTH BUILDER
//---------------------------------------------------------------------------
function LabyrinthBuilder(to_build)
{
//-- DATA ------
   this.labyr       = to_build;
   this.n_candi     = 0;
   this.candidates  = new Table(to_build.n_rows,to_build.n_cols);
   this.row         = 0;
   this.col         = 0;
   this.rand        = new RandomNumberGenerator();        // Random number.

//-- METHODS ---
   this.buildAll    = LabyrinthBuilderBuildAll;
   this.buildRoom   = LabyrinthBuilderBuildRoom;
   this.buildHall   = LabyrinthBuilderBuildHall;
   this.pickDirect  = LabyrinthBuilderPickDirect;
   this.pickHall    = LabyrinthBuilderPickHall;
   this.isCandidate = LabyrinthBuilderIsCandidate;
   this.addCircles  = LabyrinthBuilderAddCircles;
   this.updateCandi = LabyrinthBuilderUpdateCandi;

//-- INITIALIZATION --
   for (var r=0; r<this.labyr.n_rows; r++)
   {  for (var c=0; c<this.labyr.n_rows; c++)
      {  this.labyr.positions[r][c]=15; this.candidates[r][c]=0; } }
   // All the walls are there.
//-- CONSTRUCTOR -----
   this.buildAll();
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : BUILD ALL
//---------------------------------------------------------------------------
function LabyrinthBuilderBuildAll() {
   var center_row = Math.floor( this.labyr.n_rows / 2 );
   var center_col = Math.floor( this.labyr.n_cols / 2 );
   this.candidates[center_row][center_col] = 1;
   this.n_candi = 1;

   while ( this.n_candi > 0 )
   {  this.pickHall();  this.buildHall(); }
   this.addCircles();

   var door_in  = Math.floor( this.rand.next() * this.labyr.n_rows );
   var door_out = Math.floor( this.rand.next() * this.labyr.n_rows );

   this.labyr.positions[this.labyr.n_rows-1][door_in]  &= 13;
   this.labyr.positions[0]                  [door_out] &= 14;
   this.labyr.positions[this.labyr.n_rows-1][door_in]  |= 32;
   this.labyr.positions[0]                  [door_out] |= 16;
   this.labyr.start_row = this.labyr.n_rows;
   this.labyr.start_col = door_in;
   this.labyr.curr_row = this.labyr.n_rows;
   this.labyr.curr_col = door_in;
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : ADD CIRCLES
//---------------------------------------------------------------------------
function LabyrinthBuilderAddCircles() {
   var direct = new Array(4);
   var num_dir = 0;
   for (var n = this.labyr.n_circles; n > 0; n--)
   {
      this.row = Math.floor( this.rand.next() * this.labyr.n_rows );
      this.col = Math.floor( this.rand.next() * this.labyr.n_cols );
      num_dir = 0;
      if ( (this.row-1 >= 0) &&
           (this.labyr.positions[this.row][this.col] & 1) )  // Wall North?
      {  direct[num_dir] = "North";  num_dir++; }
      if ( (this.row+1 < this.labyr.n_rows) &&
           (this.labyr.positions[this.row][this.col] & 2) )  // Wall South?
      {  direct[num_dir] = "South";  num_dir++; }
      if ( (this.col-1 >= 0) &&
           (this.labyr.positions[this.row][this.col] & 4) )  // Wall West?
      {  direct[num_dir] = "West";   num_dir++; }
      if ( (this.col+1 < this.labyr.n_cols) &&
           (this.labyr.positions[this.row][this.col] & 8) )  // Wall East?
      {  direct[num_dir] = "East";   num_dir++; }
      if (num_dir == 0) { n++; continue; }
      var pick = Math.floor( this.rand.next() * num_dir );
      this.buildRoom(direct[pick]);
   }
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : BUILD HALL
//---------------------------------------------------------------------------
function LabyrinthBuilderBuildHall() {
   var dir_val = "";
   for (var i=0; i<this.labyr.hall_length; i++)
   {  if (this.buildRoom(this.pickDirect()) == "DeadEnd") { break; }
      this.updateCandi();
   }
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : BUILD ROOM
//---------------------------------------------------------------------------
// Returns direction if successful, Returns "DeadEnd" if fails.
//   Note: Direction points to an empty room.
function LabyrinthBuilderBuildRoom(direction) {
   if ( direction == "North" )
   {  this.labyr.positions[this.row--][this.col] &= 14;
      this.labyr.positions[this.row  ][this.col] &= 13; }
   else if ( direction == "South" )
   {  this.labyr.positions[this.row++][this.col] &= 13;
      this.labyr.positions[this.row  ][this.col] &= 14; }
   else if ( direction == "West" )
   {  this.labyr.positions[this.row][this.col--] &= 11;
      this.labyr.positions[this.row][this.col  ] &= 7;  }
   else if ( direction == "East" )
   {  this.labyr.positions[this.row][this.col++] &= 7;
      this.labyr.positions[this.row][this.col  ] &= 11; }
   else { return("DeadEnd"); }   // --> DeadEnd

   return(direction);
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : UPDATE CANDIDATES
//---------------------------------------------------------------------------
function LabyrinthBuilderUpdateCandi() {
  // Before constructing a new room, that room is closed (except for circles)
  //   All the non-closed adjacent positions were candidates.
  //   -> Substract that number and add the new number of candidates.

   if ((this.candidates[this.row][this.col] = this.isCandidate(this.row, this.col)) == 1)
   {  this.n_candi++; }

   if (this.row+1 < this.labyr.n_rows)
   {  if (this.labyr.positions[this.row+1][this.col] != 15) 
      {  this.n_candi--; }
      if ((this.candidates[this.row+1][this.col] = this.isCandidate(this.row+1, this.col)) == 1)
      {  this.n_candi++; }
   }
   if (this.row-1 >= 0)
   {  if (this.labyr.positions[this.row-1][this.col] != 15) 
      {  this.n_candi--; }
      if ((this.candidates[this.row-1][this.col] = this.isCandidate(this.row-1, this.col)) == 1)
      {  this.n_candi++; }
   }
   if (this.col+1 < this.labyr.n_cols)
   {  if (this.labyr.positions[this.row][this.col+1] != 15) 
      {  this.n_candi--; }
      if ((this.candidates[this.row][this.col+1] = this.isCandidate(this.row, this.col+1)) == 1)
      {  this.n_candi++; }
   }
   if (this.col-1 >= 0)
   {  if (this.labyr.positions[this.row][this.col-1] != 15) 
      {  this.n_candi--; }
      if ((this.candidates[this.row][this.col-1] = this.isCandidate(this.row, this.col-1)) == 1)
      {  this.n_candi++; }
   }
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : IS CANDIDATE ???
// Candidate if it's not closed and has a closed adjacent room
//---------------------------------------------------------------------------
function LabyrinthBuilderIsCandidate(r,c) {
   if (  (r >= 0) && (c >= 0) && (r < this.labyr.n_rows) && (c < this.labyr.n_cols)
      && (this.labyr.positions[r][c] != 15)
      && (  ((r+1 < this.labyr.n_rows) && (this.labyr.positions[r+1][c]==15)) ||
            ((r-1 >= 0)                && (this.labyr.positions[r-1][c]==15)) ||
            ((c+1 < this.labyr.n_cols) && (this.labyr.positions[r][c+1]==15)) ||
            ((c-1 >= 0)                && (this.labyr.positions[r][c-1]==15))    ) 
      )
   {  return(1); }
   else
   {  return(0); }
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : PICK DIRECTION
//---------------------------------------------------------------------------
function LabyrinthBuilderPickDirect() {
   var direction = new Array(4);
   var n_dir = 0;

   if ( (this.row-1 >= 0) &&
        (this.labyr.positions[this.row-1][this.col]==15) )
   {  direction[n_dir] = "North";  n_dir++; }

   if ( (this.row+1 < this.labyr.n_rows) &&
        (this.labyr.positions[this.row+1][this.col]==15) )
   {  direction[n_dir] = "South";  n_dir++; }

   if ( (this.col-1 >= 0) &&
        (this.labyr.positions[this.row][this.col-1]==15) )
   {  direction[n_dir] = "West";   n_dir++; }

   if ( (this.col+1 < this.labyr.n_cols) &&
        (this.labyr.positions[this.row][this.col+1]==15) )
   {  direction[n_dir] = "East";   n_dir++; }

   if (n_dir == 0) { return("DeadEnd"); }

   var pick = Math.floor( this.rand.next() * n_dir );
   return(direction[pick]);
}

//---------------------------------------------------------------------------
//    LABYRYNTH BUILDER : PICK HALL
//---------------------------------------------------------------------------
function LabyrinthBuilderPickHall() {
   var pick = Math.ceil ( this.rand.next() * this.n_candi )
   for (var r=0; r<this.labyr.n_rows; r++)
   {  for (var c=0; c<this.labyr.n_cols; c++)
      { if (1 == this.candidates[r][c])  { pick--; }
        if (0 == pick)  { this.row=r;  this.col=c;  break;}
      }
      if (0 == pick) { break; }
   }
   if (r == this.labyr.n_rows) { return("fail"); }
   return("success");
}

//***************************************************************************
//    CLASS : RANDOM NUMBER GENERATOR
//---------------------------------------------------------------------------
function NextRandomNumber() {
  var hi   = this.seed / this.Q;
  var lo   = this.seed % this.Q;
  var test = this.A * lo - this.R * hi;
  if (test > 0)
    this.seed = test;
  else
    this.seed = test + this.M;
  return (this.seed * this.oneOverM);
}
function RandomNumberGenerator() {
  var d = new Date();
  this.seed = 2345678901 + (d.getSeconds() * 0xFFFFFF) + (d.getMinutes() * 0xFFFF);
  this.A = 48271;
  this.M = 2147483647;
  this.Q = this.M / this.A;
  this.R = this.M % this.A;
  this.oneOverM = 1.0 / this.M;
  this.next = NextRandomNumber;
  return this;
}


