def test_gating_castle_at_rook_wOO(self): FEN = "r2qk2r/pppbbppp/4pn2/1N1p4/1n1P4/4PN2/PPPBBPPP/R2QK2R[heHE] w KQkq - 10 8" board = LBoard(SCHESS) board.applyFen(FEN) moves = set() for move in genAllMoves(board): moves.add(toAN(board, move)) print("--------") print(board) self.assertIn("h1e1h", moves) self.assertIn("h1e1e", moves) self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O/Hh1'))), 'h1e1h') self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O/Eh1'))), 'h1e1e') self.assertEqual(toSAN(board, newMove(H1, E1, HAWK_GATE_AT_ROOK)), "O-O/Hh1") self.assertEqual(toSAN(board, newMove(H1, E1, ELEPHANT_GATE_AT_ROOK)), "O-O/Eh1") fen = board.asFen() move = parseAN(board, "h1e1e") board.applyMove(move) print("h1e1e") print(board) self.assertEqual(placement(board.asFen()), "r2qk2r/pppbbppp/4pn2/1N1p4/1n1P4/4PN2/PPPBBPPP/R2Q1RKE[heH]") board.popMove() self.assertEqual(placement(board.asFen()), placement(fen))
def test_gating_king_move(self): board = LBoard(SCHESS) board.applyFen(SCHESSSTART) for move in "e2e3 e7e5 d1h5 d8e7 h5g4 b8c6 g1f3 d7d5 g4h4 e7c5 h4a4 e5e4 d2d4 c5e7 f3d2 e7b4 a4b4 c6b4".split(): board.applyMove(parseAN(board, move)) print("--------") print(board) moves = set() for move in genAllMoves(board): moves.add(toAN(board, move)) self.assertIn("e1d1e", moves) self.assertIn("e1d1h", moves) fen = board.asFen() move = parseAN(board, "e1d1e") board.applyMove(move) print("e1d1e") print(board) self.assertEqual(placement(board.asFen()), "r1b1kbnr/ppp2ppp/8/3p4/1n1Pp3/4P3/PPPN1PPP/RNBKEB1R[heH]") board.popMove() self.assertEqual(placement(board.asFen()), placement(fen))
def test_gating_castle_at_rook_bOO(self): board = LBoard(SCHESS) board.applyFen(SCHESSSTART) for move in "e2e3 e7e6 g1f3 c7c6 c2c3 d7d5 d2d4 g8f6 h2h3 f6e4 d1c2 b8d7 f1d3 f7f5 e1g1e d8c7 e1e2 f8e7 c2d1".split(): board.applyMove(parseAN(board, move)) moves = set() for move in genAllMoves(board): moves.add(toAN(board, move)) print("--------") print(board) self.assertIn("h8e8h", moves) self.assertIn("h8e8e", moves) fen = board.asFen() move = parseAN(board, "h8e8h") board.applyMove(move) print("h8e8e") print(board) self.assertEqual(placement(board.asFen()), "r1b2rkh/ppqnb1pp/2p1p3/3p1p2/3Pn3/2PBPN1P/PP2EPP1/RNBQ1RK1[eH]") board.popMove() self.assertEqual(placement(board.asFen()), placement(fen))
def test_gating_castle_at_rook_wOOO(self): board = LBoard(SCHESS) board.applyFen(SCHESSSTART) for move in "e2e4 d7d6 d1e2 c8d7 g1f3 g8f6 e4e5 f6d5 e2e4 d5b6 d2d3 d7c6 e4f5 c6d7 f5g5 g7g6 f3d4 h7h5 g5f4 d6e5 f4h4 f8g7 d4f3 d7g4 b1c3 f7f6 c3e4 d8d5 e4c3 d5c5 c1e3 c5d6 h2h3 g4f3 g2f3 e8g8h".split(): board.applyMove(parseAN(board, move)) moves = set() for move in genAllMoves(board): moves.add(toAN(board, move)) print("--------") print(board) self.assertIn("a1e1h", moves) self.assertIn("a1e1e", moves) fen = board.asFen() parseAN(board, "a1e1e") board.applyMove(move) print("a1e1e") print(board) self.assertEqual(placement(board.asFen()), "rn2hrk1/ppp1p1b1/1n1q1pp1/4p2p/7Q/2NPBP1P/PPP2P2/E1KR1B1R[eH]") board.popMove() self.assertEqual(placement(board.asFen()), placement(fen))
def testFEN(self): """Testing board-FEN conversion with several positions""" for i, fenstr in enumerate(self.positions[1:]): board = LBoard() board.applyFen(fenstr) fenstr2 = board.asFen() self.assertEqual(fenstr, fenstr2)
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 test_default_gating_avail(self): board = LBoard(SCHESS) board.applyFen(SCHESSSTART) print(board) print(toString(board.virgin[0])) print(toString(board.virgin[1])) self.assertEqual(board.virgin[0], brank8[1]) self.assertEqual(board.virgin[1], brank8[0]) board = LBoard(SCHESS) FEN = "r1hqerk1/pp1nbppp/2pp1nb1/4p3/2PPP3/2N1B1PP/PP2NPB1/RH1QK2R/E w KQHEDA - 2 10" board.applyFen(FEN) print("-----------") print(board) move = parseSAN(board, "O-O") board.applyMove(move) castl = board.asFen().split()[2] self.assertNotIn("Q", castl) self.assertNotIn("K", castl) self.assertNotIn("E", castl) self.assertNotIn("H", castl)
def as_fen(self, variant): fenstr = [] for r, row in enumerate(reversed(self.data)): empty = 0 for i in range(0, 8): piece = row.get(i) if piece is not None: if empty > 0: fenstr.append(str(empty)) empty = 0 sign = reprSign[piece.piece] if piece.color == BLACK: sign = sign.lower() else: sign = sign.upper() fenstr.append(sign) else: empty += 1 if empty > 0: fenstr.append(str(empty)) if r != 7: fenstr.append("/") board = LBoard(variant) board.applyFen("".join(fenstr) + " w") return board.asFen().split()[0]
def testFEN(self): """Testing board-FEN conversion with several positions""" print board = LBoard(Board) for i, fenstr in enumerate(self.positions[1:]): sys.stdout.write("#") board.applyFen(fenstr) fenstr2 = board.asFen() self.assertEqual(fenstr, fenstr2) print
def testFEN(self): """Testing board-FEN conversion with several positions""" positions = [] with open('gamefiles/perftsuite.epd') as f: for line in f: semi = line.find(" ;") positions.append(line[:semi]) for i, fenstr in enumerate(positions[1:]): board = LBoard() board.applyFen(fenstr) fenstr2 = board.asFen() self.assertEqual(fenstr, fenstr2)
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 test_moves_from_startpos(self): board = LBoard(SCHESS) board.applyFen(SCHESSSTART) moves = set() for move in genAllMoves(board): moves.add(toAN(board, move)) board.applyMove(move) board.popMove() self.assertEqual(placement(board.asFen()), placement(SCHESSSTART)) self.assertIn("b1a3e", moves) self.assertIn("b1a3h", moves) self.assertIn("b1c3e", moves) self.assertIn("b1c3h", moves) self.assertIn("g1f3e", moves) self.assertIn("g1f3h", moves) self.assertIn("g1h3e", moves) self.assertIn("g1h3h", moves)
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 OpeningTreePanel(Gtk.TreeView): def __init__(self, persp): GObject.GObject.__init__(self) self.persp = persp self.filtered = False self.persp.connect("chessfile_imported", self.on_chessfile_imported) self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.liststore = Gtk.ListStore(int, str, int, int) self.modelsort = Gtk.TreeModelSort(self.liststore) self.modelsort.set_sort_column_id(2, Gtk.SortType.DESCENDING) self.set_model(self.modelsort) self.set_headers_visible(True) column = Gtk.TreeViewColumn(_("Move"), Gtk.CellRendererText(), text=1) column.set_sort_column_id(1) column.connect("clicked", self.column_clicked, 1) self.append_column(column) column = Gtk.TreeViewColumn(_("Games"), Gtk.CellRendererText(), text=2) column.set_sort_column_id(2) column.connect("clicked", self.column_clicked, 2) self.append_column(column) column = Gtk.TreeViewColumn(_("Winning %"), Gtk.CellRendererProgress(), value=3) column.set_min_width(80) column.set_sort_column_id(3) column.connect("clicked", self.column_clicked, 3) self.append_column(column) self.conid = self.connect_after("row-activated", self.row_activated) self.board = LBoard() self.board.applyFen(FEN_START) self.columns_autosize() sw = Gtk.ScrolledWindow() sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) sw.add(self) self.box.pack_start(sw, True, True, 0) # buttons toolbar = Gtk.Toolbar() firstButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_PREVIOUS) toolbar.insert(firstButton, -1) prevButton = Gtk.ToolButton(stock_id=Gtk.STOCK_MEDIA_REWIND) toolbar.insert(prevButton, -1) self.filterButton = Gtk.ToggleToolButton(Gtk.STOCK_FIND) self.filterButton.set_tooltip_text( _("Filter game list by opening moves")) toolbar.insert(self.filterButton, -1) firstButton.connect("clicked", self.on_first_clicked) prevButton.connect("clicked", self.on_prev_clicked) self.filterButton.connect("clicked", self.on_filter_clicked) tool_box = Gtk.Box() tool_box.pack_start(toolbar, False, False, 0) self.box.pack_start(tool_box, False, False, 0) self.box.show_all() def on_chessfile_imported(self, persp, chessfile): self.update_tree() def on_first_clicked(self, widget): while self.board.hist_move: self.board.popMove() self.update_tree() def on_prev_clicked(self, widget): if self.board.hist_move: self.board.popMove() self.update_tree() def on_filter_clicked(self, button): self.filtered = button.get_active() if not self.filtered: self.persp.filter_panel.filterButton.set_sensitive(True) self.filtered = True while self.board.hist_move: self.board.popMove() self.update_tree() self.filtered = False else: self.persp.filter_panel.filterButton.set_sensitive(False) self.update_tree() def column_clicked(self, col, data): self.set_search_column(data) def row_activated(self, widget, path, col): lmove = self.liststore[self.modelsort.convert_path_to_child_path(path) [0]][0] self.board.applyMove(lmove) self.update_tree() def update_tree(self, load_games=True): self.persp.gamelist.ply = self.board.plyCount if load_games and self.filtered: self.persp.chessfile.set_fen_filter(self.board.asFen()) self.persp.gamelist.load_games() result = self.persp.chessfile.get_book_moves(self.board.asFen()) self.clear_tree() for move, count, white_won, blackwon, draw in result: lmove = parseAN(self.board, move) perf = 0 if not count else round( (white_won * 100. + draw * 50.) / count) self.liststore.append( [lmove, toSAN(self.board, lmove), count, perf]) def clear_tree(self): selection = self.get_selection() if self.conid is not None and selection.handler_is_connected( self.conid): with GObject.signal_handler_block(selection, self.conid): self.liststore.clear() else: self.liststore.clear()
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