/// <summary> /// Purpose: To calculate a heuristic value for the given board state /// </summary> /// <param name="boardState"></param> /// <param name="color"></param> /// <returns>integer representing the heuristic</returns> public static int GetHeuristicValue(byte[] boardState, ChessColor color) { bool white = color == ChessColor.White; int pH = GetPieceValueHeuristic(boardState, color); int pS = FEN.GetPieceHazard(boardState, white); return(pH + pS); }
/// <summary> /// Purpose: Lower the Heuristic value if our queen is put in danger /// </summary> /// <param name="boardState"></param> /// <param name="color"></param> /// <returns></returns> private static int PieceSafety(byte[] boardState, ChessColor color) { int hazardPenalty = 0; bool white = color == ChessColor.White; hazardPenalty = FEN.GetPieceHazard(boardState, white); /* * hazardPenalty += FEN.PieceNotSafe(boardState, FEN.GetPiecePos(boardState, white, FEN.q), white) ? -400 : 0; * //hazardPenalty += FEN.PieceNotSafe(boardState, FEN.GetPiecePos(boardState, white, FEN.r), white) ? -200 : 0; * //hazardPenalty += FEN.PieceNotSafe(boardState, FEN.GetPiecePos(boardState, white, FEN.n), white) ? -150 : 0; * //hazardPenalty += FEN.PieceNotSafe(boardState, FEN.GetPiecePos(boardState, white, FEN.b), white) ? -155 : 0; * //hazardPenalty += FEN.PieceNotSafe(boardState, FEN.GetPiecePos(boardState, white, FEN.p), white) ? -40 : 0;*/ return(hazardPenalty); }
public static int maxValue(ref byte[] board, int depth, bool white, int alpha, int beta, int cutoff, ref Stopwatch timer, byte[] moveToRemove) { TimeSpan maxTime = TimeSpan.FromMilliseconds(5500); ChessColor color = (white ? ChessColor.White : ChessColor.Black); int hValue, count; if (depth == cutoff) { return(Heuristic.GetHeuristicValue(board, color)); } LightList childrenBoard; if (depth == cutoff - 1) { childrenBoard = FENUnranked.GetAvailableMoves(board, color, false); } else { childrenBoard = FEN.GetAvailableMoves(board, color, false); } count = childrenBoard.Count; if (count == 0) { //no moves available if (FEN.InCheck(board, white)) { return(-5000); //checkmate } else { return(-3000); //stalemate; } } int maximumValue = -10000; int i = 0; byte[] tempBoard = null; while (i < count && timer.Elapsed < maxTime) //process all the children move { tempBoard = childrenBoard[i]; if (timer.Elapsed < maxTime) { hValue = minValue(ref tempBoard, depth + 1, !white, alpha, beta, cutoff, ref timer, null); } else { return(-9999); } if (depth == 1) { if (hValue > maximumValue) { maximumValue = hValue; board = childrenBoard[i]; } if (maximumValue >= beta) { hValue = maximumValue; childrenBoard = null; return(hValue); } alpha = Math.Max(alpha, maximumValue); } else { maximumValue = Math.Max(maximumValue, hValue); if (maximumValue >= beta) { hValue = maximumValue; childrenBoard = null; return(hValue); } alpha = Math.Max(alpha, maximumValue); } ++i; } childrenBoard = null; if (timer.Elapsed > maxTime) { return(-9999); } hValue = maximumValue; return(hValue); }
//This min value version is only called at depth 1 when a previously found best move is used to inform the ordering of moves public static int minValue(ref byte[] board, int depth, bool white, int alpha, int beta, int cutoff, byte[] best, ref Stopwatch timer, byte[] moveToRemove) { ChessColor color = (white ? ChessColor.White : ChessColor.Black); int hValue; LightList equalMoves = new LightList(); TimeSpan maxTime = TimeSpan.FromMilliseconds(5500); LightList childrenBoard; if (depth == cutoff - 1) { childrenBoard = FENUnranked.GetAvailableMoves(board, color, false); } else { childrenBoard = FEN.GetAvailableMoves(board, color, false); } int count = childrenBoard.Count; if (count == 0) { if (FEN.InCheck(board, white)) { return(-5000);//checkmate } else { return(-3000);//stalemate } } if (depth == 1 && moveToRemove != null && count > 1) { childrenBoard.Remove(moveToRemove); } bool found = false; int indexFound = 0; for (int idx = 0; idx < count; ++idx) { found = true; for (int index = 0; index < FEN.OUTOFBOUNDSHIGH; ++index) { if (best[index] != childrenBoard[idx][index]) { found = false; break; } } if (found == true) { indexFound = idx; break; } } //prioritize previously found best move if (indexFound != 0) //swap { shift(ref childrenBoard, indexFound); } int minimumValue = 10000; int i = 0; byte[] tempBoard = null; //int move = -99; // int moveFirst = -99; while (i < count) { //process all the children moves tempBoard = childrenBoard[i]; if (timer.Elapsed < maxTime) { hValue = maxValue(ref tempBoard, depth + 1, !white, alpha, beta, cutoff, ref timer, null); if (hValue == -9999) { //Log("i: " + i +"count " + count); break; } } else { break; } if (hValue == -5000) { board = childrenBoard[i]; childrenBoard = null; //Log("move position: " + i + " count=" + count); return(hValue); } /* if (minimumValue == hValue) * { * equalMoves.Add(tempBoard); * move = i; * }*/ else if (hValue < minimumValue) { minimumValue = hValue; board = childrenBoard[i]; equalMoves.Empty(); equalMoves.Add(board); // move = i; // moveFirst = i; } if (minimumValue <= alpha) { // board = getRandomMove(equalMoves); childrenBoard = null; //Log("move position: " + move + " count=" + count); return(hValue); } beta = Math.Min(beta, minimumValue); ++i; } if (equalMoves.Count != 0) { board = equalMoves[0]; } else { board = null; } childrenBoard = null; // Log("movefirst position: " + moveFirst+" move last: "+move + " count=" + count); return(minimumValue); }
public static int minValue(ref byte[] board, int depth, bool white, int alpha, int beta, int cutoff, ref Stopwatch timer, byte[] moveToRemove) { TimeSpan maxTime = TimeSpan.FromMilliseconds(5500); int hValue; LightList equalMoves = new LightList(); ChessColor color = (white ? ChessColor.White : ChessColor.Black); if (depth == cutoff) { return(Heuristic.GetHeuristicValue(board, color)); } LightList childrenBoard; if (depth == cutoff - 1) { childrenBoard = FENUnranked.GetAvailableMoves(board, color, false); } else { childrenBoard = FEN.GetAvailableMoves(board, color, false); } int count = childrenBoard.Count; if (count == 0) { //no moves available if (FEN.InCheck(board, white)) { return(-5000);//checkmate } else { return(-3000);//stalemate } } if (depth == 1 && moveToRemove != null && count > 1) { childrenBoard.Remove(moveToRemove); } int minimumValue = 10000; int i = 0; byte[] tempBoard = null; // int move = -99; // int moveFirst = -99; while (i < count) { //process all the children move tempBoard = childrenBoard[i]; if (timer.Elapsed < maxTime) { hValue = maxValue(ref tempBoard, depth + 1, !white, alpha, beta, cutoff, ref timer, null); } else { return(-9999); } if (depth == 1) { if (hValue == -5000) { board = childrenBoard[i]; childrenBoard = null; //Log("move position: " + i + " count=" + count); return(hValue); } /* if (minimumValue == hValue){//store move into list of moves of same value * equalMoves.Add(tempBoard); * move = i; * }*/ else if (hValue < minimumValue) //new minimum value, reset the move list { minimumValue = hValue; board = childrenBoard[i]; //move = i; // moveFirst = i; equalMoves.Empty(); equalMoves.Add(board); } if (minimumValue <= alpha) { //board=getRandomMove(equalMoves); childrenBoard = null; //Log("move position: " + move + " count=" + count); return(hValue); } beta = Math.Min(beta, minimumValue); } else { minimumValue = Math.Min(minimumValue, hValue); if (minimumValue <= alpha) { hValue = minimumValue; childrenBoard = null; return(hValue); } beta = Math.Min(beta, minimumValue); if (minimumValue == -5000) { return(-5000); } } ++i; } hValue = minimumValue; if (depth == 1) { board = getRandomMove(equalMoves); // Log("movefirst position: " + moveFirst + "move last " +move+" count=" + count); } childrenBoard = null; if (timer.Elapsed > maxTime) { return(-9999); } hValue = minimumValue; return(hValue); }
public static int maxValue(ref char[] board, int depth, bool white, int alpha, int beta, int cutoff, ref Stopwatch timer) { TimeSpan maxTime = TimeSpan.FromMilliseconds(5500); ChessColor color = (white ? ChessColor.White : ChessColor.Black); int hValue; if (depth == cutoff) { return(Heuristic.GetHeuristicValue(board, color)); } LightList childrenBoard = FEN.GetAvailableMoves(board, color, false); int count = childrenBoard.Count; if (count == 0) //no moves available { if (FENExtensions.InCheck(board, white)) { return(-5000);//checkmate } else { return(-3000);//stalemate; } } //sort array of moves int[] Hchildren = new int[count]; for (int idx = 0; idx < count; ++idx) { Hchildren[idx] = Heuristic.GetHeuristicValue(childrenBoard[idx], color); } sort(ref childrenBoard, ref Hchildren); int maximumValue = -10000; int i = 0; char[] tempBoard = null; while (i < count && timer.Elapsed < maxTime) //process all the children move { tempBoard = childrenBoard[i]; if (timer.Elapsed < maxTime) { hValue = minValue(ref tempBoard, depth + 1, !white, alpha, beta, cutoff, ref timer); } else { return(-9999); } if (depth == 1) { if (maximumValue == hValue) { //choose randomly between current choice and this move Random rnd = new Random(); int value = rnd.Next(0, 1); if (value == 0) { board = tempBoard; } } else if (hValue > maximumValue) { maximumValue = hValue; board = childrenBoard[i]; } if (maximumValue >= beta) { hValue = maximumValue; childrenBoard = null; return(hValue); } alpha = Math.Max(alpha, maximumValue); } else { maximumValue = Math.Max(maximumValue, hValue); if (maximumValue >= beta) { hValue = maximumValue; childrenBoard = null; return(hValue); } alpha = Math.Max(alpha, maximumValue); } ++i; } childrenBoard = null; if (timer.Elapsed > maxTime) { return(-9999); } hValue = maximumValue; return(hValue); }
//This min value version is only called at depth 1 when a previously found best move is used to inform the ordering of moves public static int minValue(ref char[] board, int depth, bool white, int alpha, int beta, int cutoff, char[] best, ref Stopwatch timer) { ChessColor color = (white ? ChessColor.White : ChessColor.Black); int hValue; LightList equalMoves = new LightList(); LightList childrenBoard = FEN.GetAvailableMoves(board, color, false); int count = childrenBoard.Count; if (count == 0) { //no moves available if (FENExtensions.InCheck(board, white)) { return(-5000);//checkmate } else { return(-3000);//stalemate } } //sort array of moves int[] Hchildren = new int[count]; for (int idx = 0; idx < count; ++idx) { Hchildren[idx] = Heuristic.GetHeuristicValue(childrenBoard[idx], color); } sort(ref childrenBoard, ref Hchildren); bool found = false; int indexFound = 0; for (int idx = 0; idx < count; ++idx) { found = true; for (int index = 0; index < 71; ++index) { if (best[index] != childrenBoard[idx][index]) { found = false; break; } } if (found == true) { indexFound = idx; break; } } //prioritize previously found best move if (indexFound != 0) //swap { char[] temp; temp = childrenBoard[0]; childrenBoard.Replace(childrenBoard[indexFound], 0); childrenBoard.Replace(temp, indexFound); } int minimumValue = 10000; int i = 0; char[] tempBoard = null; while (i < count) { //process all the children moves if (depth != cutoff) { tempBoard = childrenBoard[i]; hValue = maxValue(ref tempBoard, depth + 1, !white, alpha, beta, cutoff, ref timer); } else //get heuristics value { hValue = Hchildren[i]; } if (depth == 1) { if (hValue == -5000) { board = childrenBoard[i]; childrenBoard = null; return(hValue); } if (minimumValue == hValue) { equalMoves.Add(tempBoard); } else if (hValue < minimumValue) { minimumValue = hValue; board = childrenBoard[i]; equalMoves.Empty(); equalMoves.Add(board); } if (minimumValue <= alpha) { board = getRandomMove(equalMoves); childrenBoard = null; return(hValue); } beta = Math.Min(beta, minimumValue); } else { minimumValue = Math.Min(minimumValue, hValue); if (minimumValue <= alpha) { hValue = minimumValue; childrenBoard = null; return(hValue); } beta = Math.Min(beta, minimumValue); if (minimumValue == -5000) { return(-5000); } } ++i; } hValue = minimumValue; if (depth == 1) { board = getRandomMove(equalMoves); } childrenBoard = null; return(hValue); }
public static int minValue(ref char[] board, int depth, bool white, int alpha, int beta, int cutoff, ref Stopwatch timer) { TimeSpan maxTime = TimeSpan.FromMilliseconds(5500); int hValue; LightList equalMoves = new LightList(); ChessColor color = (white ? ChessColor.White : ChessColor.Black); if (depth == cutoff) { return(Heuristic.GetHeuristicValue(board, color)); } LightList childrenBoard = FEN.GetAvailableMoves(board, color, false); int count = childrenBoard.Count; if (count == 0) { //no moves available if (FENExtensions.InCheck(board, white)) { return(-5000);//checkmate } else { return(-3000);//stalemate } } //sort array of moves int[] Hchildren = new int[count]; for (int idx = 0; idx < count; ++idx) { Hchildren[idx] = Heuristic.GetHeuristicValue(childrenBoard[idx], color); } sort(ref childrenBoard, ref Hchildren); int minimumValue = 10000; int i = 0; char[] tempBoard = null; while (i < count) { //process all the children move tempBoard = childrenBoard[i]; if (timer.Elapsed < maxTime) { hValue = maxValue(ref tempBoard, depth + 1, !white, alpha, beta, cutoff, ref timer); } else { return(-9999); } if (depth == 1) { if (hValue == -5000) { board = childrenBoard[i]; childrenBoard = null; return(hValue); } if (minimumValue == hValue) //store move into list of moves of same value { equalMoves.Add(tempBoard); } else if (hValue < minimumValue) //new minimum value, reset the move list { minimumValue = hValue; board = childrenBoard[i]; equalMoves.Empty(); equalMoves.Add(board); } if (minimumValue <= alpha) { board = getRandomMove(equalMoves); childrenBoard = null; return(hValue); } beta = Math.Min(beta, minimumValue); } else { minimumValue = Math.Min(minimumValue, hValue); if (minimumValue <= alpha) { hValue = minimumValue; childrenBoard = null; return(hValue); } beta = Math.Min(beta, minimumValue); if (minimumValue == -5000) { return(-5000); } } ++i; } hValue = minimumValue; if (depth == 1) { board = getRandomMove(equalMoves); } childrenBoard = null; if (timer.Elapsed > maxTime) { return(-9999); } hValue = minimumValue; return(hValue); }