public static LightList ConvertBuffer(BoardBuffer bf) { LightList ll = new LightList(); for (int i = 0; i < bf.capCount; ++i) { ll.Add(bf.captures[i]); } for (int i = 0; i < bf.thrCount; ++i) { ll.Add(bf.threats[i]); } for (int i = 0; i < bf.forCount; ++i) { ll.Add(bf.forward[i]); } for (int i = 0; i < bf.oCount; ++i) { ll.Add(bf.other[i]); } for (int i = 0; i < bf.nsCount; ++i) { ll.Add(bf.notSafe[i]); } return ll; }
public static void AddDiagonalMaps(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { char[] temp; int idx = i + 8; while (idx < 71 && idx % 9 >= 0) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (board.TakesOpponentPiece(white, idx)) { break; } } else { break; } idx += 8; } idx = i + 10; while (idx < 71 && idx % 9 <= 8) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (board.TakesOpponentPiece(white, idx)) { break; } } else { break; } idx += 10; } idx = i - 10; while (idx > -1 && idx % 9 >= 0) { if (board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (board.TakesOpponentPiece(white, idx)) { break; } } else { break; } idx -= 10; } idx = i - 8; while (idx > -1 && idx % 9 <= 8) { if (board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (board.TakesOpponentPiece(white, idx)) { break; } } else { break; } idx -= 8; } }
//returns a move/board randomly from a set of board with equal quality private static byte[] getRandomMove(LightList equalMoves) { if (equalMoves.Count == 1) { return equalMoves[0]; } else { Random rnd = new Random(); int value = rnd.Next(0, equalMoves.Count - 1); return equalMoves[value]; } }
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 void AddPawnMoves(this byte[] board, bool white, int i, ref LightList moves, bool allowCheck) { byte[] temp; if (!white) { if (i / COLUMN == 1) { if (board[i + UPUP] == _ && board[i + UP] == _) { temp = board.MovePawn(i, i + UPUP, white); if (allowCheck || allowCheck || !InCheck(temp, white)) moves.Add(temp); } } if (board[i + UP] == _) { temp = board.MovePawn(i, i + UP, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (board[i + UPLEFT].IsUpper() && (i + UPLEFT) % COLUMN != COL8) { temp = board.MovePawn(i, i + UPLEFT, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (i < 54 && board[i + UPRIGHT].IsUpper() && (i + UPRIGHT) % COLUMN != COL1) { temp = board.MovePawn(i, i + UPRIGHT, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } else { if (i / COLUMN == COL7) { if (board[i + DOWNDOWN] == _ && board[i + DOWN] == _) { temp = board.MovePawn(i, i + DOWNDOWN, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } if (board[i + DOWN] == _) { temp = board.MovePawn(i, i + DOWN, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (board[i + DOWNRIGHT].IsLower() && (i + DOWNRIGHT) % COLUMN != COL1) { temp = board.MovePawn(i, i + DOWNRIGHT, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (i > 8 && board[i + DOWNLEFT].IsLower() && (i + DOWNLEFT) % COLUMN != COL8) { temp = board.MovePawn(i, i + DOWNLEFT, white); if (!InCheck(temp, white)) moves.Add(temp); } } }
public static void AddKnightMoves(this byte[] board, bool white, int i, ref LightList moves, bool allowCheck) { int originRow = i % COLUMN; int idx = i + UPUPRIGHT; byte[] temp; if (idx < OUTOFBOUNDSHIGH && originRow < COL8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + UPUPLEFT; if (idx < OUTOFBOUNDSHIGH && originRow > COL1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + UPRIGHTRIGHT; if (idx < OUTOFBOUNDSHIGH && originRow < COL7 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + UPLEFTLEFT; if (idx < OUTOFBOUNDSHIGH && originRow > COL2 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + DOWNDOWNLEFT; if (idx > OUTOFBOUNDSLOW && originRow > COL1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + DOWNDOWNRIGHT; if (idx > OUTOFBOUNDSLOW && originRow < COL8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + DOWNLEFTLEFT; if (idx > OUTOFBOUNDSLOW && originRow > COL2 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + DOWNRIGHTRIGHT; if (idx > OUTOFBOUNDSLOW && originRow < COL7 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } }
public static void AddAdjacentMaps(this byte[] board, bool white, int i, ref LightList moves, bool allowCheck) { int idx = i + UP; byte[] temp; while (idx < OUTOFBOUNDSHIGH) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (!InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, idx)) break; } else break; idx += UP; } idx = i + DOWN; while (idx > OUTOFBOUNDSLOW) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, idx)) break; } else break; idx += DOWN; } idx = i % COLUMN; int bse = i - idx; while (--idx > -1) { if (IsValidMove(board, white, bse + idx)) { temp = board.Move(i, bse + idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, bse + idx)) break; } else break; } idx = i % COLUMN; bse = i - idx; while (++idx < 8) { if (IsValidMove(board, white, bse + idx)) { temp = board.Move(i, bse + idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, bse + idx)) break; } else break; } }
//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); }
public static LightList GetAvailableMoves(char[] board, ChessColor color, bool allowCheck) { bool white = color == ChessColor.White; LightList moves = new LightList(); //iterate thru entire board {64} including row delimiters {7} for (int i = 0; i < 71; ++i) { if (!white) { switch (board[i]) { case 'p': board.AddPawnMoves(white, i, ref moves, allowCheck); break; case 'r': board.AddAdjacentMaps(white, i, ref moves, allowCheck); break; case 'b': board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'n': board.AddKnightMoves(white, i, ref moves, allowCheck); break; case 'q': board.AddAdjacentMaps(white, i, ref moves, allowCheck); board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'k': board.AddKingMoves(white, i, ref moves, allowCheck); break; default: break; } } else { switch (board[i]) { case 'P': board.AddPawnMoves(white, i, ref moves, allowCheck); break; case 'R': board.AddAdjacentMaps(white, i, ref moves, allowCheck); break; case 'B': board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'N': board.AddKnightMoves(white, i, ref moves, allowCheck); break; case 'Q': board.AddAdjacentMaps(white, i, ref moves, allowCheck); board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'K': board.AddKingMoves(white, i, ref moves, allowCheck); break; default: break; } } } return(moves); }
public static void AddPawnMoves(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { char[] temp; if (!white) { if (i / 9 == 1) { if (board[i + 18] == '_' && board[i + 9] == '_') { temp = board.MovePawn(i, i + 18, white); if (allowCheck || allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } } if (board[i + 9] == '_') { temp = board.MovePawn(i, i + 9, white); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (Char.IsUpper(board[i + 8])) { temp = board.MovePawn(i, i + 8, white); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (i < 61 && Char.IsUpper(board[i + 10])) { temp = board.MovePawn(i, i + 10, white); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } } else { if (i / 9 == 6) { if (board[i - 18] == '_' && board[i - 9] == '_') { temp = board.MovePawn(i, i - 18, white); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } } if (board[i - 9] == '_') { temp = board.MovePawn(i, i - 9, white); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (Char.IsLower(board[i - 8])) { temp = board.MovePawn(i, i - 8, white); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (i > 10 && Char.IsLower(board[i - 10])) { temp = board.MovePawn(i, i - 10, white); if (!InCheck(board, white)) { moves.Add(temp); } } } }
public static void AddKingMoves(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { char[] temp; int idx = i + 8; if (idx < 71) { if (idx % 9 != 8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (board.IsValidMove(white, ++idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (++idx % 9 != 8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } } idx = i + 1; if (idx % 9 != 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i - 1; if (idx % 9 != 8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i - 8; if (idx > -1) { if (idx % 9 != 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (board.IsValidMove(white, --idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } if (idx % 9 != 0 && board.IsValidMove(white, --idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } } }
public static void AddKnightMoves(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { int originRow = i % 9; int idx = i + 19; char[] temp; if (idx < 71 && originRow < 7 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i + 17; if (idx < 71 && originRow > 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i + 11; if (idx < 71 && originRow < 6 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i + 7; if (idx < 71 && originRow % 9 > 1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i - 19; if (idx > -1 && originRow > 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i - 17; if (idx > -1 && originRow < 7 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i - 11; if (idx > -1 && originRow > 1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } idx = i - 7; if (idx > -1 && originRow < 6 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } } }
public static void AddAdjacentMaps(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { int idx = i + 9; char[] temp; while (idx < 71) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (!InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, idx)) break; } else break; idx += 9; } idx = i - 9; while (idx > -1) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, idx)) break; } else break; idx -= 9; } idx = i % 9; int bse = i - idx; while (--idx > -1) { if (IsValidMove(board, white, bse + idx)) { temp = board.Move(i, bse + idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, bse + idx)) break; } else break; } idx = i % 9; bse = i - idx; while (++idx < 8) { if (IsValidMove(board, white, bse + idx)) { temp = board.Move(i, bse + idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (TakesOpponentPiece(board, white, bse + idx)) break; } else break; } }
//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; }
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); }
private static void sort(ref LightList children, ref int[] h) { int count = children.Count; bool swapped; do { swapped = false; for (int j = 1; j < count; ++j) { if (h[j - 1] < h[j]) { int temp; char[] tempBoard; temp = h[j]; tempBoard = children[j]; h[j] = h[j - 1]; h[j - 1] = temp; children.Replace(children[j - 1], j); children.Replace(tempBoard, j - 1); swapped = true; } } count--; } while (swapped); }
public static void AddDiagonalMaps(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { char[] temp; int idx = i + 8; while (idx < 71 && idx % 9 >= 0) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx += 8; } idx = i + 10; while (idx < 71 && idx % 9 <= 8) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx += 10; } idx = i - 10; while (idx > -1 && idx % 9 >= 0) { if (board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx -= 10; } idx = i - 8; while (idx > -1 && idx % 9 <= 8) { if (board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx -= 8; } }
public static void AddDiagonalMaps(this byte[] board, bool white, int i, ref LightList moves, bool allowCheck) { byte[] temp; int idx = i + UPLEFT; while (idx < OUTOFBOUNDSHIGH && idx % COLUMN != COL8) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx += UPLEFT; } idx = i + UPRIGHT; while (idx < OUTOFBOUNDSHIGH && idx % COLUMN != COL1) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx += UPRIGHT; } idx = i + DOWNLEFT; while (idx > OUTOFBOUNDSLOW && idx % COLUMN != COL8) { if (board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx += DOWNLEFT; } idx = i + DOWNRIGHT; while (idx > OUTOFBOUNDSLOW && idx % COLUMN != 0) { if (board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); if (board.TakesOpponentPiece(white, idx)) break; } else break; idx += DOWNRIGHT; } }
public static void AddKnightMoves(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { int originRow = i % 9; int idx = i + 19; char[] temp; if (idx < 71 && originRow < 7 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + 17; if (idx < 71 && originRow > 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + 11; if (idx < 71 && originRow < 6 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + 7; if (idx < 71 && originRow % 9 > 1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i - 19; if (idx > -1 && originRow > 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i - 17; if (idx > -1 && originRow < 7 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i - 11; if (idx > -1 && originRow > 1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i - 7; if (idx > -1 && originRow < 6 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } }
public static void AddKingMoves(this byte[] board, bool white, int i, ref LightList moves, bool allowCheck) { byte[] temp; int idx = i + UPLEFT; if (idx < OUTOFBOUNDSHIGH) { if (idx % COLUMN != COL8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (board.IsValidMove(white, ++idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (++idx % COLUMN != COL1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } idx = i + RIGHT; if (idx % COLUMN != COL1 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + LEFT; if (idx % COLUMN != COL8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i + DOWNRIGHT; if (idx > -1) { if (i % COLUMN != COL8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (board.IsValidMove(white, --idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (i % COLUMN != COL1 && board.IsValidMove(white, --idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } }
public static void AddKingMoves(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { char[] temp; int idx = i + 8; if (idx < 71) { if (idx % 9 != 8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (board.IsValidMove(white, ++idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (++idx % 9 != 8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } idx = i + 1; if (idx % 9 != 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i - 1; if (idx % 9 != 8 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } idx = i - 8; if (idx > -1) { if (idx % 9 != 0 && board.IsValidMove(white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (board.IsValidMove(white, --idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (idx % 9 != 0 && board.IsValidMove(white, --idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } }
public static LightList GetAvailableMoves(this byte[] board, ChessColor color, bool allowCheck) { bool white = color == ChessColor.White; LightList moves = new LightList(); //iterate thru entire board {64} including row delimiters {7} for (int i = 0; i < OUTOFBOUNDSHIGH; ++i) { if (!white) { switch (board[i]) { case 0x02: board.AddPawnMoves(white, i, ref moves, allowCheck); break; case 0x04: board.AddAdjacentMaps(white, i, ref moves, allowCheck); break; case 0x06: board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 0x08: board.AddKnightMoves(white, i, ref moves, allowCheck); break; case 0x0A: board.AddAdjacentMaps(white, i, ref moves, allowCheck); board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 0x0C: board.AddKingMoves(white, i, ref moves, allowCheck); break; default: break; } } else { switch (board[i]) { case 0x01: board.AddPawnMoves(white, i, ref moves, allowCheck); break; case 0x03: board.AddAdjacentMaps(white, i, ref moves, allowCheck); break; case 0x05: board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 0x07: board.AddKnightMoves(white, i, ref moves, allowCheck); break; case 0x09: board.AddAdjacentMaps(white, i, ref moves, allowCheck); board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 0x0B: board.AddKingMoves(white, i, ref moves, allowCheck); break; default: break; } } } return moves; }
public static void AddPawnMoves(this char[] board, bool white, int i, ref LightList moves,bool allowCheck) { char[] temp; if (!white) { if (i / 9 == 1) { if (board[i + 18] == '_' && board[i + 9] == '_') { temp = board.MovePawn(i, i + 18, white); if (allowCheck || allowCheck || !InCheck(temp, white)) moves.Add(temp); } } if (board[i + 9] == '_') { temp = board.MovePawn(i, i + 9, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (Char.IsUpper(board[i + 8])) { temp = board.MovePawn(i, i + 8, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (i < 61 && Char.IsUpper(board[i + 10])) { temp = board.MovePawn(i, i + 10, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } else { if (i / 9 == 6) { if (board[i - 18] == '_' && board[i - 9] == '_') { temp = board.MovePawn(i, i - 18, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } } if (board[i - 9] == '_') { temp = board.MovePawn(i, i - 9, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (Char.IsLower(board[i - 8])) { temp = board.MovePawn(i, i - 8, white); if (allowCheck || !InCheck(temp, white)) moves.Add(temp); } if (i > 10 && Char.IsLower(board[i - 10])) { temp = board.MovePawn(i, i - 10, white); if (!InCheck(board, white)) moves.Add(temp); } } }
//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 LightList GetAvailableMoves(char[] board, ChessColor color, bool allowCheck) { bool white = color == ChessColor.White; LightList moves = new LightList(); //iterate thru entire board {64} including row delimiters {7} for (int i = 0; i < 71; ++i) { if (!white) { switch (board[i]) { case 'p': board.AddPawnMoves(white, i, ref moves,allowCheck); break; case 'r': board.AddAdjacentMaps(white, i, ref moves,allowCheck); break; case 'b': board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'n': board.AddKnightMoves(white, i, ref moves, allowCheck); break; case 'q': board.AddAdjacentMaps(white, i, ref moves, allowCheck); board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'k': board.AddKingMoves(white, i, ref moves, allowCheck); break; default: break; } } else { switch (board[i]) { case 'P': board.AddPawnMoves(white, i, ref moves, allowCheck); break; case 'R': board.AddAdjacentMaps(white, i, ref moves, allowCheck); break; case 'B': board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'N': board.AddKnightMoves(white, i, ref moves, allowCheck); break; case 'Q': board.AddAdjacentMaps(white, i, ref moves, allowCheck); board.AddDiagonalMaps(white, i, ref moves, allowCheck); break; case 'K': board.AddKingMoves(white, i, ref moves, allowCheck); break; default: break; } } } return moves; }
private static void shift(ref LightList children, int indexFound) { byte[] tempBest = children[indexFound]; for (int i = indexFound; i > 0; --i) { children.Replace(children[i - 1], i); } children.Replace(tempBest, 0); }
public static void AddAdjacentMaps(this char[] board, bool white, int i, ref LightList moves, bool allowCheck) { int idx = i + 9; char[] temp; while (idx < 71) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (!InCheck(temp, white)) { moves.Add(temp); } if (TakesOpponentPiece(board, white, idx)) { break; } } else { break; } idx += 9; } idx = i - 9; while (idx > -1) { if (IsValidMove(board, white, idx)) { temp = board.Move(i, idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (TakesOpponentPiece(board, white, idx)) { break; } } else { break; } idx -= 9; } idx = i % 9; int bse = i - idx; while (--idx > -1) { if (IsValidMove(board, white, bse + idx)) { temp = board.Move(i, bse + idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (TakesOpponentPiece(board, white, bse + idx)) { break; } } else { break; } } idx = i % 9; bse = i - idx; while (++idx < 8) { if (IsValidMove(board, white, bse + idx)) { temp = board.Move(i, bse + idx); if (allowCheck || !InCheck(temp, white)) { moves.Add(temp); } if (TakesOpponentPiece(board, white, bse + idx)) { break; } } else { break; } } }