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
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
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
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
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