private void RemovePieceAt(Vector2Int position) { SetAt(position, TileState.None); OnPieceRemoved?.Invoke(this, position); }
private void Chessboard_MouseUp(object sender, MouseEventArgs e) { Cursor = Cursors.Default; if (DragDropOperation.DraggedPiece != null && DragDropOperation.DraggedPiece.Kind != ChessPieceKind.None) { if (e.X > DigitAreaWidth && e.X < this.Width && e.Y < Height - LetterAreaHeight && e.Y > 0) { // Drops a piece on the board var destinationSquare = (BoardDirection == BoardDirection.BlackOnTop ? new ChessSquare((ChessFile)((e.X - DigitAreaWidth) / SquareWidth), (ChessRank)(7 - (e.Y / SquareHeight))) : new ChessSquare((ChessFile)(7 - (e.X - DigitAreaWidth) / SquareWidth), (ChessRank)(e.Y / SquareHeight))); var moveValidationResult = ChessEngine.GetMoveValidity(DragDropOperation.Origin, destinationSquare); if (moveValidationResult.IsValid) { var promotionCancelled = false; if (moveValidationResult.MoveKind.HasFlag(ChessMoveType.Promotion)) { var pieceChooser = new FrmPromotion(ChessEngine.Turn); promotionCancelled = pieceChooser.ShowDialog() != DialogResult.OK; moveValidationResult.PromotedTo = pieceChooser.ChoosePiece; } if (!promotionCancelled) { moveValidationResult.ToSAN = ChessEngine.MoveToSAN(moveValidationResult); // Update the SAN after promotion MovePiece(moveValidationResult); OnPieceMoved?.Invoke(this, moveValidationResult); if (ChessEngine.IsCheckmate) { OnCheckmate?.Invoke(this, new EventArgs()); } else if (ChessEngine.IsCheck) { OnCheck?.Invoke(this, new EventArgs()); } else if (ChessEngine.IsDraw) { OnDraw?.Invoke(this, new EventArgs()); } } else { Invalidate(); } } else { Invalidate(); } } else { // Drops a piece outside of the board ChessEngine.RemovePieceAt(DragDropOperation.Origin); Invalidate(); OnPieceRemoved?.Invoke(this, DragDropOperation.Origin, DragDropOperation.DraggedPiece, e.Location); } } DragDropOperation = new DragOperation(null, null); OnSquareUnselected?.Invoke(this, new EventArgs()); }