public static ChessMove GetBestMove(ChessBoard board, int depth, Progress progress) { Evaluator e = new Evaluator(); EvaluatedMove root = new EvaluatedMove(null, board); e.Minimax(root, depth, progress); EvaluatedMove[] bestMoves = root.Next.Where(m => (m != null) && (m.BestNextMoveValue == root.BestNextMoveValue)).ToArray(); IOrderedEnumerable<EvaluatedMove> orderedMoves = bestMoves.OrderBy(m => m.MateDepth); //.ThenBy(m => board[m.Move.Source]); if (board.IsBlacksTurn) orderedMoves = orderedMoves.ThenBy(m=>m.AccumulatedMoveValues); else orderedMoves = orderedMoves.ThenByDescending(m => m.AccumulatedMoveValues); EvaluatedMove[] bestOrderedMoves = orderedMoves.ToArray(); if (random == null) random = new Random(); int moveIndex = -1; for (int i = 1; i < bestOrderedMoves.Length; i++ ) { if ((bestOrderedMoves[i].AccumulatedMoveValues != bestOrderedMoves[i - 1].AccumulatedMoveValues) /*|| (board[bestOrderedMoves[i].Move.Source] != board[bestOrderedMoves[i - 1].Move.Source])*/ || (bestOrderedMoves[i].MateDepth != bestOrderedMoves[i-1].MateDepth)) { moveIndex = random.Next(i); break; } } if (moveIndex < 0) moveIndex = random.Next(bestOrderedMoves.Length); return bestOrderedMoves[moveIndex].Move; }
public void CopyFrom(ChessBoard source) { for (int row = 0; row < 8; row++) for (int col = 0; col < 8; col++) { board[row, col] = source.board[row, col]; } flags = source.flags; pawnJumpCol = source.pawnJumpCol; }
public ChessBoard Clone() { ChessBoard clone = new ChessBoard(); clone.CopyFrom(this); return clone; }
/* Capitals are white pieces, and lowercase are black pieces. * Initial layout looks like: * rnbqkbnr * pppppppp * * * * * PPPPPPPP * RNBQKBNR */ public static ChessBoard Parse(string boardString) { int stringPos = 0; ChessBoard result = new ChessBoard(); for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { if (stringPos >= boardString.Length) throw new ArgumentException(string.Format("Expected row {0}, column {1} at string index {2}, but found end of string.", row, col, stringPos)); if (boardString[stringPos] == '\n') { col = 7; continue; } else result.board[row, col] = GetChessPiece(boardString[stringPos++]); } if ((stringPos < boardString.Length) && (boardString[stringPos++] != '\n')) throw new ArgumentException(string.Format("Expected row {0} to be terminated by a newline", row)); } return result; }
public static ChessBoard FromUniqueKey(string key) { int index = 0; int row = 0, col = 0; ChessBoard result = new ChessBoard(); while ((index < key.Length) && (key[index] != '-')) { int distance = uniqueKeyDistanceCodes.IndexOf(key[index]); if (distance >= 0) { int newCoord = row * 8 + col + distance + 1; row = newCoord / 8; col = newCoord % 8; index++; } if (row >= 8) throw new ArgumentException("Invalid board code"); result.board[row, col] = GetChessPiece(key[index++]); col++; if (col > 7) { col = 0; row++; } } if (index >= key.Length - 1) throw new ArgumentException("Invalid board code"); result.flags = (BoardFlags)uniqueKeyDistanceCodes.IndexOf(key[++index]); result.CheckForCheck(); return result; }
public EvaluatedMove(ChessMove move, ChessBoard resultingState, EvaluatedMove predecessor = null) { this.move = move; this.resultingState = resultingState; this.Previous = predecessor; }