SanMove

using SanMove = std::variant<SanNormalMove, SanCastlingMove>

A variant representing either a normal move or a castling move in SAN (Standard Algebraic Notation).

struct SanCastlingMove
#include <san_move.h>

Represents a castling move in Standard Algebraic Notation (SAN).

Public Members

CastlingSide side = {}

The side of the castling move.

std::optional<CheckIndicator> check_indicator = std::nullopt

Indicates whether the move gives check or checkmate.

struct SanNormalMove
#include <san_move.h>

Represents a normal (non-castling) chess move in Standard Algebraic Notation (SAN).

Public Members

PieceType piece_type = {}

The type of piece being moved.

PartialSquare origin = {}

The origin square of the move, which may be fully specified, partially specified (by file or rank), or unspecified.

bool is_capture = false

True if the move captures an opponent’s piece.

Square destination

The destination square of the move.

std::optional<PromotablePieceType> promotion = std::nullopt

Optional promotion piece type.

std::optional<CheckIndicator> check_indicator = std::nullopt

Indicates whether the move gives check or checkmate.

Helper classes

template<>
struct formatter : public chesscxx::internal::NoSpec
#include <san_move_formatter.h>

formatting support for chesscxx::SanCastlingMove

template<>
struct formatter : public chesscxx::internal::NoSpec
#include <san_move_formatter.h>

formatting support for chesscxx::SanNormalMove

template<>
struct formatter : public chesscxx::internal::NoSpec
#include <san_move_formatter.h>

formatting support for chesscxx::SanMove

template<>
class Parser
#include <san_move_parser.h>

parsing support for SanNormalMove

template<>
class Parser
#include <san_move_parser.h>

parsing support for SanCastlingMove

template<>
class Parser
#include <san_move_parser.h>

parsing support for SanMove

Examples

SanMove

#include <chesscxx/castling_side.h>
#include <chesscxx/file.h>
#include <chesscxx/parse.h>
#include <chesscxx/partial_square.h>
#include <chesscxx/piece_type.h>
#include <chesscxx/rank.h>
#include <chesscxx/san_move.h>
#include <chesscxx/square.h>

#include <optional>
#include <print>
#include <string_view>

namespace {
void printErrorOrValue(auto parsed_value) {
  if (parsed_value) {
    std::println("{}", parsed_value.value());
  } else {
    std::println("{}", parsed_value.error());
  }
}

void parseAndPrint(std::string_view str) {
  auto parsed_san_move = chesscxx::parse<chesscxx::SanMove>(str);
  printErrorOrValue(parsed_san_move);
}
}  // namespace

auto main() -> int {
  chesscxx::SanMove san_move = chesscxx::SanNormalMove{
      .piece_type = chesscxx::PieceType::kKing,
      .origin = chesscxx::PartialSquare(chesscxx::File::kE, std::nullopt),
      .destination = chesscxx::Square(chesscxx::File::kF, chesscxx::Rank::k8),
  };
  std::println("{}", san_move);

  san_move = chesscxx::SanCastlingMove{
      .side = chesscxx::CastlingSide::kKingside,
  };
  std::println("{}", san_move);

  parseAndPrint("Be7xd8=Q+");
  parseAndPrint("e2e4+");
  parseAndPrint("O-O-O");
  parseAndPrint("ke7xd8=Q+");
  parseAndPrint("0-0");
  parseAndPrint("e4");
}

Output:

Kef8
O-O
Be7xd8=Q+
e2e4+
O-O-O
Invalid file
Invalid file
e4

SanNormalMove

#include <chesscxx/check_indicator.h>
#include <chesscxx/file.h>
#include <chesscxx/parse.h>
#include <chesscxx/partial_square.h>
#include <chesscxx/piece_type.h>
#include <chesscxx/rank.h>
#include <chesscxx/san_move.h>
#include <chesscxx/square.h>

#include <optional>
#include <print>
#include <string_view>

namespace {
void printErrorOrValue(auto parsed_value) {
  if (parsed_value) {
    std::println("{}", parsed_value.value());
  } else {
    std::println("{}", parsed_value.error());
  }
}

void parseAndPrint(std::string_view str) {
  auto parsed_san_move = chesscxx::parse<chesscxx::SanNormalMove>(str);
  printErrorOrValue(parsed_san_move);
}
}  // namespace

auto main() -> int {
  chesscxx::SanNormalMove normal_move = {
      .piece_type = chesscxx::PieceType::kPawn,
      .origin = chesscxx::PartialSquare(chesscxx::File::kE, chesscxx::Rank::k7),
      .is_capture = true,
      .destination = chesscxx::Square(chesscxx::File::kF, chesscxx::Rank::k8),
      .promotion = chesscxx::PromotablePieceType::kQueen,
      .check_indicator = chesscxx::CheckIndicator::kCheckmate,
  };
  std::println("{}", normal_move);

  normal_move = {
      .piece_type = chesscxx::PieceType::kKing,
      .origin = chesscxx::PartialSquare(chesscxx::File::kE, std::nullopt),
      .destination = chesscxx::Square(chesscxx::File::kF, chesscxx::Rank::k8),
  };
  std::println("{}", normal_move);

  parseAndPrint("Be7xd8=Q+");
  parseAndPrint("be7xd8=Q+");
  parseAndPrint("ke7xd8=Q+");
  parseAndPrint("e7xd8=Q#");
  parseAndPrint("Pe7xd8=Q+");
  parseAndPrint("e7xd8=K");
  parseAndPrint("e7d8");
  parseAndPrint("ed8");
  parseAndPrint("7d8");
  parseAndPrint("d8");
  parseAndPrint("d");
  parseAndPrint("8");
  parseAndPrint("O-O-O");
}

Output:

e7xf8=Q#
Kef8
Be7xd8=Q+
Expecting end of string
Invalid file
e7xd8=Q#
e7xd8=Q+
Invalid promotable piece type
e7d8
ed8
7d8
d8
Invalid file
Invalid file
Invalid file

SanCastlingMove

#include <chesscxx/castling_side.h>
#include <chesscxx/check_indicator.h>
#include <chesscxx/parse.h>
#include <chesscxx/san_move.h>

#include <print>
#include <string_view>

namespace {
void printErrorOrValue(auto parsed_value) {
  if (parsed_value) {
    std::println("{}", parsed_value.value());
  } else {
    std::println("{}", parsed_value.error());
  }
}

void parseAndPrint(std::string_view str) {
  auto parsed_san_move = chesscxx::parse<chesscxx::SanCastlingMove>(str);
  printErrorOrValue(parsed_san_move);
}
}  // namespace

auto main() -> int {
  chesscxx::SanCastlingMove castling = {
      .side = chesscxx::CastlingSide::kKingside,
  };
  std::println("{}", castling);

  castling = {
      .side = chesscxx::CastlingSide::kQueenside,
      .check_indicator = chesscxx::CheckIndicator::kCheck,
  };
  std::println("{}", castling);

  parseAndPrint("O-O");
  parseAndPrint("O-O-O");
  parseAndPrint("O-O-O+");
  parseAndPrint("O-O-O#");
  parseAndPrint("0-0");
  parseAndPrint("e4");
}

Output:

O-O
O-O-O+
O-O
O-O-O
O-O-O+
O-O-O#
Invalid san castling
Invalid san castling