Exemplo n.º 1
0
    def create_fen(self, pieces):
        """ Create a random FEN position using given pieces """

        pos = pieces.rfind("k")
        pieces = pieces[:pos], pieces[pos:]

        ok = False
        while not ok:
            lboard = LBoard()
            lboard.applyFen("8/8/8/8/8/8/8/8 w - - 0 1")

            cords = list(range(0, 64))
            pawn_cords = list(range(0 + 8, 64 - 8))
            for color in (BLACK, WHITE):
                for char in pieces[color]:
                    piece = chrU2Sign[char.upper()]
                    cord = random.choice(pawn_cords if char == "p" else cords)
                    lboard._addPiece(cord, piece, color)
                    cords.remove(cord)
                    if cord in pawn_cords:
                        pawn_cords.remove(cord)
            # TODO: 2 same color bishop is not ok
            ok = (not lboard.isChecked()) and (not lboard.opIsChecked())

        fen = lboard.asFen()
        return fen
Exemplo n.º 2
0
def create_fen(pieces):
    """ Create a random FEN position using given pieces """

    pos = pieces.rfind("k")
    pieces = pieces[:pos], pieces[pos:]

    ok = False
    while not ok:
        lboard = LBoard()
        lboard.applyFen("8/8/8/8/8/8/8/8 w - - 0 1")
        bishop_cords = [[], []]
        bishop_colors_ok = True

        cords = list(range(0, 64))
        pawn_cords = list(range(0 + 8, 64 - 8))

        # Order of color is important here to prevent offering
        # positions with trivial captures in first move
        for color in (WHITE, BLACK):
            for char in pieces[color]:
                piece = chrU2Sign[char.upper()]
                attacked = True
                limit = 100
                while attacked and limit > 0:
                    cord = random.choice(pawn_cords if char == "p" else cords)
                    attacked = isAttacked(lboard, cord, 1 - color)
                    limit -= 1
                lboard._addPiece(cord, piece, color)
                cords.remove(cord)
                if cord in pawn_cords:
                    pawn_cords.remove(cord)
                if char == "b":
                    bishop_cords[color].append(cord)

            # 2 same color bishop is not ok
            if len(bishop_cords[color]) == 2 and bishop_colors_ok:
                b0, b1 = bishop_cords[color]
                b0_color = BLACK if RANK(b0) % 2 == FILE(b0) % 2 else WHITE
                b1_color = BLACK if RANK(b1) % 2 == FILE(b1) % 2 else WHITE
                if b0_color == b1_color:
                    bishop_colors_ok = False
                    break

        ok = (not lboard.isChecked()) and (
            not lboard.opIsChecked()) and bishop_colors_ok

    fen = lboard.asFen()
    return fen
Exemplo n.º 3
0
def create_fen(pieces):
    """ Create a random FEN position using given pieces """

    pos = pieces.rfind("k")
    pieces = pieces[:pos], pieces[pos:]

    ok = False
    while not ok:
        lboard = LBoard()
        lboard.applyFen("8/8/8/8/8/8/8/8 w - - 0 1")
        bishop_cords = [[], []]
        bishop_colors_ok = True

        cords = list(range(0, 64))
        pawn_cords = list(range(0 + 8, 64 - 8))

        # Order of color is important here to prevent offering
        # positions with trivial captures in first move
        for color in (WHITE, BLACK):
            for char in pieces[color]:
                piece = chrU2Sign[char.upper()]
                attacked = True
                limit = 100
                while attacked and limit > 0:
                    cord = random.choice(pawn_cords if char == "p" else cords)
                    attacked = isAttacked(lboard, cord, 1 - color)
                    limit -= 1
                lboard._addPiece(cord, piece, color)
                cords.remove(cord)
                if cord in pawn_cords:
                    pawn_cords.remove(cord)
                if char == "b":
                    bishop_cords[color].append(cord)

            # 2 same color bishop is not ok
            if len(bishop_cords[color]) == 2 and bishop_colors_ok:
                b0, b1 = bishop_cords[color]
                b0_color = BLACK if RANK(b0) % 2 == FILE(b0) % 2 else WHITE
                b1_color = BLACK if RANK(b1) % 2 == FILE(b1) % 2 else WHITE
                if b0_color == b1_color:
                    bishop_colors_ok = False
                    break

        ok = (not lboard.isChecked()) and (not lboard.opIsChecked()) and bishop_colors_ok

    fen = lboard.asFen()
    return fen
