private void AIMove() // determine how the AI will move and swap back to players turn after AI makes its move { if (PvE && (currentState == gameState.Normal || currentState == gameState.Check) && ((turn && AIColor) || (!turn && !AIColor))) { int currentBoardState = 0; AIResult aiResult = new AIResult(); AI ai = new AI(0); for (int y = 0; y < board.Length; y++) { for (int x = 0; x < board[y].Length; x++) { if (board[y][x] == null) { continue; } if (PieceDetails.IsPieceBlackorWhite(board[y][x].Name)) { currentBoardState += ai.PieceValue(PieceDetails.selectedPiece(board[y][x].Name)); } else { currentBoardState -= ai.PieceValue(PieceDetails.selectedPiece(board[y][x].Name)); } } } ai.MiniMax(board, turn, AIComplexity, currentBoardState, aiResult); selectedpiece = board[aiResult.SourceY][aiResult.SourceX]; if (!IsValidMove(PieceDetails.selectedPiece(board[aiResult.SourceY][aiResult.SourceX].Name), aiResult.DestinationY, aiResult.DestinationX)) { MessageBox.Show("AI ERROR"); undo(); return; } completeTurn(); } }
private bool KingAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult) { // loop through all directions king can move by one square for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int Y = y + i; int X = x + j; if ((i == 0 && j == 0) || Y < 0 || Y > 7 || X < 0 || X > 7) { continue; } PictureBox[][] newBoard = new PictureBox[8][]; if (board[Y][X] == null) // if king moves to empty square { setNewBoard(board, newBoard, y, x, Y, X); if (IsValidMove(newBoard, turn)) { continue; } AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } continue; } int value = PieceValue(PieceDetails.selectedPiece(board[Y][X].Name)); bool pieceColor = PieceDetails.IsPieceBlackorWhite(board[Y][X].Name); if (turn && !pieceColor) // white king eats black piece { if (value == kingvalue) // if king is eatten prune this path completely { return(true); } if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state { setNewBoard(board, newBoard, y, x, Y, X); if (IsValidMove(newBoard, turn)) { continue; } bestPath = currentBoardState + value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } } else if (!turn && pieceColor) // black king eats white piece { if (value == kingvalue) { return(true); } if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state { setNewBoard(board, newBoard, y, x, Y, X); if (IsValidMove(newBoard, turn)) { continue; } bestPath = currentBoardState - value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } } } } return(false); }
private bool KnightAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult) { foreach (int[] dir in PieceDetails.KnightDirection) { int Y = y + dir[0]; int X = x + dir[1]; if (Y < 0 || Y > 7 || X < 0 || X > 7) { continue; } PictureBox[][] newBoard = new PictureBox[8][]; if (board[Y][X] == null) // knight moving to empty square { setNewBoard(board, newBoard, y, x, Y, X); // create new board object to be used as parameter to call minimax function if (IsValidMove(newBoard, turn)) { continue; } AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } continue; } int value = PieceValue(PieceDetails.selectedPiece(board[Y][X].Name)); bool pieceColor = PieceDetails.IsPieceBlackorWhite(board[Y][X].Name); if (turn && !pieceColor) // white knight eatting black piece { setNewBoard(board, newBoard, y, x, Y, X); if (value == kingvalue) // if king is eatten prune this path completely { return(true); } if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state { if (IsValidMove(newBoard, turn)) { continue; } bestPath = currentBoardState + value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } } else if (!turn && pieceColor) // black knight eatting white piece { setNewBoard(board, newBoard, y, x, Y, X); if (value == kingvalue) { return(true); } if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state { if (IsValidMove(newBoard, turn)) { continue; } bestPath = currentBoardState - value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } } } return(false); }
private bool QueenAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult) { bool[] pieceDirection = new bool[8]; // this array represents north, east, south, west, northeast, southeast, southwest, northwest and will reduce the processing time for (int i = 1; i < 8; i++) // represents the distance to be moved { // queen cannot move anymore as it is either out of bound or there is another piece blocking it from its target if (PieceDetails.checkedAllDirections(pieceDirection)) { break; } for (int j = 0; j < PieceDetails.QueenDirection.Length; j++) // represents the array to define the direction of the move { if (pieceDirection[j]) { continue; } int Y = y + i * PieceDetails.QueenDirection[j][0]; int X = x + i * PieceDetails.QueenDirection[j][1]; if (Y >= 0 && Y < 8 && X >= 0 && X < 8) { PictureBox[][] newBoard = new PictureBox[8][]; if (board[Y][X] == null) // if queen moves to an empty square { setNewBoard(board, newBoard, y, x, Y, X); // create new board object to be used as parameter to call minimax function if (IsValidMove(newBoard, turn)) { continue; } AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } else { bool pieceColor = PieceDetails.IsPieceBlackorWhite(board[Y][X].Name); int value = PieceValue(PieceDetails.selectedPiece(board[Y][X].Name)); if (turn && !pieceColor) // if white queen eats a black piece { if (value == kingvalue) // if king is eatten prune this path completely { return(true); } if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state { setNewBoard(board, newBoard, y, x, Y, X); if (IsValidMove(newBoard, turn)) { pieceDirection[j] = true; continue; } bestPath = currentBoardState + value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } pieceDirection[j] = true; } else if (!turn && pieceColor) // if black queen eats a white piece { if (value == kingvalue) { return(true); } if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state { setNewBoard(board, newBoard, y, x, Y, X); if (IsValidMove(newBoard, turn)) { pieceDirection[j] = true; continue; } bestPath = currentBoardState - value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, Y, X, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, Y, X, 0); } } pieceDirection[j] = true; } else { pieceDirection[j] = true; // if bishop lands on the its same color piece } } } else { pieceDirection[j] = true; // if bishop lands out of bounds } } } return(false); }
private bool PawnAI(PictureBox[][] board, int y, int x, bool turn, int movesCount, int movesLimit, int currentBoardState, AIResult finalResult) { if (turn) // white pawn move { if (y - 1 >= 0) { if (board[y - 1][x] == null) // white pawn moving 1 square north to empty square { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y - 1, x); // create new board object to be used as parameter to call minimax function if (!IsValidMove(newBoard, turn)) { AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); // find best path if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y - 1, x, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y - 1, x, 0); } } } if (x - 1 >= 0 && board[y - 1][x - 1] != null && !PieceDetails.IsPieceBlackorWhite(board[y - 1][x - 1].Name)) // white pawn eat black piece at north-west { int value = PieceValue(PieceDetails.selectedBlackPiece(board[y - 1][x - 1].Name)); if (value == kingvalue) // if king is eatten prune this path completely { return(true); } if (bestPath <= currentBoardState + value) // prune path that are smaller than the current board state { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y - 1, x - 1); if (!IsValidMove(newBoard, turn)) { bestPath = currentBoardState + value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y - 1, x - 1, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y - 1, x - 1, 0); } } } } if (x + 1 < 8 && board[y - 1][x + 1] != null && !PieceDetails.IsPieceBlackorWhite(board[y - 1][x + 1].Name)) // white pawn eat black piece at north-east { int value = PieceValue(PieceDetails.selectedBlackPiece(board[y - 1][x + 1].Name)); if (value == kingvalue) { return(true); } if (bestPath <= currentBoardState + value) { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y - 1, x + 1); if (!IsValidMove(newBoard, turn)) { bestPath = currentBoardState + value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState + value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y - 1, x + 1, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y - 1, x + 1, 0); } } } } } if (y - 2 >= 0 && y == 6 && board[y - 1][x] == null && board[y - 2][x] == null) // white pawn moves 2 squares north to empty square { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y - 2, x); if (!IsValidMove(newBoard, turn)) { AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y - 2, x, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y - 2, x, 0); } } } } else // black pawn move { if (y + 1 < 8) { if (board[y + 1][x] == null) // black pawn moving 1 square south to empty square { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y + 1, x); // create new board object to be used as parameter to call minimax function if (!IsValidMove(newBoard, turn)) { AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y + 1, x, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y + 1, x, 0); } } } if (x - 1 >= 0 && board[y + 1][x - 1] != null && PieceDetails.IsPieceBlackorWhite(board[y + 1][x - 1].Name)) // black pawn eat white piece at south-west { int value = PieceValue(PieceDetails.selectedWhitePiece(board[y + 1][x - 1].Name)); if (value == kingvalue) // if king is eatten prune this path completely { return(true); } if (bestPath >= currentBoardState - value) // prune path that are larger than the current board state { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y + 1, x - 1); if (!IsValidMove(newBoard, turn)) { bestPath = currentBoardState - value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y + 1, x - 1, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y + 1, x - 1, 0); } } } } if (x + 1 < 8 && board[y + 1][x + 1] != null && PieceDetails.IsPieceBlackorWhite(board[y + 1][x + 1].Name)) // black pawn eat white piece at south-east { int value = PieceValue(PieceDetails.selectedWhitePiece(board[y + 1][x + 1].Name)); if (value == kingvalue) { return(true); } if (bestPath >= currentBoardState - value) { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y + 1, x + 1); if (!IsValidMove(newBoard, turn)) { bestPath = currentBoardState - value; AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState - value, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y + 1, x + 1, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y + 1, x + 1, 0); } } } } } if (y + 2 < 8 && y == 1 && board[y + 1][x] == null && board[y + 2][x] == null) // white pawn moves 2 squares south to empty square { PictureBox[][] newBoard = new PictureBox[8][]; setNewBoard(board, newBoard, y, x, y + 2, x); if (!IsValidMove(newBoard, turn)) { AI newAI = new AI(movesCount + 1); int bestBoardState = newAI.MiniMax(newBoard, !turn, movesLimit, currentBoardState, finalResult); if (movesCount == 0) { CapturedSquares capture = new CapturedSquares(); setResult(turn, bestBoardState, y, x, y + 2, x, capture.CaptureCount(newBoard)); } else { setResult(turn, bestBoardState, y, x, y + 2, x, 0); } } } } return(false); }