private void Position(string command) { if (command.Contains("startpos")) { command = command.Replace("startpos", "fen " + Definitions.STDSETUP); } var fen = command; int index; string[] moves = null; if (command.Contains("moves")) { index = command.IndexOf("moves") - 1; fen = command.Substring(0, index); index = command.IndexOf("moves") + 6; var temp = command.Substring(index); moves = temp.Split(' '); } index = fen.IndexOf("fen") + 4; fen = fen.Substring(index); //Console.WriteLine(fen); // Setup new BoardState. _bs = _helper.BoardsetupFromFen(fen); /*_bs.PieceKeys = _zobrist.InitZobrist(_bs); * _bs.PosKey = _zobrist.Hash(_bs);*/ if (moves == null) { return; } var mg = new MoveGenerator(_bs); foreach (var move in moves) { // perform those moves var validMoves = mg.AllLegalMoves(); foreach (var validMove in validMoves) { var algebraic = Definitions.IndexToAlgebraic[validMove.GetFromToSquare()[0]] + Definitions.IndexToAlgebraic[validMove.GetFromToSquare()[1]] + validMove.Promotion; if (algebraic == move) { mg.MakeMove(validMove); break; } } } //_helper.PrintBoardWhitePerspective(_bs.BoardRepresentation); }
// Inspiration from VICE Chess Engine. public int AlphaBeta(int alpha, int beta, int depth, BoardState bs, SearchInfo sInfo) { if (depth == 0) { //return _eval.EvalPosition(bs); return(Quiescene(alpha, beta, bs, sInfo)); } // Check if time is up or interrupted by the GUI. if (sInfo.IsTimeUp()) { sInfo.Stopped = true; } sInfo.Nodes++; /*if (bs.BestPly != null) * { * if (bs.FiftyMoveRule >= 100 || _helper.IsRepetition(bs)) * { * return 0; * //Console.WriteLine("bestmove: {0}{1}, score {2}", Definitions.IndexToAlgebraic[bs.BestPly.GetFromToSquare()[0]], Definitions.IndexToAlgebraic[bs.BestPly.GetFromToSquare()[1]], bs.BestPly.Score); * } * }*/ var mg = new MoveGenerator(bs); var legalMoves = mg.AllLegalMoves(); Ply bestMove = null; var nMoves = legalMoves.Length; var oldAlpha = alpha; var moveNum = 0; if (bs.BestPlyAtLowerDepth != null && !bs.HaveSearched) { mg.MakeMove(bs.BestPlyAtLowerDepth); bs.BestPlyAtLowerDepth.Score = -AlphaBeta(-beta, -alpha, depth - 1, bs, sInfo); mg.UndoMove(bs.BestPlyAtLowerDepth); bs.HaveSearched = true; bestMove = bs.BestPlyAtLowerDepth; alpha = bestMove.Score; } for (moveNum = 0; moveNum < legalMoves.Length; moveNum++) { mg.MakeMove(legalMoves[moveNum]); legalMoves[moveNum].Score = -AlphaBeta(-beta, -alpha, depth - 1, bs, sInfo); mg.UndoMove(legalMoves[moveNum]); if (sInfo.Stopped) { return(Definitions.Stopped); } if (legalMoves[moveNum].Score >= beta) { if (nMoves == 1) { sInfo.Fhf++; } sInfo.Fh++; return(beta); // Fail hard beta-cutoff. } if (legalMoves[moveNum].Score > alpha) { alpha = legalMoves[moveNum].Score; // alpha acts like max in minimax. bestMove = legalMoves[moveNum]; } } if (nMoves == 0) { if (_helper.IsKingInCheck(bs.SideToMove, bs.BoardRepresentation, bs.KingSquares)) { return(-Definitions.MATE + bs.Ply); } // Stalemate. return(0); } if (alpha != oldAlpha) { bs.BestPly = bestMove; } return(alpha); }