Exemplo n.º 4
0
def create_fen(pieces):
    """ Create a random FEN position using given pieces """

    pos = pieces.rfind("k")
    pieces = pieces[:pos], pieces[pos:]

    ok = False
    while not ok:
        lboard = LBoard()
        lboard.applyFen("8/8/8/8/8/8/8/8 w - - 0 1")
        bishop_cords = [[], []]
        bishop_colors_ok = True

        cords = list(range(0, 64))
        pawn_cords = list(range(0 + 8, 64 - 8))
        for color in (BLACK, WHITE):
            for char in pieces[color]:
                piece = chrU2Sign[char.upper()]
                cord = random.choice(pawn_cords if char == "p" else cords)
                lboard._addPiece(cord, piece, color)
                cords.remove(cord)
                if cord in pawn_cords:
                    pawn_cords.remove(cord)
                if char == "b":
                    bishop_cords[color].append(cord)

            # 2 same color bishop is not ok
            if len(bishop_cords[color]) == 2 and bishop_colors_ok:
                b0, b1 = bishop_cords[color]
                b0_color = BLACK if RANK(b0) % 2 == FILE(b0) % 2 else WHITE
                b1_color = BLACK if RANK(b1) % 2 == FILE(b1) % 2 else WHITE
                if b0_color == b1_color:
                    bishop_colors_ok = False
                    break

        ok = (not lboard.isChecked()) and (not lboard.opIsChecked()) and bishop_colors_ok

    fen = lboard.asFen()
    return fen
