static public int[][] minimax(int layers, Chessboard board, int player) { if (layers == 0) { int[][] highScoreArr = new int[2][]; highScoreArr[0] = new int[2] { board.evaluateBoard(), 0 }; highScoreArr[1] = new int[2] { 0, 0 }; // Console.WriteLine("Final board score: " + highScoreArr[0][0]); return(highScoreArr); } else { Dictionary <int[], List <int[]> > moves = board.getLegalMoves(player, true); int score = 0; bool firstRun = true; int highScore = 0; int[] bestMoveTo = { 0, 0 }; int[] bestMoveFrom = { 0, 0 }; foreach (KeyValuePair <int[], List <int[]> > moveSet in moves) { foreach (int[] move in moveSet.Value) { Chessboard newBoard = Chessboard.DeepCopy(board); newBoard.stringMakeMove(moveToText(moveSet.Key, move), player); if (firstRun) { score = minimax(layers - 1, newBoard, -player)[0][0]; highScore = score; bestMoveFrom = moveSet.Key; bestMoveTo = move; firstRun = false; } else { score = minimax(layers - 1, newBoard, -player)[0][0]; } if ((score > highScore && player == 1) || (score < highScore && player == -1)) { // Console.WriteLine("Sick move found"); highScore = score; bestMoveFrom = moveSet.Key; bestMoveTo = move; } } } int[][] highScoreArr = new int[3][]; highScoreArr[0] = new int[2] { highScore, 0 }; highScoreArr[1] = bestMoveFrom; highScoreArr[2] = bestMoveTo; // if (layers == 2) { Console.WriteLine("Best move is " + bestMoveFrom[0] + ":" + bestMoveFrom[1] + " -> " + bestMoveTo[0] + ":" + bestMoveTo[1]); } if (layers == 2) { Console.Write("."); } return(highScoreArr); } }
public Dictionary <int[], List <int[]> > getLegalMoves(int player, bool checkKing) { Dictionary <int[], List <int[]> > legalMoves = new Dictionary <int[], List <int[]> >(new MyEqualityComparer()); bool possible; int count; int[] currentKingPosition = { 0, 0 }; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (board[i, j] != null && Math.Sign(board[i, j].id) == player) { legalMoves[new int[] { i, j }] = new List <int[]>(); Piece currentPiece = board[i, j]; switch (currentPiece.id) { case 1: // White Pawn if (i < 7 && board[i + 1, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j }); } if (i == 1 && board[i + 1, j] == null && board[i + 2, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + 2, j }); } if (j > 0 && i < 7 && board[i + 1, j - 1] != null && Math.Sign(board[i + 1, j - 1].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j - 1 }); } if (j < 7 && i < 7 && board[i + 1, j + 1] != null && Math.Sign(board[i + 1, j + 1].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j + 1 }); } break; case -1: if (i > 0 && board[i - 1, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j }); } if (i == 6 && board[i - 1, j] == null && board[i - 2, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i - 2, j }); } if (j > 0 && i > 0 && board[i - 1, j - 1] != null && Math.Sign(board[i - 1, j - 1].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j - 1 }); } if (j < 7 && i > 0 && board[i - 1, j + 1] != null && Math.Sign(board[i - 1, j + 1].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j + 1 }); } break; case 2: // Knight case -2: if (i < 6) { if (j < 7 && (board[i + 2, j + 1] == null || Math.Sign(board[i + 2, j + 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 2, j + 1 }); } if (j > 0 && (board[i + 2, j - 1] == null || Math.Sign(board[i + 2, j - 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 2, j - 1 }); } } if (i > 1) { if (j < 7 && (board[i - 2, j + 1] == null || Math.Sign(board[i - 2, j + 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 2, j + 1 }); } if (j > 0 && (board[i - 2, j - 1] == null || Math.Sign(board[i - 2, j - 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 2, j - 1 }); } } if (j < 6) { if (i < 7 && (board[i + 1, j + 2] == null || Math.Sign(board[i + 1, j + 2].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j + 2 }); } if (i > 0 && (board[i - 1, j + 2] == null || Math.Sign(board[i - 1, j + 2].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j + 2 }); } } if (j > 1) { if (i < 7 && (board[i + 1, j - 2] == null || Math.Sign(board[i + 1, j - 2].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j - 2 }); } if (i > 0 && (board[i - 1, j - 2] == null || Math.Sign(board[i - 1, j - 2].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j - 2 }); } } break; case 3: // Bishop case -3: possible = true; count = 1; while (possible && i + count < 8 && j + count < 8) { if (board[i + count, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } else { if (Math.Sign(board[i + count, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } possible = false; } count++; } possible = true; count = -1; while (possible && i + count >= 0 && j + count >= 0) { if (board[i + count, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } else { if (Math.Sign(board[i + count, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } possible = false; } count--; } possible = true; count = 1; while (possible && i + count < 8 && j - count >= 0) { if (board[i + count, j - count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } else { if (Math.Sign(board[i + count, j - count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } possible = false; } count++; } possible = true; count = -1; while (possible && i + count >= 0 && j - count < 8) { if (board[i + count, j - count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } else { if (Math.Sign(board[i + count, j - count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } possible = false; } count--; } break; case 4: // Rook case -4: possible = true; count = 1; while (possible && i + count < 8) { if (board[i + count, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } else { if (Math.Sign(board[i + count, j].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } possible = false; } count++; } possible = true; count = -1; while (possible && i + count >= 0) { if (board[i + count, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } else { if (Math.Sign(board[i + count, j].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } possible = false; } count--; } possible = true; count = 1; while (possible && j + count < 8) { if (board[i, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } else { if (Math.Sign(board[i, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } possible = false; } count++; } possible = true; count = -1; while (possible && j + count >= 0) { if (board[i, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } else { if (Math.Sign(board[i, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } possible = false; } count--; } break; case 5: // Queen case -5: possible = true; count = 1; while (possible && i + count < 8 && j + count < 8) { if (board[i + count, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } else { if (Math.Sign(board[i + count, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } possible = false; } count++; } possible = true; count = -1; while (possible && i + count >= 0 && j + count >= 0) { if (board[i + count, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } else { if (Math.Sign(board[i + count, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j + count }); } possible = false; } count--; } possible = true; count = 1; while (possible && i + count < 8 && j - count >= 0) { if (board[i + count, j - count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } else { if (Math.Sign(board[i + count, j - count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } possible = false; } count++; } possible = true; count = -1; while (possible && i + count >= 0 && j - count < 8) { if (board[i + count, j - count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } else { if (Math.Sign(board[i + count, j - count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j - count }); } possible = false; } count--; } possible = true; count = 1; while (possible && i + count < 8) { if (board[i + count, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } else { if (Math.Sign(board[i + count, j].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } possible = false; } count++; } possible = true; count = -1; while (possible && i + count >= 0) { if (board[i + count, j] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } else { if (Math.Sign(board[i + count, j].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i + count, j }); } possible = false; } count--; } possible = true; count = 1; while (possible && j + count < 8) { if (board[i, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } else { if (Math.Sign(board[i, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } possible = false; } count++; } possible = true; count = -1; while (possible && j + count >= 0) { if (board[i, j + count] == null) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } else { if (Math.Sign(board[i, j + count].id) != player) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + count }); } possible = false; } count--; } break; case 6: // King case -6: if (i < 7 && (board[i + 1, j] == null || Math.Sign(board[i + 1, j].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j }); } if (i < 7 && j < 7 && (board[i + 1, j + 1] == null || Math.Sign(board[i + 1, j + 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j + 1 }); } if (j < 7 && (board[i, j + 1] == null || Math.Sign(board[i, j + 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i, j + 1 }); } if (i > 0 && j < 7 && (board[i - 1, j + 1] == null || Math.Sign(board[i - 1, j + 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j + 1 }); } if (i > 0 && (board[i - 1, j] == null || Math.Sign(board[i - 1, j].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j }); } if (i > 0 && j > 0 && (board[i - 1, j - 1] == null || Math.Sign(board[i - 1, j - 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i - 1, j - 1 }); } if (j > 0 && (board[i, j - 1] == null || Math.Sign(board[i, j - 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i, j - 1 }); } if (i < 7 && j > 0 && (board[i + 1, j - 1] == null || Math.Sign(board[i + 1, j - 1].id) != player)) { legalMoves[new int[] { i, j }].Add(new int[] { i + 1, j - 1 }); } if (Math.Sign(board[i, j].id) == player) { currentKingPosition = new int[] { i, j }; } break; } } } } if (checkKing) { Dictionary <int[], List <int> > movesToRemove = new Dictionary <int[], List <int> >(); foreach (KeyValuePair <int[], List <int[]> > legalMoveSet in legalMoves) { int i = 0; foreach (int[] legalMove in legalMoveSet.Value) { Chessboard nextMove = DeepCopy(this); nextMove.stringMakeMove(moveToText(legalMoveSet.Key, legalMove), player); if (legalMove[0] == 6 && legalMove[1] == 4) { // nextMove.displayBoard(1); } Dictionary <int[], List <int[]> > tempLegalMoves = nextMove.getLegalMoves(player * -1, false); foreach (KeyValuePair <int[], List <int[]> > tempLegalMoveSet in tempLegalMoves) { foreach (int[] tempMove in tempLegalMoveSet.Value) { if (nextMove.board[tempMove[0], tempMove[1]] != null && nextMove.board[tempMove[0], tempMove[1]].id == player * 6) { // Console.WriteLine("Removed a bad move!" + legalMoveSet.Key[0] + legalMoveSet.Key[1] + "-" + legalMoveSet.Value[i][0] + legalMoveSet.Value[i][1]); try { movesToRemove[legalMoveSet.Key].Add(i); } catch { movesToRemove[legalMoveSet.Key] = new List <int>(); movesToRemove[legalMoveSet.Key].Add(i); } // legalMoves[legalMoveSet.Key].RemoveAt(i); // break; } } } i++; } } foreach (KeyValuePair <int[], List <int> > moveToRemove in movesToRemove) { List <int> alreadyRemoved = new List <int>(); foreach (int i in moveToRemove.Value.AsEnumerable().Reverse()) { // Console.WriteLine("We are going to remove the move for " + moveToRemove.Key[0] + moveToRemove.Key[1] + " at index " + i); if (!alreadyRemoved.Contains(i)) { try { legalMoves[moveToRemove.Key].RemoveAt(i); } catch { } alreadyRemoved.Add(i); } } } } return(legalMoves); }