public Move Parse(string algebraicMove)
        {
            var match = _regex.Match(algebraicMove);

            var move = new Move();
            if (match.Length == 0)
            {
                move.HasError = true;
                move.ErrorMessage = "Failed to match expected structure";
                return move;
            }

            move.CastleType = CastleType.GetFor(match.Groups[Castle].Value);
            move.IsCastle = move.CastleType != null;
            if (!move.IsCastle)
            {
                move.PieceType = PieceType.GetFor(match.Groups[Piece].Value);
                move.SourceFile = match.Groups[SourceFile].Value.Length == 0 ? null : File.GetFor(match.Groups[SourceFile].Value[0]);
                move.SourceRow = Row.GetFor(match.Groups[SourceRow].Value);
                move.IsCapture = !match.Groups[Capture].Value.IsNullOrEmpty();
                move.DestinationFile = match.Groups[DestinationFile].Value.Length == 0 ? null : File.GetFor(match.Groups[DestinationFile].Value[0]);
                move.DestinationRow = Row.GetFor(match.Groups[Destinationrow].Value);
                if (move.PieceType == PieceType.Pawn)
                {
                    move.PromotionPiece = match.Groups[Promotionpiece].Value.Length == 0 ? null : PieceType.GetFor(match.Groups[Promotionpiece].Value[0]);
                    move.IsPromotion = move.PromotionPiece != null;
                }
                if (move.IsCapture)
                {
                    move.IsEnPassantCapture = !match.Groups[EnPassant].Value.IsNullOrEmpty();
                }
                if (!move.PieceType.IsLegal(new Position
                    {
                        File = move.SourceFile,
                        Row = move.SourceRow
                    }, move.IsCapture, new Position
                        {
                            File = move.DestinationFile,
                            Row = move.DestinationRow
                        }))
                {
                    move.HasError = true;
                    move.ErrorMessage = "The source and destination are illegal for this piece type";
                }
            }

            move.IsCheck = !match.Groups[Check].Value.IsNullOrEmpty();
            if (move.IsCheck)
            {
                move.IsDoubleCheck = !match.Groups[DoubleCheck].Value.IsNullOrEmpty();
            }
            else
            {
                move.IsMate = !match.Groups[Mate].Value.IsNullOrEmpty();
            }

            return move;
        }
 private static void Verify(Move move, Move expected)
 {
     move.HasError.ShouldBeEqualTo(expected.HasError, "has error");
     move.PieceType.ShouldBeEqualTo(expected.PieceType, "piece type");
     move.SourceFile.ShouldBeEqualTo(expected.SourceFile, "source file");
     move.SourceRow.ShouldBeEqualTo(expected.SourceRow, "source row");
     move.DestinationFile.ShouldBeEqualTo(expected.DestinationFile, "destination file");
     move.DestinationRow.ShouldBeEqualTo(expected.DestinationRow, "destination row");
     move.IsCapture.ShouldBeEqualTo(expected.IsCapture, "is capture");
     move.IsEnPassantCapture.ShouldBeEqualTo(expected.IsEnPassantCapture, "is en passant capture");
     move.IsPromotion.ShouldBeEqualTo(expected.IsPromotion, "is promotion");
     move.PromotionPiece.ShouldBeEqualTo(expected.PromotionPiece, "promotion piece");
     move.IsCastle.ShouldBeEqualTo(expected.IsCastle, "is castle");
     move.CastleType.ShouldBeEqualTo(expected.CastleType, "castle type");
     move.IsCheck.ShouldBeEqualTo(expected.IsCheck, "is check");
     move.IsDoubleCheck.ShouldBeEqualTo(expected.IsDoubleCheck, "is double check");
     move.IsMate.ShouldBeEqualTo(expected.IsMate, "is mate");
 }