public AIMove GetAIMove(ChessEngine.Engine.Engine engine) { PieceList.Clear(); Squares = engine.ChessBoard.Squares; WhoseTurn = engine.WhoseMove; //Find all pieces that can be moved on this turn for (byte i = 0; i < Squares.Length; i++) { if (Squares[i].Piece != null && Squares[i].Piece.PieceColor == WhoseTurn && Squares[i].Piece.ValidMoves.Count > 0) { PieceList.Add(i); } } //If piecelist is empty, no moves can be made if (PieceList.Count == 0) { return(null); } //Randomly select Piece byte Piece = PieceList[RandomGenerator.Next(0, PieceList.Count)]; //Calculate piece position byte SquareCount = 7; byte Row = 0; while (SquareCount < 64) { if (Piece <= SquareCount) { break; } Row++; SquareCount += 8; } byte Column = (byte)(Piece - Row * 8); AIMove.SourceRow = Row; AIMove.SourceColumn = Column; //Randomly select a move LegalMoves = engine.GetValidMoves(Column, Row); int MoveIndex = RandomGenerator.Next(0, LegalMoves.Length); AIMove.DestinationRow = LegalMoves[MoveIndex][1]; AIMove.DestinationColumn = LegalMoves[MoveIndex][0]; Console.WriteLine("(" + AIMove.SourceColumn + ", " + AIMove.SourceRow + ")" + " (" + AIMove.DestinationColumn + ", " + AIMove.DestinationRow + ")" + "\n---------------"); return(AIMove); }
private ChessEngine.Engine.Engine ReturnNewState(ChessEngine.Engine.Engine engine, byte piece, byte move) { ChessEngine.Engine.Engine newState = new Engine.Engine(); newState.ChessBoard = new Board(engine.ChessBoard); byte[] sourcePos = engine.CalculateColumnAndRow((byte)(piece)); byte[] destinationPos = engine.CalculateColumnAndRow(move); if (!newState.MovePiece(sourcePos[0], sourcePos[1], destinationPos[0], destinationPos[1])) { return(null); } return(newState); }
private DynamicArray ReturnAllMovablePieces(ChessEngine.Engine.Engine engine) { DynamicArray pieceList = new DynamicArray(); Square[] squares = engine.ChessBoard.Squares; //Find all pieces that can be moved on this turn for (byte i = 0; i < squares.Length; i++) { if (squares[i].Piece != null && squares[i].Piece.PieceColor == engine.WhoseMove && squares[i].Piece.ValidMoves.Count > 0) { pieceList.Add(i); } } return(pieceList); }
private void debugWrite(ChessEngine.Engine.Engine engine) { string line = ""; for (int i = 0; i < engine.ChessBoard.Squares.Length; i++) { if (i == 59) { } Square square = engine.ChessBoard.Squares[i]; if (square.Piece != null) { if (square.Piece.PieceType == ChessPieceType.Knight) { line += "H"; } else { line += square.Piece.PieceType.ToString().Substring(0, 1); } } else { line += "."; } if ((i + 1) % 8 == 0) { Debug.WriteLine(line); line = ""; } } Debug.WriteLine("\n\n\n"); }
public void NewGame() { //ChessEngine engine = new Engine(); currentSource = new Selection(); currentDestination = new Selection(); if (engine.HumanPlayer != engine.WhoseMove) { EngineMove(); } Refresh(); }
private double MaxValue(int depth, double alpha, double beta, ChessEngine.Engine.Engine engine) { //Check if stalemate if (engine.IsStalemateBy50MoveRule()) { return(0); } //Check if checkmate if (engine.IsCheckMate()) { return(Double.MinValue); } //A leaf node, return value of board state if ((depth == 0 && maxDepth != 0) || (maxTime.Seconds != 0 && timer.Elapsed > maxTime)) { if (maxTime.Seconds != 0 && timer.Elapsed > maxTime) { overTime = true; } double boardValue = evaluator.ValuateBoard(engine.ChessBoard.Squares); return(boardValue); } double value = Double.MinValue; //Find all pieces that can be moved on this turn DynamicArray pieceList = ReturnAllMovablePieces(engine); //Go through all possible moves foreach (byte piece in pieceList) { foreach (byte move in engine.ChessBoard.Squares[piece].Piece.ValidMoves) { //Create the next board stage ChessEngine.Engine.Engine newState = ReturnNewState(engine, piece, move); //Invalid move, continue to next move if (newState == null) { continue; } //Pass parameters to the next node value = MinValue(depth - 1, alpha, beta, newState); //Check if alpha can be given bigger value if (value > alpha) { alpha = value; if (depth == maxDepth) { //Back at the root node with a better move than the previous best byte[] source = engine.CalculateColumnAndRow(piece); byte[] destination = engine.CalculateColumnAndRow(move); bestMove.SourceColumn = source[0]; bestMove.SourceRow = source[1]; bestMove.DestinationColumn = destination[0]; bestMove.DestinationRow = destination[1]; } } //If alpha is bigger than beta, don't investigate branch further if (alpha > beta) { return(alpha); } if (overTime) { break; } } if (overTime) { break; } } return(alpha); }
private double MinValue(int depth, double alpha, double beta, ChessEngine.Engine.Engine engine) { //Check if stalemate if (engine.IsStalemateBy50MoveRule()) { return(0); } //Check if checkmate if (engine.IsCheckMate()) { return(Double.MaxValue); } //A leaf node, return value of board state if ((depth == 0 && maxDepth != 0) || (maxTime.Seconds != 0) && timer.Elapsed > maxTime) { if (maxTime.Seconds != 0 && timer.Elapsed > maxTime) { overTime = true; } double boardValue = evaluator.ValuateBoard(engine.ChessBoard.Squares); return(boardValue); } double value = Double.MaxValue; //Find all pieces that can be moved on this turn DynamicArray pieceList = ReturnAllMovablePieces(engine); //Go through all possible moves foreach (byte piece in pieceList) { foreach (byte move in engine.ChessBoard.Squares[piece].Piece.ValidMoves) { //Create the next board stage and pass it to the next node ChessEngine.Engine.Engine newState = ReturnNewState(engine, piece, move); //Invalid move, continue to next move if (newState == null) { continue; } value = MaxValue(depth - 1, alpha, beta, newState); //Check if beta can be given smaller value if (value < beta) { beta = value; } //If beta is smaller than alpha, don't investigate branch further if (beta < alpha) { return(beta); } if (overTime) { break; } } if (overTime) { break; } } return(beta); }