diff --git a/utils/gdb/seer_pretty_printers.py b/utils/gdb/seer_pretty_printers.py index 0481d8d..c03e992 100644 --- a/utils/gdb/seer_pretty_printers.py +++ b/utils/gdb/seer_pretty_printers.py @@ -4,6 +4,17 @@ import gdb import gdb.printing +def optional(constructor, val): + try: + return constructor(val["Some"]["__0"]) + except gdb.error: + return None + + +def print_opt(val): + return "(None)" if val is None else str(val) + + class Square(object): """ Python representation of a 'seer::board::square::Square' raw value. @@ -13,8 +24,14 @@ class Square(object): RANKS = list(map(lambda n: str(n + 1), range(8))) def __init__(self, val): + if isinstance(val, Square): + val = val._val self._val = val + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + @classmethod def from_file_rank(cls, file, rank): return cls(file * 8 + rank) @@ -37,8 +54,14 @@ class Bitboard(object): """ def __init__(self, val): + if isinstance(val, Bitboard): + val = val._val self._val = val + @classmethod + def from_gdb(cls, val): + return cls(int(val["__0"])) + def __str__(self): return "[" + ", ".join(map(str, self.squares)) + "]" @@ -65,6 +88,10 @@ class CastleRights(enum.IntEnum): QUEEN_SIDE = 2 BOTH_SIDES = 3 + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + def __str__(self): return self.name.title().replace("_", "") @@ -78,6 +105,10 @@ class Color(enum.IntEnum): WHITE = 0 BLACK = 1 + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + def __str__(self): return self.name.title() @@ -97,6 +128,10 @@ class File(enum.IntEnum): G = 6 H = 7 + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + def __str__(self): return self.name.title() @@ -116,6 +151,10 @@ class Rank(enum.IntEnum): Seventh = 6 Eighth = 7 + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + def __str__(self): return self.name.title() @@ -133,6 +172,10 @@ class Piece(enum.IntEnum): KNIGHT = 4 PAWN = 5 + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + def __str__(self): return self.name.title() @@ -164,6 +207,10 @@ class Move(object): def __init__(self, val): self._val = val + @classmethod + def from_gdb(cls, val): + return cls(int(val)) + @property def piece(self): return Piece(self._val >> self.PIECE_SHIFT & self.PIECE_MASK) @@ -213,7 +260,6 @@ class Move(object): "double_step", "castling", ] - print_opt = lambda val: "(None)" if val is None else str(val) indent = lambda s: " " + s values = [key + ": " + print_opt(getattr(self, key)) + ",\n" for key in KEYS] @@ -234,6 +280,7 @@ class ChessBoard(object): half_move_clock, total_plies, side, + en_passant, ): self._piece_occupancy = list(map(Bitboard, piece_occupancy)) self._color_occupancy = list(map(Bitboard, color_occupancy)) @@ -241,17 +288,18 @@ class ChessBoard(object): self._half_move_clock = int(half_move_clock) self._total_plies = int(total_plies) self._side = Color(side) + self._en_passant = None if en_passant is None else Square(en_passant) @classmethod def from_gdb(cls, val): return cls( - [int(val["piece_occupancy"][p]["__0"]) for p in Piece], - [int(val["color_occupancy"][c]["__0"]) for c in Color], - [int(val["castle_rights"][c]) for c in Color], - # FIXME: find out how to check for Some/None in val["en_passant"], + [Bitboard.from_gdb(val["piece_occupancy"][p]) for p in Piece], + [Bitboard.from_gdb(val["color_occupancy"][c]) for c in Color], + [CastleRights.from_gdb(val["castle_rights"][c]) for c in Color], int(val["half_move_clock"]), int(val["total_plies"]), - Color(int(val["side"])), + Color.from_gdb(val["side"]), + optional(Square.from_gdb, val["en_passant"]), ) def at(self, square): @@ -292,6 +340,7 @@ class ChessBoard(object): "Half-move clock: " + str(self._half_move_clock), "Total plies: " + str(self._total_plies), "Side to play: " + str(self._side), + "En passant: " + print_opt(self._en_passant), ] return "\n".join(res) @@ -300,7 +349,7 @@ class SquarePrinter(object): "Print a seer::board::square::Square" def __init__(self, val): - self._val = Square(val) + self._val = Square.from_gdb(val) def to_string(self): return str(self._val) @@ -310,7 +359,7 @@ class BitboardPrinter(object): "Print a seer::board::bitboard::Bitboard" def __init__(self, val): - self._val = Bitboard(int(val["__0"])) + self._val = Bitboard.from_gdb(val) def to_string(self): return "Bitboard{" + str(self._val)[1:-1] + "}" @@ -320,7 +369,7 @@ class CastleRightsPrinter(object): "Print a seer::board::castle_rights::CastleRights" def __init__(self, val): - self._val = CastleRights(int(val)) + self._val = CastleRights.from_gdb(val) def to_string(self): return str(self._val) @@ -330,7 +379,7 @@ class ColorPrinter(object): "Print a seer::board::color::Color" def __init__(self, val): - self._val = Color(int(val)) + self._val = Color.from_gdb(val) def to_string(self): return str(self._val) @@ -340,7 +389,7 @@ class FilePrinter(object): "Print a seer::board::file::File" def __init__(self, val): - self._val = File(int(val)) + self._val = File.from_gdb(val) def to_string(self): return str(self._val) @@ -350,7 +399,7 @@ class RankPrinter(object): "Print a seer::board::rank::Rank" def __init__(self, val): - self._val = Rank(int(val)) + self._val = Rank.from_gdb(val) def to_string(self): return str(self._val) @@ -360,7 +409,7 @@ class PiecePrinter(object): "Print a seer::board::piece::Piece" def __init__(self, val): - self._val = Piece(int(val)) + self._val = Piece.from_gdb(val) def to_string(self): return str(self._val) @@ -370,7 +419,7 @@ class MovePrinter(object): "Print a seer::board::move::Move" def __init__(self, val): - self._val = Move(int(val["__0"])) + self._val = Move.from_gdb(val) def to_string(self): return str(self._val)