Exemplo n.º 5
0
class OLVFile(ChessFile):
    def __init__(self, handle):
        ChessFile.__init__(self, handle)

        self.games = self.read_games(handle)
        self.count = len(self.games)

    def read_games(self, handle):
        """ We don't return games if stipulation is not 'mate in #' """
        games = []
        rec = None
        rec_id = 1
        contains_fairy_pieces = False

        # authors is a more line list (each line starts with "-")
        in_authors = False

        # piece list are usually in one line list inside []
        # but sometimes given in more line lists
        in_white = False
        in_black = False

        for line in handle:
            line = line.rstrip()

            if in_authors and ":" in line:
                in_authors = False

            elif in_white and ":" in line:
                in_white = False

            elif in_black and ":" in line:
                in_black = False
                rec["FEN"] = self.lboard.asFen()

            # New record start
            if line == "---":
                if rec is not None and rec["Black"].startswith("Mate in ") and not contains_fairy_pieces:
                    games.append(rec)
                    rec_id += 1

                contains_fairy_pieces = False

                self.lboard = LBoard()
                self.lboard.applyFen("8/8/8/8/8/8/8/8 w - - 0 1")

                rec = collections.defaultdict(str)
                rec["Id"] = rec_id
                rec["Offset"] = 0

            elif line.startswith("authors:"):
                in_authors = True

            elif line.startswith("source:"):
                rec["Event"] = line[8:]

            elif line.startswith("source-id:"):
                rec["Event"] = "%s (%s)" % (rec["Event"], line[12:])

            elif line.startswith("date:"):
                parts = line[6:].split("-")
                parts_len = len(parts)
                if parts_len >= 3:
                    rec["Day"] = parts[2]
                if parts_len >= 2:
                    rec["Month"] = parts[1]
                if parts_len >= 1:
                    rec["Year"] = parts[0]

            elif line.startswith("distinction:"):
                rec["Site"] = line[12:]

            elif line.startswith("algebraic:"):
                pass

            elif line.startswith("  white:"):
                parts = line.split("[")
                if len(parts) > 1:
                    pieces = parts[1][:-1]
                    for piece in pieces.split(", "):
                        if piece.startswith("Royal") or piece[0] not in chr2piece:
                            contains_fairy_pieces = True
                        else:
                            cord = Cord(piece[1:3]).cord
                            piece = chr2piece[piece[0]]
                            self.lboard._addPiece(cord, piece, WHITE)
                else:
                    in_white = True

            elif line.startswith("  black:"):
                parts = line.split("[")
                if len(parts) > 1:
                    pieces = parts[1][:-1]
                    for piece in pieces.split(", "):
                        if piece.startswith("Royal") or piece[0] not in chr2piece:
                            contains_fairy_pieces = True
                        else:
                            cord = Cord(piece[1:3]).cord
                            piece = chr2piece[piece[0]]
                            self.lboard._addPiece(cord, piece, BLACK)

                    rec["FEN"] = self.lboard.asFen()
                else:
                    in_black = True

            elif line.startswith("stipulation:"):
                if line.endswith("Black to move"):
                    line = line[:-14]
                    rec["FEN"] = rec["FEN"].replace("w", "b")

                line = line.split(": ")[1]
                if "+" in line:
                    rec["Result"] = WHITEWON
                    rec["Black"] = "Win"
                elif "-" in line:
                    rec["Result"] = BLACKWON
                    rec["Black"] = "Win"
                elif "=" in line:
                    rec["Result"] = DRAW
                    rec["Black"] = "Draw"
                elif line.startswith('"#'):
                    rec["Result"] = WHITEWON
                    rec["Black"] = "Mate in %s" % line[2:-1]
                    rec["Termination"] = "mate in %s" % line[2:-1]

            elif line.startswith("solution:"):
                # TODO: solutions can be in several (sometimes rather unusual) form
                pass

            else:
                if in_authors:
                    author = line[line.find("-") + 1:].lstrip()
                    if rec["White"]:
                        rec["White"] = "%s - %s" % (rec["White"], author)
                    else:
                        rec["White"] = author

                elif in_white:
                    piece = line[line.find("-") + 1:].lstrip()
                    cord = Cord(piece[1:3]).cord
                    piece = chr2piece[piece[0]]
                    self.lboard._addPiece(cord, piece, WHITE)

                elif in_black:
                    piece = line[line.find("-") + 1:].lstrip()
                    cord = Cord(piece[1:3]).cord
                    piece = chr2piece[piece[0]]
                    self.lboard._addPiece(cord, piece, BLACK)

        # Append the latest record
        if rec is not None and rec["Black"].startswith("Mate in ") and not contains_fairy_pieces:
            games.append(rec)

        return games

    def loadToModel(self, rec, position, model=None):
        if not model:
            model = GameModel()

        model.tags['Event'] = rec["Event"]
        model.tags['Site'] = rec["Site"]
        model.tags['Date'] = self.get_date(rec)
        model.tags['Round'] = ""
        model.tags['White'] = "?"
        model.tags['Black'] = "?"
        model.tags['Termination'] = rec["Termination"]

        fen = rec["FEN"]

        model.boards = [model.variant(setup=fen)]
        model.variations = [model.boards]
        model.status = WAITING_TO_START

        return model

    def get_date(self, rec):
        year = rec['Year']
        month = rec['Month']
        day = rec['Day']
        if year and month and day:
            tag_date = "%s.%02d.%02d" % (year, int(month), int(day))
        elif year and month:
            tag_date = "%s.%02d" % (year, int(month))
        elif year:
            tag_date = "%s" % year
        else:
            tag_date = ""
        return tag_date