def step_through_moves(pos, line, is_our_move): global book global max_moves move = "" entries = [] if (is_our_move): fen = pos.fen old_line = line line = make_best_move(pos, line) if (line == '' or line.count(' ') > max_moves): pos = chess.Position(fen) return step_through_moves(pos, line, False) pos = chess.Position(fen) line = old_line else: for entry in book.get_entries_for_position(pos): entries.append(entry) for entry in entries: old_line = line line = add_move_to_line(entry.move, line) move = entry.move fen = pos.fen pos.make_move(chess.Move.from_uci(str(move))) step_through_moves(pos, line, True) pos = chess.Position(fen) line = old_line
def test_insufficient_material(self): """Tests material counting.""" # Starting position. pos = chess.Position() self.assertFalse(pos.is_insufficient_material()) # King vs. King + 2 bishops of the same color. pos = chess.Position("k1K1B1B1/8/8/8/8/8/8/8 w - - 7 32") self.assertTrue(pos.is_insufficient_material()) # Add a black bishop of the opposite color for the weaker side. pos["b8"] = chess.Piece("b") self.assertFalse(pos.is_insufficient_material())
def test_single_step_pawn_move(self): """Tests that single step pawn moves are possible.""" pos = chess.Position() a3 = chess.Move.from_uci('a2a3') self.assertTrue(a3 in pos.get_pseudo_legal_moves()) self.assertTrue(a3 in pos.get_legal_moves()) pos.make_move(a3)
def main(): global color global book global black global game_tree global white if (len(sys.argv) != 4): print "USAGE: parse_opening_books.py <polyglot book> <white|black> \"<opening line>\"\n" sys.exit(0) book = chess.PolyglotOpeningBook(sys.argv[1]) pos = chess.Position() i = 0 if (sys.argv[2].lower() == "black"): color = 1 opening_line = sys.argv[3] if (opening_line.lower() == "full"): process_full(pos) else: process_opening(pos, opening_line) clean_up() print_results()
def test_default_position(self): """Tests the default position.""" pos = chess.Position() self.assertEqual(pos[chess.Square('b1')], chess.Piece('N')) self.assertEqual( pos.fen, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1") self.assertEqual(pos.turn, "w")
def test_pawn_captures(self): """Tests pawn captures in the kings gambit.""" pos = chess.Position() pos.make_move(pos.get_move_from_san("e4")) pos.make_move(pos.get_move_from_san("e5")) pos.make_move(pos.get_move_from_san("f4")) accepted = chess.Position(pos) self.assertTrue( chess.Move.from_uci("e5f4") in accepted.get_pseudo_legal_moves()) self.assertTrue( chess.Move.from_uci("e5f4") in accepted.get_legal_moves()) accepted.make_move(accepted.get_move_from_san("exf4")) wierd_declined = chess.Position(pos) wierd_declined.make_move(wierd_declined.get_move_from_san("d5")) wierd_declined.make_move(wierd_declined.get_move_from_san("exd5"))
def test_move_info(self): """Tests move info generation.""" pos = chess.Position() e4 = pos.make_move(chess.Move.from_uci('e2e4')) self.assertEqual(e4.san, 'e4') self.assertFalse(e4.is_check) self.assertFalse(e4.is_checkmate) self.assertFalse(e4.is_castle)
def test_enpassant(self): """Test pawns captured en passant are removed.""" pos = chess.Position( "rnbqkbnr/pp2pppp/2p5/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 3") move_info = pos.make_move_from_san("exd6") self.assertTrue(move_info.is_enpassant) self.assertEqual( pos.fen, "rnbqkbnr/pp2pppp/2pP4/8/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 3")
def test_mainline(self): pos = chess.Position() book = chess.PolyglotOpeningBook("data/opening-books/performance.bin") while True: try: entry = book.get_entries_for_position(pos).next() pos.make_move(entry.move) except StopIteration: break
def test_get_set(self): """Tests the get and set methods.""" pos = chess.Position() self.assertEqual(pos["b1"], chess.Piece("N")) del pos["e2"] self.assertEqual(pos[chess.Square("e2")], None) pos[chess.Square("e4")] = chess.Piece("r") self.assertEqual(pos["e4"], chess.Piece("r"))
def test_ambigous_rank(self): """Tests ambigous rank in SANs.""" pos = chess.Position( "r1bqkb1r/pp1n1ppp/2p1pn2/6N1/3P4/3B4/PPP2PPP/R1BQK1NR w KQkq - 0 7" ) first_rank_move = pos.get_move_from_san("N1f3") self.assertEqual(first_rank_move, chess.Move.from_uci("g1f3")) fifth_rank_move = pos.get_move_from_san("N5f3") self.assertEqual(fifth_rank_move, chess.Move.from_uci("g5f3"))
def test_performance_bin(self): pos = chess.Position() book = chess.PolyglotOpeningBook("data/opening-books/performance.bin") e4 = book.get_entries_for_position(pos).next() self.assertEqual(e4.move, pos.get_move_from_san("e4")) pos.make_move(e4.move) e5 = book.get_entries_for_position(pos).next() self.assertEqual(e5.move, pos.get_move_from_san("e5")) pos.make_move(e5.move)
def test_scholars_mate(self): """Tests the scholars mate.""" pos = chess.Position() self.assertTrue(pos.has_queenside_castling_right("b")) e4 = chess.Move.from_uci('e2e4') self.assertTrue(e4 in pos.get_legal_moves()) pos.make_move(e4) self.assertTrue(pos.has_queenside_castling_right("b")) e5 = chess.Move.from_uci('e7e5') self.assertTrue(e5 in pos.get_legal_moves()) self.assertFalse(e4 in pos.get_legal_moves()) pos.make_move(e5) self.assertTrue(pos.has_queenside_castling_right("b")) Qf3 = chess.Move.from_uci('d1f3') self.assertTrue(Qf3 in pos.get_legal_moves()) pos.make_move(Qf3) self.assertTrue(pos.has_queenside_castling_right("b")) Nc6 = chess.Move.from_uci('b8c6') self.assertTrue(Nc6 in pos.get_legal_moves()) pos.make_move(Nc6) self.assertTrue(pos.has_queenside_castling_right("b")) Bc4 = chess.Move.from_uci('f1c4') self.assertTrue(Bc4 in pos.get_legal_moves()) pos.make_move(Bc4) self.assertTrue(pos.has_queenside_castling_right("b")) Rb8 = chess.Move.from_uci('a8b8') self.assertTrue(Rb8 in pos.get_legal_moves()) pos.make_move(Rb8) self.assertFalse(pos.has_queenside_castling_right("b")) self.assertFalse(pos.is_check()) self.assertFalse(pos.is_checkmate()) self.assertFalse(pos.is_game_over()) self.assertFalse(pos.is_stalemate()) Qf7_mate = chess.Move.from_uci('f3f7') self.assertTrue(Qf7_mate in pos.get_legal_moves()) pos.make_move(Qf7_mate) self.assertTrue(pos.is_check()) self.assertTrue(pos.is_checkmate()) self.assertTrue(pos.is_game_over()) self.assertFalse(pos.is_stalemate()) self.assertEqual( pos.fen, "1rbqkbnr/pppp1Qpp/2n5/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQk - 0 4")
def __init__(self, previous_node, move, nags=[], comment="", start_comment=""): self.__previous_node = previous_node self.__move = move if move: self.__position = chess.Position(previous_node.position) self.__position.make_move(move) self.__nags = nags self.comment = comment self.start_comment = start_comment self.__variations = []
def test_san_moves(self): """Tests making moves from SANs.""" pos = chess.Position() pos.make_move(pos.get_move_from_san('Nc3')) pos.make_move(pos.get_move_from_san('c5')) pos.make_move(pos.get_move_from_san('e4')) pos.make_move(pos.get_move_from_san('g6')) pos.make_move(pos.get_move_from_san('Nge2')) pos.make_move(pos.get_move_from_san('Bg7')) pos.make_move(pos.get_move_from_san('d3')) pos.make_move(pos.get_move_from_san('Bxc3')) pos.make_move(pos.get_move_from_san('bxc3')) self.assertEqual( pos.fen, 'rnbqk1nr/pp1ppp1p/6p1/2p5/4P3/2PP4/P1P1NPPP/R1BQKB1R b KQkq - 0 5' )
def test_ep_file(self): pos = chess.Position( "rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 2") self.assertEqual(pos.ep_file, "d")
def play_immortal_game(): pos = chess.Position() # 1.e4 e5 pos.make_move_from_san("e4") pos.make_move_from_san("e5") # 2.f4 exf4 pos.make_move_from_san("f4") pos.make_move_from_san("exf4") # 3.Bc4 Qh4+ pos.make_move_from_san("Bc4") pos.make_move_from_san("Qh4+") # 4.Kf1 b5?! pos.make_move_from_san("Kf1") pos.make_move_from_san("b5") # 5.Bxb5 Nf6 pos.make_move_from_san("Bxb5") pos.make_move_from_san("Nf6") # 6.Nf3 Qh6 pos.make_move_from_san("Nf3") pos.make_move_from_san("Qh6") # 7.d3 Nh5 pos.make_move_from_san("d3") pos.make_move_from_san("Nh5") # 8.Nh4 Qg5 pos.make_move_from_san("Nh4") pos.make_move_from_san("Qg5") # 9.Nf5 c6 pos.make_move_from_san("Nf5") pos.make_move_from_san("c6") # 10.g4 Nf6 pos.make_move_from_san("g4") pos.make_move_from_san("Nf6") # 11.Rg1! cxb5? pos.make_move_from_san("Rg1") pos.make_move_from_san("cxb5") # 12.h4! Qg6 pos.make_move_from_san("h4") pos.make_move_from_san("Qg6") # 13.h5 Qg5 pos.make_move_from_san("h5") pos.make_move_from_san("Qg5") # 14.Qf3 Ng8 pos.make_move_from_san("Qf3") pos.make_move_from_san("Ng8") # 15.Bxf4 Qf6 pos.make_move_from_san("Bxf4") pos.make_move_from_san("Qf6") # 16.Nc3 Bc5 pos.make_move_from_san("Nc3") pos.make_move_from_san("Bc5") # 17.Nd5 Qxb2 pos.make_move_from_san("Nd5") pos.make_move_from_san("Qxb2") # 18.Bd6! Bxg1? pos.make_move_from_san("Bd6") pos.make_move_from_san("Bxg1") # 19.e5! Qxa1+ pos.make_move_from_san("e5") pos.make_move_from_san("Qxa1+") # 20.Ke2 Na6 pos.make_move_from_san("Ke2") pos.make_move_from_san("Na6") # 21.Nxg7+ Kd8 pos.make_move_from_san("Nxg7+") pos.make_move_from_san("Kd8") # 22.Qf6+! Nxf6 pos.make_move_from_san("Qf6+") pos.make_move_from_san("Nxf6") # 23.Be7# 1-0 pos.make_move_from_san("Be7#") assert pos.is_checkmate()
def test_promotion_with_check(self): pos = chess.Position("8/6P1/2p5/1Pqk4/6P1/2P1RKP1/4P1P1/8 w - - 0 1") move_info = pos.make_move_from_san("g8=Q+") self.assertTrue(move_info.is_check) self.assertEqual(pos.fen, "6Q1/8/2p5/1Pqk4/6P1/2P1RKP1/4P1P1/8 b - - 0 1")
def position(self): """A copy of the position.""" return chess.Position(self.__position)
def test_pawn_move_generation(self): """Tests pawn move generation in a specific position from a Kasparov vs. Deep Blue game.""" pos = chess.Position("8/2R1P3/8/2pp4/2k1r3/P7/8/1K6 w - - 1 55") list(pos.get_pseudo_legal_moves())
def __setitem__(self, key, value): key = self.__normalize_key(key) if not isinstance(value, basestring): raise TypeError("Expected value to be a string, got: %s." % repr(value)) if key == "Date": matches = date_regex.match(value) if not matches: raise ValueError("Invalid value for Date header: %s." % repr(value)) year = matches.group(1) if matches.group(1) != "????" else "2000" month = int(matches.group(2)) if matches.group(2) != "??" else "10" day = int(matches.group(3)) if matches.group(3) != "??" else "1" datetime.date(int(year), int(month), int(day)) elif key == "Round": if not round_regex.match(value): raise ValueError("Invalid value for Round header: %s." % repr(value)) elif key == "Result": if not value in ["1-0", "0-1", "1/2-1/2", "*"]: raise ValueError("Invalid value for Result header: %s." % repr(value)) elif key == "PlyCount": if not value.isdigit(): raise ValueError("Invalid value for PlyCount header: %s." % repr(value)) else: value = str(int(value)) elif key == "TimeControl": if not time_control_regex.match(value): raise ValueError("Invalid value for TimeControl header: %s." % repr(value)) elif key == "Time": matches = time_regex.match(value) if (not matches or int(matches.group(1)) < 0 or int(matches.group(1)) >= 24 or int(matches.group(2)) < 0 or int(matches.group(2)) >= 60 or int(matches.group(3)) < 0 or int(matches.group(3)) >= 60): raise ValueError("Invalid value for Time header: %s." % repr(value)) elif key == "Termination": value = value.lower() if not value in [ "abandoned", "adjudication", "death", "emergency", "normal", "rules infraction", "time forfeit", "unterminated" ]: raise ValueError("Invalid value for Termination header: %s." % repr(value)) elif key == "Mode": value = value.upper() if not value in ["OTB", "ICS"]: raise ValueError("Invalid value for Mode header: %s." % repr(value)) elif key == "FEN": value = chess.Position(value).fen if value == chess.START_FEN: if not "FEN" in self: return else: if "FEN" in self and self["FEN"] == value: return if self.__game and self.__game.ply > 0: raise ValueError( "FEN header can not be set, when there are already moves.") if value == chess.START_FEN: del self["FEN"] del self["SetUp"] return else: self["SetUp"] = "1" self.__headers[key] = value
def read_eco(source): result = {} tokens = collections.deque() eco = None name = None position = chess.Position() state = 0 for lineno, unstripped_line in enumerate(source): # Skip emtpy lines and comments. line = unstripped_line.strip() if not line or line.startswith("#"): continue # Split line into tokens. tokens.extend(line.split()) # Consume tokens on the fly. while tokens: try: token = tokens.popleft() if state == 0: # State 0: Expecting ECO code. eco = token if eco in result: state = 4 else: state = 1 elif state == 1: # State 1: Expecting variation name. if not token.startswith("\""): name = token state = 3 elif not token.endswith("\""): name = token[1:] state = 2 else: name = token[1:-1] state = 3 elif state == 2: # State 2: Expecting rest of a quoted name. if not token.endswith("\""): name += " " + token else: name += " " + token[:-1] state = 3 elif state == 3: # State 3: Expecting moves. if token == "*": result[eco] = { "eco": eco, "fen": position.fen, "hash": position.__hash__(), "name": name, } state = 0 eco = None name = None position = chess.Position() else: san = token.split(".")[-1] if san in ["0-0", "o-o"]: san = "O-O" elif san in ["0-0-0", "o-o-o"]: san = "O-O-O" position.make_move_from_san(san) elif state == 4: # State 4: Waiting for end of record. if token == "*": state = 0 except: # Dump last line and token. sys.stderr.write("Line %d:\n" % (lineno + 1, )) sys.stderr.write(" ") sys.stderr.write(unstripped_line) sys.stderr.write(" ") sys.stderr.write(" " * unstripped_line.index(token)) sys.stderr.write("^" * len(token)) sys.stderr.write("\n") # Dump current variables. sys.stderr.write("State: %d\n" % state) sys.stderr.write("ECO: %s\n" % eco) sys.stderr.write("FEN: %s\n" % position.fen) sys.stderr.write("Name: %s\n" % name) sys.stderr.flush() raise return result