// Cloned by Mathias Bazin on 31 Jul 2018 from Mind "Simple AI - Depth 1" by Mathias Bazin // Please leave this clone trail here.// Cloned by Mathias Bazin on 31 Jul 2018 from Mind "Simple AI - Depth 2" by Mathias Bazin // Please leave this clone trail here.// Cloned by Mathias Bazin on 31 Jul 2018 from Mind "Simple AI - Depth 1" by Mathias Bazin // Please leave this clone trail here.// Cloned by Mathias Bazin on 30 Jul 2018 from Mind "First move always" by Mathias Bazin // Please leave this clone trail here.functionMind(){
let positionCount;/*The "AI" part starts here */
let minimaxRoot =function(depth, game, isMaximisingPlayer){
let newGameMoves = game.moves();
let bestMove =-9999;
let bestMoveFound;for(let i =0; i < newGameMoves.length; i++){
let newGameMove = newGameMoves[i]
game.move(newGameMove);
let value = minimax(depth -1, game,-10000,10000,!isMaximisingPlayer);
game.undo();if(value >= bestMove){
bestMove = value;
bestMoveFound = newGameMove;}}return bestMoveFound;};
let minimax =function(depth, game, alpha, beta, isMaximisingPlayer){
positionCount++;if(depth ===0){return-evaluateBoard(board(game));}
let newGameMoves = game.moves();if(isMaximisingPlayer){
let bestMove =-9999;for(let i =0; i < newGameMoves.length; i++){
game.move(newGameMoves[i]);
bestMove =Math.max(bestMove, minimax(depth -1, game, alpha, beta,!isMaximisingPlayer));
game.undo();
alpha =Math.max(alpha, bestMove);if(beta <= alpha){return bestMove;}}return bestMove;}else{
let bestMove =9999;for(let i =0; i < newGameMoves.length; i++){
game.move(newGameMoves[i]);
bestMove =Math.min(bestMove, minimax(depth -1, game, alpha, beta,!isMaximisingPlayer));
game.undo();
beta =Math.min(beta, bestMove);if(beta <= alpha){return bestMove;}}return bestMove;}};
let evaluateBoard =function(board){
let totalEvaluation =0;for(let i =0; i <8; i++){for(let j =0; j <8; j++){
totalEvaluation = totalEvaluation + getPieceValue(board[i][j], i ,j);}}return totalEvaluation;};
let reverseArray =function(array){return array.slice().reverse();};
let pawnEvalWhite =[[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0],[1.0,1.0,2.0,3.0,3.0,2.0,1.0,1.0],[0.5,0.5,1.0,2.5,2.5,1.0,0.5,0.5],[0.0,0.0,0.0,2.0,2.0,0.0,0.0,0.0],[0.5,-0.5,-1.0,0.0,0.0,-1.0,-0.5,0.5],[0.5,1.0,1.0,-2.0,-2.0,1.0,1.0,0.5],[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]];
let pawnEvalBlack = reverseArray(pawnEvalWhite);
let knightEval =[[-5.0,-4.0,-3.0,-3.0,-3.0,-3.0,-4.0,-5.0],[-4.0,-2.0,0.0,0.0,0.0,0.0,-2.0,-4.0],[-3.0,0.0,1.0,1.5,1.5,1.0,0.0,-3.0],[-3.0,0.5,1.5,2.0,2.0,1.5,0.5,-3.0],[-3.0,0.0,1.5,2.0,2.0,1.5,0.0,-3.0],[-3.0,0.5,1.0,1.5,1.5,1.0,0.5,-3.0],[-4.0,-2.0,0.0,0.5,0.5,0.0,-2.0,-4.0],[-5.0,-4.0,-3.0,-3.0,-3.0,-3.0,-4.0,-5.0]];
let bishopEvalWhite =[[-2.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-2.0],[-1.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0],[-1.0,0.0,0.5,1.0,1.0,0.5,0.0,-1.0],[-1.0,0.5,0.5,1.0,1.0,0.5,0.5,-1.0],[-1.0,0.0,1.0,1.0,1.0,1.0,0.0,-1.0],[-1.0,1.0,1.0,1.0,1.0,1.0,1.0,-1.0],[-1.0,0.5,0.0,0.0,0.0,0.0,0.5,-1.0],[-2.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-2.0]];
let bishopEvalBlack = reverseArray(bishopEvalWhite);
let rookEvalWhite =[[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0],[0.5,1.0,1.0,1.0,1.0,1.0,1.0,0.5],[-0.5,0.0,0.0,0.0,0.0,0.0,0.0,-0.5],[-0.5,0.0,0.0,0.0,0.0,0.0,0.0,-0.5],[-0.5,0.0,0.0,0.0,0.0,0.0,0.0,-0.5],[-0.5,0.0,0.0,0.0,0.0,0.0,0.0,-0.5],[-0.5,0.0,0.0,0.0,0.0,0.0,0.0,-0.5],[0.0,0.0,0.0,0.5,0.5,0.0,0.0,0.0]];
let rookEvalBlack = reverseArray(rookEvalWhite);
let evalQueen =[[-2.0,-1.0,-1.0,-0.5,-0.5,-1.0,-1.0,-2.0],[-1.0,0.0,0.0,0.0,0.0,0.0,0.0,-1.0],[-1.0,0.0,0.5,0.5,0.5,0.5,0.0,-1.0],[-0.5,0.0,0.5,0.5,0.5,0.5,0.0,-0.5],[0.0,0.0,0.5,0.5,0.5,0.5,0.0,-0.5],[-1.0,0.5,0.5,0.5,0.5,0.5,0.0,-1.0],[-1.0,0.0,0.5,0.0,0.0,0.0,0.0,-1.0],[-2.0,-1.0,-1.0,-0.5,-0.5,-1.0,-1.0,-2.0]];
let kingEvalWhite =[[-3.0,-4.0,-4.0,-5.0,-5.0,-4.0,-4.0,-3.0],[-3.0,-4.0,-4.0,-5.0,-5.0,-4.0,-4.0,-3.0],[-3.0,-4.0,-4.0,-5.0,-5.0,-4.0,-4.0,-3.0],[-3.0,-4.0,-4.0,-5.0,-5.0,-4.0,-4.0,-3.0],[-2.0,-3.0,-3.0,-4.0,-4.0,-3.0,-3.0,-2.0],[-1.0,-2.0,-2.0,-2.0,-2.0,-2.0,-2.0,-1.0],[2.0,2.0,0.0,0.0,0.0,0.0,2.0,2.0],[2.0,3.0,1.0,0.0,0.0,1.0,3.0,2.0]];
let kingEvalBlack = reverseArray(kingEvalWhite);
let getPieceValue =function(piece, x, y){if(piece ===null){return0;}
let getAbsoluteValue =function(piece, isWhite, x ,y){if(piece.type ==='p'){return10+( isWhite ? pawnEvalWhite[y][x]: pawnEvalBlack[y][x]);}elseif(piece.type ==='r'){return50+( isWhite ? rookEvalWhite[y][x]: rookEvalBlack[y][x]);}elseif(piece.type ==='n'){return30+ knightEval[y][x];}elseif(piece.type ==='b'){return30+( isWhite ? bishopEvalWhite[y][x]: bishopEvalBlack[y][x]);}elseif(piece.type ==='q'){return90+ evalQueen[y][x];}elseif(piece.type ==='k'){return900+( isWhite ? kingEvalWhite[y][x]: kingEvalBlack[y][x]);}throw"Unknown piece type: "+ piece.type;};
let absoluteValue = getAbsoluteValue(piece, piece.color ==='w', x ,y);return piece.color ==='w'? absoluteValue :-absoluteValue;};function board(game){
let letters =['a','b','c','d','e','f','g','h'];
let nbs =['8','7','6','5','4','3','2','1'];
let b =newArray(8);for(let i =0; i<8; i++){
b[i]=newArray(8);for(let j =0; j <8; j++){
let square = letters[j]+ nbs[i];
b[i][j]= game.get(square);}}return b;}function boardToString(b){
let s ="";for(let i =0; i<8; i++){for(let j =0; j<8; j++){if(b[i][j]===null) s +=" ";else{if(b[i][j].color =='b') s += b[i][j].type;else s += b[i][j].type.toUpperCase();}}
s +="\n";}return s;}this.getAction =function( state ){
let game =newChess(state);
let b = board(game);
let move = minimaxRoot(1, game,true);return move;};}