/***********************************************************************************************************
 * su.bot.checkers.javascript.bot.Smart
 * Location: http://www.bot.su/library/su/bot/checkers/javascript/bot/Smart.js
 * Index Version Location: http://www.bot.su/library/su/bot/checkers/javascript/bot/smart/index.html
 * © Bot.Su (http://www.bot.su/) 
***********************************************************************************************************/

if (typeof su == "undefined") {su = {};};
if (typeof su.bot == "undefined") {su.bot = {};};
if (typeof su.bot.checkers == "undefined") {su.bot.checkers = {};};
if (typeof su.bot.checkers.javascript == "undefined") {su.bot.checkers.javascript = {};};
if (typeof su.bot.checkers.javascript.bot == "undefined") {su.bot.checkers.javascript.bot = {};};

if (typeof su.bot.checkers.javascript.bot.Smart == "undefined") {
 su.bot.checkers.javascript.bot.Smart = function() {}; 
 su.bot.checkers.javascript.bot.Smart.prototype = new su.bot.checkers.javascript.Gamer();

 su.bot.checkers.javascript.bot.Smart.prototype.className = "Smart"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classNamespace = "su.bot.checkers.javascript.bot.Smart"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classCreated = "20070523"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classCreator = "http://www.bot.su/"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classLocation = "http://www.bot.su/library/su/bot/checkers/javascript/bot/Smart.js"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classIndexLocation = "http://www.bot.su/library/su/bot/checkers/javascript/bot/smart/index.html"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classVersion = "20070528"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classVersionLocation = "http://www.bot.su/library/su/bot/checkers/javascript/bot/smart/builds/20070528/Smart.js"; 
 su.bot.checkers.javascript.bot.Smart.prototype.classVersionIndexLocation = "http://www.bot.su/library/su/bot/checkers/javascript/bot/smart/index.html";
 
 su.bot.checkers.javascript.bot.Smart.prototype.bestNode = null; 
  su.bot.checkers.javascript.bot.Smart.prototype.getBestNode = function () {return this.bestNode;};
  su.bot.checkers.javascript.bot.Smart.prototype.setBestNode = function (bestNode) {this.bestNode = bestNode;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.choosingBestNode = false;
  su.bot.checkers.javascript.bot.Smart.prototype.getChoosingBestNode = function () {return this.choosingBestNode;};
  su.bot.checkers.javascript.bot.Smart.prototype.setChoosingBestNode = function (choosingBestNode) {this.choosingBestNode = choosingBestNode;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.choosingNode = false;
  su.bot.checkers.javascript.bot.Smart.prototype.getChoosingNode = function () {return this.choosingNode;};
  su.bot.checkers.javascript.bot.Smart.prototype.setChoosingNode = function (choosingNode) {this.choosingtNode = choosingNode;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.creatingLegalNodes = false;
  su.bot.checkers.javascript.bot.Smart.prototype.getCreatingLegalNodes = function () {return this.creatingLegalNodes;};
  su.bot.checkers.javascript.bot.Smart.prototype.setCreatingLegalNodes = function (creatingLegalNodes) {this.creatingLegalNodes = creatingLegalNodes;};
 su.bot.checkers.javascript.bot.Smart.prototype.environment;
  su.bot.checkers.javascript.bot.Smart.prototype.getEnvironment = function () {return this.environment;};
  su.bot.checkers.javascript.bot.Smart.prototype.setEnvironment = function (environment) {this.environment = environment;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.messageFromReferee = false;
  su.bot.checkers.javascript.bot.Smart.prototype.getMessageFromReferee = function () {return this.messageFromReferee;};
  su.bot.checkers.javascript.bot.Smart.prototype.setMessageFromReferee = function (messageFromReferee) {this.messageFromReferee = messageFromReferee;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.mustDoMoveDate = new Date();
  su.bot.checkers.javascript.bot.Smart.prototype.getMustDoMoveDate = function () {return this.mustDoMoveDate;};
  su.bot.checkers.javascript.bot.Smart.prototype.setMustDoMoveDate = function (mustDoMoveDate) {this.mustDoMoveDate = mustDoMoveDate;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.nodeForProcess = null;
  su.bot.checkers.javascript.bot.Smart.prototype.getNodeForProcess = function () {return this.nodeForProcess;};
  su.bot.checkers.javascript.bot.Smart.prototype.setNodeForProcess = function (nodeForProcess) {this.nodeForProcess = nodeForProcess;}; 
 su.bot.checkers.javascript.bot.Smart.prototype.startMoveTime = null;
  su.bot.checkers.javascript.bot.Smart.prototype.getStartMoveTime = function () {return this.startMoveTime;};
  su.bot.checkers.javascript.bot.Smart.prototype.setStartMoveTime = function (startMoveTime) {this.startMoveTime = startMoveTime;}; 
  
 su.bot.checkers.javascript.bot.Smart.prototype.calculateNumericalSuperiority = function(node) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.calculateNumericalSuperiority is runing...");};
  if(node == null || node.nodes.length == 0) {return;};
  var daughterAnticipatedNumericalSuperiority = node.nodes[0].anticipatedNumericalSuperiority;
  var anticipatedNumericalSuperiority = node.nodes[0].move.taked ? 1 : 0;
  if(node.whoseMove == node.nodes[0].whoseMove) {
   for(var i = 1; i < node.nodes.length; i++) {
    daughterAnticipatedNumericalSuperiority = Math.max(daughterAnticipatedNumericalSuperiority, node.nodes[i].anticipatedNumericalSuperiority);
   };
   anticipatedNumericalSuperiority += daughterAnticipatedNumericalSuperiority;
  } else {
   for(var i = 1; i < node.nodes.length; i++) {
    daughterAnticipatedNumericalSuperiority = Math.min(daughterAnticipatedNumericalSuperiority, node.nodes[i].anticipatedNumericalSuperiority);
   };
   anticipatedNumericalSuperiority -= daughterAnticipatedNumericalSuperiority;
  };
  node.anticipatedNumericalSuperiority = anticipatedNumericalSuperiority;
  var probabilityNumericalSuperiority = 0.5;
  if(anticipatedNumericalSuperiority > 0) {
   probabilityNumericalSuperiority = 1;
  } else if(anticipatedNumericalSuperiority < 0) {
   probabilityNumericalSuperiority = 0;
  } else {
   var sumProbabilityNumericalSuperiority = node.nodes[0].probabilityNumericalSuperiority;
   for(var i = 1; i < node.nodes.length; i++) {sumProbabilityNumericalSuperiority += node.nodes[i].probabilityNumericalSuperiority;};
   probabilityNumericalSuperiority = (node.whoseMove == node.nodes[0].whoseMove) ? sumProbabilityNumericalSuperiority/node.nodes.length : (1 - sumProbabilityNumericalSuperiority/node.nodes.length);
  };
  node.probabilityNumericalSuperiority = probabilityNumericalSuperiority;
  if(node.parentNode == null) {return;} else {this.calculateNumericalSuperiority(node.parentNode);};
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.calculateProbabilityWinning = function(node) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.calculateProbabilityWinning is runing...");};
  if(node.nodes.length == 0) {
   node.probabilityWinningRandom = 0 + node.probabilityWinningProper; node.probabilityWinningSmart = 0 + node.probabilityWinningProper; 
  } else if(node.nodes.length == 1) {
   node.probabilityWinningSmart = 0 + ((node.whoseMove == node.nodes[0].whoseMove) ? node.nodes[0].probabilityWinningSmart : (1 - node.nodes[0].probabilityWinningSmart)); 
   node.probabilityWinningRandom = 0 + node.probabilityWinningSmart; 
  } else {
   var maxProbabilityWinningSmart = 0.5, minProbabilityWinningSmart = 0.5;
   var allMax = true, allMin = true;
   for(var i = 0; i < node.nodes.length; i++) {
    if(node.nodes[i].probabilityWinningSmart > maxProbabilityWinningSmart) {maxProbabilityWinningSmart = 0 + node.nodes[i].probabilityWinningSmart;};
    if(node.nodes[i].probabilityWinningSmart < minProbabilityWinningSmart) {minProbabilityWinningSmart = 0 + node.nodes[i].probabilityWinningSmart;};
	if(allMax && node.nodes[i].probabilityWinningSmart != 1) {allMax = false;};
	if(allMin && node.nodes[i].probabilityWinningSmart != 0) {allMin = false;};
   };
   if(allMax || allMin) {
    node.probabilityWinningSmart =  0 + ((node.whoseMove == node.nodes[0].whoseMove) ? node.nodes[0].probabilityWinningSmart : (1 - node.nodes[0].probabilityWinningSmart));
    node.probabilityWinningRandom = 0 + node.probabilityWinningSmart;
   } else if((node.whoseMove == node.nodes[0].whoseMove && maxProbabilityWinningSmart == 1) || (node.whoseMove != node.nodes[0].whoseMove && minProbabilityWinningSmart == 0)) {
    node.probabilityWinningSmart = 1;     
    if(this.name == node.whoseMove) {
     var newNodes = new Array(); var f = false;
     for(var i = 0; i < node.nodes.length && !f; i++) {
      if( (node.whoseMove == node.nodes[i].whoseMove && node.nodes[i].probabilityWinningSmart == 1) 
         || (node.whoseMove != node.nodes[i].whoseMove && node.nodes[i].probabilityWinningSmart == 0) ) {
       newNodes[0] = node.nodes[i]; f = true;
      };
     };
     node.nodes = newNodes;  
    };
   } else {
    node.probabilityWinningSmart = 0.5;
   };
   if(!allMax && !allMin) {
    var sumProbabilityWinningRandom = 0;
    for(var i = 0; i < node.nodes.length; i++) {
     sumProbabilityWinningRandom += (node.nodes[i].probabilityWinningSmart == 0 || node.nodes[i].probabilityWinningSmart == 1) ? node.nodes[i].probabilityWinningSmart : node.nodes[i].probabilityWinningRandom;
    };
    var avgProbabilityWinningRandom = sumProbabilityWinningRandom/node.nodes.length;
    node.probabilityWinningRandom = 0 + ((node.whoseMove == node.nodes[0].whoseMove) ? avgProbabilityWinningRandom : (1 - avgProbabilityWinningRandom));
   };
  };
  if(node.parentNode == null) {return;} else {this.calculateProbabilityWinning(node.parentNode);};
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.changeCurrentNode = function(currentNode) {
  if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.changeCurrentNode is runing for currentNode="+currentNode);};
  var finded = false;
  if(this.getCurrentNode() != null && this.getCurrentNode().getMove() != null && this.getCurrentNode().similarTo(currentNode)) {
   finded = true;
  } else if(this.getCurrentNode() != null  && this.getCurrentNode().getProcessed()) {
   var nodes = this.getCurrentNode().getNodes();
   for(var i = 0; (i<nodes.length)&&(!finded); i++) {
    nodes[i].setDebugging(this.getDebugging()); nodes[i].setTracing(this.getTracing()); nodes[i].setLog(this.getLog());
    if(nodes[i].similarTo(currentNode)) {
     nodes[i].setParentNode(null);
     var move = nodes[i].getMove();
     this.setCurrentNode(nodes[i]);
     finded = true;
	};
   };
  };
  if(!finded) {
   var node = currentNode.getFullCopy(currentNode);
   node.parentNode = null;
   this.currentNode = node;
  };
 }; 
  
 su.bot.checkers.javascript.bot.Smart.prototype.chooseBestNode = function() {
  if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.chooseBestNode is runing...");};
  this.setChoosingBestNode(true);
  if(this.getBestNode() != null) {this.setChoosingBestNode(false); return;};
  if(!this.getCurrentNode().getProcessed() || this.getCurrentNode().getNodes().length == 0) {
   this.setBestNode(null);
   this.setChoosingBestNode(false);
  };
  var nodes = this.getCurrentNode().getNodes();
  if(nodes.length == 1) {
   this.setBestNode(nodes[0]);
  } else {
   nodes = this.selectBestNodes(nodes);
   var r = Math.floor(Math.random()*nodes.length);
   this.setBestNode(nodes[r]);
  };
  this.setChoosingBestNode(false);
 }; 
  
 su.bot.checkers.javascript.bot.Smart.prototype.chooseNode = function() {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.chooseNode is runing...");};
  this.setChoosingNode(true);
  if(this.getCurrentNode() != null) {
   if(!this.getCurrentNode().getProcessed()) {
    this.setNodeForProcess(this.getCurrentNode());
   } else {
    this.setNodeForProcess(this.chooseNodeFromNodes(this.getCurrentNode().getNodes()));
   };
  };
  this.setChoosingNode(false);
 }; 
  
 su.bot.checkers.javascript.bot.Smart.prototype.chooseNodeFromNodes = function(nodes) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.chooseNodeFromNodes is runing...");};
  var nodesArray = new Array();
  for(var i = 0; i < nodes.length; i++) {nodesArray[i] = nodes[i];};
  for(var i = 0; i < nodesArray.length; i++) {
   if(!nodesArray[i].getProcessed()) {
    return nodesArray[i];
   } else {
    var childNodes = nodesArray[i].getNodes();
    for(var j = 0; j < childNodes.length; j++) {nodesArray[nodesArray.length] = childNodes[j];};
   };
  };
 }; 
 
 su.bot.checkers.javascript.bot.Smart.prototype.createLegalNodes = function(node) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.createLegalNodes runing....");};
  this.setCreatingLegalNodes(true);
  if(!node.processed) {
   var checkersLocation = node.board.getCheckersLocation(node.whoseMove);
   if(checkersLocation.length == 0) {
    node.probabilityWinningProper = 0;
    node.hasNode = false;
   } else {
	this.createLegalNodesForTake(node, checkersLocation);
    if(node.nodes.length == 0) {this.createLegalNodesForMove(node, checkersLocation);};
    //if(nodes.length == 0) {
    if(node.nodes.length == 0) {
     node.probabilityWinningProper = 0;
     node.hasNode = false;
	};
   }; 
   this.calculateProbabilityWinning(node);
   node.setProcessed(true);
  };
  this.setCreatingLegalNodes(false);
 };
 
 su.bot.checkers.javascript.bot.Smart.prototype.createLegalNodesForMove = function(node, checkersLocation) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.createLegalNodesForMove is runing for node="+node);};
  var nodes = new Array();
  var board = node.getBoard();
  for(var i = 0; i < checkersLocation.length; i++) {
   var fromSquare = checkersLocation[i];
   var fromI = fromSquare.i; var fromJ = fromSquare.j;
   var checker = node.getBoard().getChecker(fromI, fromJ);
   var toWhoseMove = (node.getWhoseMove() == "min") ? "max" : "min";
   var moves = checker.isChecker() ? this.getLegalMovesForChecker(node, fromSquare) : this.getLegalMovesForKing(node, fromSquare);
   for(var j = 0; j < moves.length; j++) {
    var toNode = new su.bot.checkers.javascript.Node();
	toNode.setMove(moves[j]);
	toNode.setParentNode(node);
	toNode.setWhoseMove(toWhoseMove);
	var toBoard = board.getCopy();
	toBoard.move(moves[j]);
	toNode.setBoard(toBoard);
    nodes[nodes.length] = toNode;
   };
  };
  node.nodes = nodes;
 };
 
 su.bot.checkers.javascript.bot.Smart.prototype.createLegalNodesForTake = function(node, checkersLocation) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.createLegalNodesForTake is runing...");}; 
  var nodes = new Array();
  var whoseMove = node.whoseMove;
  var board = node.board;
  var maxDepthTake = 0;
  for(var i = 0; i < checkersLocation.length; i++) {
   var fromSquare = checkersLocation[i];
   var fromI = fromSquare.i; var fromJ = fromSquare.j;
   var checker = board.getChecker(fromI, fromJ);
   var moves = checker.isChecker() ? this.getLegalTakesForChecker(node, fromSquare) : this.getLegalTakesForKing(node, fromSquare);
   for(var j = 0; j < moves.length; j++) {
    var toNode = new su.bot.checkers.javascript.Node();
	toNode.setMove(moves[j]);
	toNode.setParentNode(node);
	toNode.setWhoseMove(whoseMove);
	var toBoard = board.getCopy();
	toBoard.move(moves[j]);
	toNode.setBoard(toBoard);
	var cL = new Array();
	cL[0] = moves[j].to;
	this.createLegalNodesForTake(toNode, cL);
    //if(nodesArray.length == 0) {
    if(toNode.nodes.length == 0) {
     toNode.setWhoseMove((whoseMove == "min") ? "max" : "min");
	 this.createLegalNodes(toNode);
	} else {
	 var toDepthTake = toNode.nodes[0].getMaxDepthTake()+1;
     toNode.setMaxDepthTake(toDepthTake);
	 toNode.setProcessed(true);
	 if(toDepthTake > maxDepthTake) {maxDepthTake = toDepthTake;};
	};
    nodes[nodes.length] = toNode;
   };
  };
  if(maxDepthTake != 0) {
   var selectedNodes = new Array();   
   for(var i = 0; i < nodes.length; i++) {if(nodes[i].getMaxDepthTake() == maxDepthTake) {selectedNodes[selectedNodes.length] = nodes[i];};};
   nodes = selectedNodes;
  };
  node.nodes = nodes;
  if(nodes.length > 0) {this.calculateNumericalSuperiority(node);};
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.doMove = function() {
  if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.doMove is runing...");};
  this.setMessageFromReferee(true);
  this.setStartMoveTime(new Date());
  this.changeCurrentNode(this.getEnvironment().getReferee().getLastNode());
  this.mustDoMoveDate = new Date();
  this.setMessageFromReferee(false);
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.getLegalMovesForChecker = function(node, fromSquare) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.getLegalMovesForChecker is runing...");};
  var moves = new Array();
  var board = node.getBoard();
  var fromI = fromSquare.i;
  var properties = this.environment.properties;
  var whoseTopPosition = properties.whoseTopPosition;
  var toI = (node.whoseMove == whoseTopPosition) ? fromI+1 : fromI-1;
  if(board.containI(toI)) {
   var fromJ = fromSquare.j;
   for(var toJ = fromJ-1; toJ < fromJ+2; toJ = toJ+2) {
    if(board.containJ(toJ)) {
     if(board.getChecker(toI, toJ).isEmpty()) {
      var toSquare = new su.bot.checkers.javascript.Square();
      toSquare.i = toI; toSquare.j = toJ;
      var move = new su.bot.checkers.javascript.Move();
      move.from = fromSquare; move.to = toSquare; move.checker = board.getChecker(fromI, fromJ).clone();
      if( ( (toI == (properties.getNumberSquaresVertical()-1)) && (node.whoseMove == whoseTopPosition) ) || ( (toI == 0) && (node.whoseMove != whoseTopPosition) )) {
        move.setComeKing(true);
      };
	  moves[moves.length] = move;
     };
    };
   };
  };
  return moves;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.getLegalMovesForKing = function(node, fromSquare) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.getLegalMovesForKing is runing...");};
  var moves = new Array();
  var board = node.getBoard();
  var fromI = fromSquare.i; var fromJ = fromSquare.j;
  var kingMoveLength = this.getEnvironment().getProperties().getKingMoveLength();
  for(var offset=1; offset < kingMoveLength; offset=offset+1) {
   for(var offsetI=-1*offset; offsetI < offset*2; offsetI += offset*2) {
    for(var offsetJ=-1*offset; offsetJ < offset*2; offsetJ += offset*2) {
     var toI = fromI+offsetI; var toJ = fromJ+offsetJ;
     var toSquare = new su.bot.checkers.javascript.Square();
     toSquare.i = toI; toSquare.j = toJ; 
     if(board.isFree(fromSquare, toSquare)) {
	  var move = new su.bot.checkers.javascript.Move();
      move.from = fromSquare; move.to = toSquare; move.checker = board.getChecker(fromI, fromJ).clone();
	  moves[moves.length] = move;
	 };
	};
   };
  };
  return moves;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.getLegalTakesForChecker = function(node, fromSquare) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.getLegalTakesForChecker is runing for fromSquare="+fromSquare.getId());};
  var moves = new Array();
  var fromI = fromSquare.getI(); var fromJ = fromSquare.getJ();
  var board = node.getBoard();
  var firstOffsetI = 1;
  var properties = this.environment.getProperties();
  var whoseTopPosition = properties.getWhoseTopPosition();
  if(properties.getTakeBack()) {firstOffsetI = -1;};
  for(var offsetI = firstOffsetI; offsetI < 2; offsetI = offsetI+2) {
   var toI;
   if(node.getWhoseMove() == whoseTopPosition) {
    takeI = fromI+offsetI;
    toI = fromI+2*offsetI;
   } else {
    takeI = fromI-offsetI;
    toI = fromI-2*offsetI; 
   };
   if(board.containI(takeI) && board.containI(toI)) {
    for(var offsetJ = -1; offsetJ < 2; offsetJ = offsetJ+2) {
     var takeJ = fromJ+offsetJ;
     var toJ = fromJ+2*offsetJ;
     if(board.containJ(takeJ) && board.containJ(toJ)) {
      if(board.getChecker(toI, toJ).isEmpty() 
         && !board.getChecker(takeI, takeJ).isEmpty()
         && board.getChecker(takeI, takeJ).getOwner() != board.getChecker(fromI, fromJ).getOwner()) {
       var toSquare = new su.bot.checkers.javascript.Square();
	   toSquare.setI(toI); toSquare.setJ(toJ);
       var takeSquare = new su.bot.checkers.javascript.Square();
	   takeSquare.setI(takeI); takeSquare.setJ(takeJ);
	   var move = new su.bot.checkers.javascript.Move();
	   move.setChecker(board.getChecker(fromI, fromJ).clone()); move.setTakedChecker(board.getChecker(takeI, takeJ).clone());
	   move.setFrom(fromSquare); move.setTake(takeSquare); move.setTo(toSquare); 
	   if( ( (toI == (this.getEnvironment().getProperties().getNumberSquaresVertical()-1)) && (node.getWhoseMove() == this.getEnvironment().getProperties().getWhoseTopPosition()) )
          || ( (toI == 0) && (node.getWhoseMove() != this.getEnvironment().getProperties().getWhoseTopPosition()) )) {
        move.setComeKing(true);
	   };
	   moves[moves.length] = move;
      };
     };
    };
   };
  };
  return moves;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.getLegalTakesForKing = function(node, fromSquare) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.getLegalTakesForKing is runing...");};
  var moves = new Array();
  var fromI = fromSquare.getI(); var fromJ = fromSquare.getJ();
  if(!node) {node = this.getLastNode();};
  var board = node.getBoard();
  var kingMoveLength = this.getEnvironment().getProperties().getKingMoveLength();
  for(var offsetI = -1; offsetI <= 1; offsetI=offsetI+2) {
   for(var offsetJ = -1; offsetJ <= 1; offsetJ=offsetJ+2) {
    var takeI = fromI+offsetI; var takeJ = fromJ+offsetJ;
	var i;
	for(i = 2; board.containI(takeI) && board.containJ(takeJ) && board.getChecker(takeI, takeJ).isEmpty() && (Math.abs(i*offsetI) <= kingMoveLength) && (Math.abs(i*offsetJ) <= kingMoveLength); i++) {
     takeI = fromI + i*offsetI; takeJ = fromJ + i*offsetJ;
	};
	if(board.containI(takeI) && board.containJ(takeJ) 
	   && (Math.abs(i*offsetI) <= kingMoveLength) && (Math.abs(i*offsetJ) <= kingMoveLength)
	   && board.getChecker(takeI, takeJ).getOwner() != board.getChecker(fromI, fromJ).getOwner()) {
	 var toI = takeI+offsetI; var toJ = takeJ+offsetJ;
	 for(var j = 1; board.containI(toI) && board.containJ(toJ) && board.getChecker(toI, toJ).isEmpty(); j++) {
      var toSquare = new su.bot.checkers.javascript.Square();
      toSquare.setI(toI); toSquare.setJ(toJ);
      var takeSquare = new su.bot.checkers.javascript.Square();
      takeSquare.setI(takeI); takeSquare.setJ(takeJ);
      var move = new su.bot.checkers.javascript.Move();
      move.setChecker(board.getChecker(fromI, fromJ).clone()); move.setTakedChecker(board.getChecker(takeI, takeJ).clone());
      move.setFrom(fromSquare); move.setTake(takeSquare); move.setTo(toSquare); 
      moves[moves.length] = move;
      toI = takeI+(j+1)*offsetI; toJ = takeJ+(j+1)*offsetJ;	  
	 };
	}
   };
  };
  return moves;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.manager = function() {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.manager is runing...");};
  if(this.runing && this.currentNode != null && !this.messageFromReferee) {
   var environment = this.environment;
   var referee = environment.referee;
   var properties = environment.properties;
   if(referee.whoseMove == this.name && this.currentNode.processed && this.currentNode.daughterProcessed() && !this.choosingBestNode
	  && ((this.currentNode.nodes.length < 2) || ( (this.startMoveTime != null) && (((new Date()).getTime() - this.startMoveTime) >= properties.timeForMove) ))) { 
    if(this.currentNode.nodes.length > 0) {
      this.chooseBestNode();
      referee.doMove(this.name, this.bestNode.move);
      this.changeCurrentNode(referee.lastNode);
	  this.bestNode = null;
	  this.startMoveTime = null;
    } else {
     this.end();
     this.bestNode = null;
     referee.surrender(this.name);
	 this.startMoveTime = null;
	 return;
    };
   } else {
    if(this.nodeForProcess != null && !this.creatingLegalNodes) {
     this.createLegalNodes(this.nodeForProcess);
     this.nodeForProcess = null;
    } else if(!this.choosingNode) {
     this.chooseNode();
    };
   };
  };
  if(this.getRuning()) {
   var the = this; this.setRunTimer(setTimeout(function(){the.manager();}, 100));//
  } else {
   try {clearTimeout(this.getRunTimer())} catch (e) {};
  };
 }; 
  
 su.bot.checkers.javascript.bot.Smart.prototype.run = function() {
  if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.run is runing...");};
  if(!this.getRuning()) {
   this.setRuning(true);
   this.manager();
  };
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodes = function(nodesArray) {
  if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes is runing...");};
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes nodesArray.length = "+nodesArray.length);};
  var selectedNodes = this.selectBestNodesForDepthTake(nodesArray);
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes selectedNodes.length (DepthTake) = "+selectedNodes.length);};
  selectedNodes = this.selectBestNodesForWinningSmart(selectedNodes);
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes selectedNodes.length (ForWinningSmart) = "+selectedNodes.length);};
  selectedNodes = this.selectBestNodesForAnticipatedNumericalSuperiority(selectedNodes);
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes selectedNodes.length (ForAnticipatedNumericalSuperiority) = "+selectedNodes.length);};
  selectedNodes = this.selectBestNodesForKingProper(selectedNodes);
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes selectedNodes.length (ForKingProper) = "+selectedNodes.length);};
  selectedNodes = this.selectBestNodesForWinningRandom(selectedNodes);
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes selectedNodes.length (ForWinningRandom) = "+selectedNodes.length);};
  selectedNodes = this.selectBestNodesForProbabilityNumericalSuperiority(selectedNodes);
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodes selectedNodes.length (ForProbabilityNumericalSuperiority) = "+selectedNodes.length);};
  return selectedNodes;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodesForDepthTake = function(nodesArray) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForDepthTake is runing...");};
  if(nodesArray.length < 2) {return nodesArray;};
  var selectedNodes = new Array();
  var depthTake = 0;
  for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].getMaxDepthTake() > depthTake) {depthTake = nodesArray[i].getMaxDepthTake();};};
  if(status == 0) {return nodesArray;};
  for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].getMaxDepthTake() == depthTake) {selectedNodes[selectedNodes.length] = nodesArray[i];};};
  return selectedNodes;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodesForKingProper = function(nodesArray) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForKingProper is runing...");};
  if(nodesArray.length < 2) {return nodesArray;};
  var selectedNodes = new Array(); 
  for(var i = 1; i < nodesArray.length; i++) {if(nodesArray[i].move.comeKing) {selectedNodes[selectedNodes.length] = nodesArray[i];};};
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForKingProper selectedNodes.length="+selectedNodes.length);};
  return (selectedNodes.length > 0) ? selectedNodes : nodesArray;
 };
 
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodesForAnticipatedNumericalSuperiority = function(nodesArray) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForAnticipatedNumericalSuperiority is runing...");};
  if(nodesArray.length < 2) {return nodesArray;};
  var selectedNodes = new Array(); 
  var anticipatedNumericalSuperiority = nodesArray[0].anticipatedNumericalSuperiority;
  if(this.name == nodesArray[0].whoseMove) {
   for(var i = 1; i < nodesArray.length; i++) {anticipatedNumericalSuperiority = Math.max(anticipatedNumericalSuperiority, nodesArray[i].anticipatedNumericalSuperiority);};
  } else {
   for(var i = 1; i < nodesArray.length; i++) {anticipatedNumericalSuperiority = Math.min(anticipatedNumericalSuperiority, nodesArray[i].anticipatedNumericalSuperiority);};
  };
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForAnticipatedNumericalSuperiority anticipatedNumericalSuperiority="+anticipatedNumericalSuperiority);};
  for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].anticipatedNumericalSuperiority == anticipatedNumericalSuperiority) {selectedNodes[selectedNodes.length] = nodesArray[i];};}
  return selectedNodes;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodesForProbabilityNumericalSuperiority = function(nodesArray) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForProbabilityNumericalSuperiority is runing...");};
  if(nodesArray.length < 2) {return nodesArray;};
  var selectedNodes = new Array(); 
  var sumProbabilityNumericalSuperiority = nodesArray[0].probabilityNumericalSuperiority; 
  for(var i = 1; i < nodesArray.length; i++) {sumProbabilityNumericalSuperiority += nodesArray[i].probabilityNumericalSuperiority;};
  var avgProbabilityNumericalSuperiority = sumProbabilityNumericalSuperiority/nodesArray.length;
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForProbabilityNumericalSuperiority avgProbabilityNumericalSuperiority="+avgProbabilityNumericalSuperiority);};
  if(this.name == nodesArray[0].whoseMove) {
   for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].probabilityNumericalSuperiority >= avgProbabilityNumericalSuperiority) {selectedNodes[selectedNodes.length] = nodesArray[i];};};
  } else {
   for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].probabilityNumericalSuperiority <= avgProbabilityNumericalSuperiority) {selectedNodes[selectedNodes.length] = nodesArray[i];};}
  };
  return (selectedNodes.length > 0) ? selectedNodes : nodesArray;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodesForWinningRandom = function(nodesArray) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningRandom is runing...");};
  if(nodesArray.length < 2) {return nodesArray;};
  var selectedNodes = new Array();
  var sumWinningRandom = 0 + nodesArray[0].probabilityWinningRandom;
  for(var i = 1; i < nodesArray.length; i++) {sumWinningRandom += nodesArray[i].probabilityWinningRandom;};
  var avgWinningRandom = sumWinningRandom/nodesArray.length;
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningRandom avgWinningRandom="+avgWinningRandom);};
  if(this.name == nodesArray[0].whoseMove) {
   for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].probabilityWinningRandom >= avgWinningRandom) {selectedNodes[selectedNodes.length] = nodesArray[i];};};
  } else {
   for(var i = 0; i < nodesArray.length; i++) {if(nodesArray[i].probabilityWinningRandom <= avgWinningRandom) {selectedNodes[selectedNodes.length] = nodesArray[i];};}
  };   
  return (selectedNodes.length > 0) ? selectedNodes : nodesArray;
 };
  
 su.bot.checkers.javascript.bot.Smart.prototype.selectBestNodesForWinningSmart = function(nodesArray) {
  //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart is runing...");};
  if(nodesArray.length < 2) {return nodesArray;};
  var selectedNodes1 = new Array();
  if(this.name == nodesArray[0].whoseMove) {
   for(var i = 0; i < nodesArray.length; i++) {
    //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart delete probabilityWinningSmart == 0");};
    if(nodesArray[i].probabilityWinningSmart != 0) {selectedNodes1[selectedNodes1.length] = nodesArray[i];};
   };
  }	else {
   for(var i = 0; i < nodesArray.length; i++) {
    //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart delete probabilityWinningSmart == 1");};
    if(nodesArray[i].probabilityWinningSmart != 1) {selectedNodes1[selectedNodes1.length] = nodesArray[i];};
   };
  };
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart selectedNodes1.length="+selectedNodes1.length);};
  if(selectedNodes1.length == 0) {return nodesArray;};
  var selectedNodes2 = new Array();
  if(this.name == selectedNodes1[0].whoseMove) {
   for(var i = 0; i < selectedNodes1.length; i++) {
    //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart search probabilityWinningSmart == 1");};
    if(selectedNodes1[i].probabilityWinningSmart == 1) {selectedNodes2[selectedNodes2.length] = selectedNodes1[i];};
   };
  }	else {
   for(var i = 0; i < selectedNodes1.length; i++) {
    //if(this.mustTrace()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart search probabilityWinningSmart == 0");};
    if(selectedNodes1[i].probabilityWinningSmart == 0) {selectedNodes2[selectedNodes2.length] = selectedNodes1[i];};
   };
  };
  //if(this.mustDebug()) {this.getLog().println("su.bot.checkers.javascript.bot.Smart.selectBestNodesForWinningSmart selectedNodes2.length="+selectedNodes2.length);};
  return (selectedNodes2 > 0) ? selectedNodes2 : selectedNodes1;
 };
};
