public void setSelected(Vector2 position) { int x = (int)position.X; int y = (int)position.Y; Vector2 newPosition = new Vector2(x, y); if (mSelectedPiece == null) { // Select Piece at position foreach (KeyValuePair <string, ChessPiece> entry in chessPieces) { if ((mMyColor == entry.Value.getPlayer()) && (newPosition == entry.Value.getPosition())) { // Set Selected Piece mSelectedPiece = entry.Value; selectedPieceMasqueradingAs = entry.Value.getMasqueradeType(); // In easy mode - set moves to display AppSettings settings = new AppSettings(); if (!settings.AdvancedModeSettings) { mBoard.setMoves(entry.Value.getMoves()); } return; } } } else { // Piece already selected - place at position ChessBoard.BoardSquare[,] squares = mSelectedPiece.getMoves(); if (mSelectedPiece.getPosition() == newPosition) { // Put Piece Back mSelectedPiece = null; //mBoard.clearBoardSquares(); } else if (squares[x, y] == ChessBoard.BoardSquare.CAN_MOVE) { // Move is valid previousPosition = mSelectedPiece.getPosition(); chosenPosition = newPosition; //mBoard.clearBoardSquares(); mMoveMade = true; } else if (squares[x, y] == ChessBoard.BoardSquare.CAN_TAKE) { // Move is valid - Enemy Piece is taken foreach (KeyValuePair <string, ChessPiece> entry in chessPieces) { if ((mMyColor != entry.Value.getPlayer()) && (newPosition == entry.Value.getPosition())) { // Remove Enemy Piece chessPieces[entry.Key].remove(); break; } } previousPosition = mSelectedPiece.getPosition(); chosenPosition = newPosition; //mBoard.clearBoardSquares(); mMoveMade = true; } else { resetTurn(); // Move is not valid System.Diagnostics.Debug.WriteLine("Invalid Move"); System.Diagnostics.Debug.WriteLine(new Vector2(x, y)); throw new Exception("Move is not Valid"); } //if (mSelectedPiece.getType() == ChessPiece.Piece.PAWN) //{ // System.Diagnostics.Debug.WriteLine("Placed Pawn"); // pawnToPromote = mSelectedPiece; //} } }
public bool checkmate(ChessPiece.Color opponentColor) { // Assume inCheck() has been called, // therefore all piece moves have been calculated //Cache current state mCurrentState = toCurrentGameState(); ChessPiece kingPiece = chessPieces[(opponentColor == ChessPiece.Color.BLACK ? "black" : "white") + "_king"]; Vector2 kingPos = kingPiece.getPosition(); // If king has a move that is not CAN_TAKE or CAN_MOVE // Check if any of kings moves do not result in check int[] cardinalDir = new int[16] { -1, 1, 0, 1, 1, 1, -1, 0, 1, 0, -1, -1, 0, -1, 1, -1 }; for (int i = 0; i < 8; ++i) { //System.Diagnostics.Debug.WriteLine("Check # " + i); Vector2 potentialMove = kingPos + new Vector2(cardinalDir[2 * i], cardinalDir[2 * i + 1]); //System.Diagnostics.Debug.WriteLine(potentialMove); try { //setSelected(potentialMove); kingPiece.makeMove(potentialMove, chessPieces); if (!inCheck(opponentColor)) { // Valid move out of check exists //System.Diagnostics.Debug.WriteLine("CheckMate Check - Valid Move :)"); resetTurn(); return(false); } } catch (Exception ex) { // Not valid move //System.Diagnostics.Debug.WriteLine("CheckMate Check - Exception"); } // Reset and try new move resetTurn(); //System.Diagnostics.Debug.WriteLine("CheckMate Check - Invalid Move"); //System.Diagnostics.Debug.WriteLine(""); } // All moves have been checked, king is stuck. inCheck(opponentColor); if (checkingPieces.Count > 1) { // If checked by two pieces & can't move, checkmate return(true); } // But can he be saved without being exposed to new attack? ChessPiece checkingPiece = checkingPieces[0]; int x = (int)checkingPiece.getPosition().X, y = (int)checkingPiece.getPosition().Y, xDelta = x - (int)kingPos.X, yDelta = y - (int)kingPos.Y, dist = (xDelta == 0 ? Math.Abs(yDelta) : Math.Abs(xDelta)); xDelta /= Math.Abs(xDelta); yDelta /= Math.Abs(yDelta); foreach (KeyValuePair <string, ChessPiece> entry in chessPieces) { // Only check pieces in play AND opponents color AND not the king if ((!entry.Value.isTaken()) && (entry.Value.getPlayer() == opponentColor) && (entry.Value.getType() == ChessPiece.Piece.KING)) { ChessBoard.BoardSquare[,] moves = entry.Value.getMoves(); // Check if piece can be taken or blocked if sliding if (moves[x, y] == ChessBoard.BoardSquare.CAN_TAKE) { // Checking piece can be taken entry.Value.makeMove(new Vector2(x, y), chessPieces); if (!inCheck(opponentColor)) { // Move does not result in another check //System.Diagnostics.Debug.WriteLine("CheckMate Check - Potential Taking Piece"); //System.Diagnostics.Debug.WriteLine("CheckMate Check - " + entry.Value.getPosition()); resetTurn(); return(false); } else { // Move results in check resetTurn(); } } if (checkingPieces[0].getType() != ChessPiece.Piece.PAWN && checkingPieces[0].getType() != ChessPiece.Piece.KNIGHT) { // Check spots between king and checking piece for (int i = 1; i < dist; ++i) { int blockX = (int)kingPos.X + i * xDelta, blockY = (int)kingPos.Y + i * yDelta; if (moves[blockX, blockY] == ChessBoard.BoardSquare.CAN_MOVE) { // Checking piece can be blocked entry.Value.makeMove(new Vector2(blockX, blockY), chessPieces); if (!inCheck(opponentColor)) { // Move does not result in another check //System.Diagnostics.Debug.WriteLine("CheckMate Check - Potential Blocking Piece"); //System.Diagnostics.Debug.WriteLine("CheckMate Check - " + entry.Value.getPosition()); resetTurn(); return(false); } else { // Move results in check resetTurn(); } } // Else cannot block checking piece } } // Else piece is not a blockable piece } } // Otherwise, in checkmate return(true); }