예제 #1
0
    def run(cls, fenstr, variant):
        cls._ensureReady()
        if cls.widgets["newgamedialog"].props.visible:
            cls.widgets["newgamedialog"].present()
            return

        cls._hideOthers()
        for button in ("copy_button", "clear_button", "paste_button", "initial_button"):
            cls.widgets[button].show()
        cls.widgets["newgamedialog"].set_title(_("Setup Position"))
        cls.widgets["setupPositionSidePanel"].show()

        cls.setupmodel = SetupModel()
        cls.board_control = BoardControl(cls.setupmodel,
                                         {},
                                         setup_position=True)
        cls.setupmodel.curplayer = SetupPlayer(cls.board_control)
        cls.setupmodel.connect("game_changed", cls.game_changed)

        child = cls.widgets["setupBoardDock"].get_child()
        if child is not None:
            cls.widgets["setupBoardDock"].remove(child)
        cls.widgets["setupBoardDock"].add(cls.board_control)
        cls.board_control.show_all()
        if fenstr is not None:
            lboard = LBoard(variant)
            lboard.applyFen(fenstr)
            cls.setupmodel.boards = [cls.setupmodel.variant(setup=fenstr, lboard=lboard)]
            cls.setupmodel.variations = [cls.setupmodel.boards]
            cls.ini_widgets(fenstr, lboard)
        else:
            fenstr = cls.get_fen()
            cls.ini_widgets(True)
        cls.widgets["fen_entry"].set_text(fenstr)

        cls.setupmodel.start()
        cls.board_control.emit("action", "SETUP", None, fenstr)

        def _validate(gamemodel):
            try:
                fenstr = cls.get_fen()
                cls.setupmodel.variant(setup=fenstr)
                return True
            except (AssertionError, LoadingError, SyntaxError) as e:
                d = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.WARNING,
                                      buttons=Gtk.ButtonsType.OK,
                                      message_format=e.args[0])
                if len(e.args) > 1:
                    d.format_secondary_text(e.args[1])
                d.connect("response", lambda d, a: d.hide())
                d.show()
                return False

        def _callback(gamemodel, p0, p1):
            text = cls.get_fen()
            perspective = perspective_manager.get_perspective("games")
            create_task(perspective.generalStart(
                gamemodel, p0, p1, (StringIO(text), fen, 0, -1)))

        cls._generalRun(_callback, _validate)
예제 #2
0
def benchmark(maxdepth=6):
    """ Times a search of a static list of positions. """

    suite_time = time()
    suite_nodes = lsearch.nodes
    lsearch.endtime = sys.maxsize
    lsearch.searching = True
    for i, fen in enumerate(benchmarkPositions):
        lsearch.table.clear()
        clearPawnTable()
        board = LBoard(NORMALCHESS)
        board.applyFen(fen)
        pos_start_time = time()
        pos_start_nodes = lsearch.nodes
        for depth in range(1, maxdepth):
            mvs, scr = lsearch.alphaBeta(board, depth)
            pos_time = time() - pos_start_time
            pos_nodes = lsearch.nodes - pos_start_nodes
            pv = " ".join(listToSan(board, mvs))
            time_cs = int(100 * pos_time)
            print(depth, scr, time_cs, pos_nodes, pv)
        print("Searched position", i, "at",
              int(pos_nodes / pos_time) if pos_time > 0 else pos_nodes, "n/s")
    suite_time = time() - suite_time
    suite_nodes = lsearch.nodes - suite_nodes
    print("Total:", suite_nodes, "nodes in", suite_time, "s: ",
          suite_nodes / suite_time, "n/s")
    lsearch.nodes = 0
    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]
예제 #4
0
    def testPolyglot_1(self):
        """Testing hash keys agree with Polyglot's"""

        for testcase in testcases:
            board = LBoard(Board)
            board.applyFen(testcase[0])
            self.assertEqual(board.hash, testcase[1])
예제 #5
0
def benchmark(maxdepth=6):
    """ Times a search of a static list of positions. """

    suite_time = time()
    suite_nodes = lsearch.nodes
    lsearch.endtime = sys.maxsize
    lsearch.searching = True
    for i, fen in enumerate(benchmarkPositions):
        lsearch.table.clear()
        clearPawnTable()
        board = LBoard(NORMALCHESS)
        board.applyFen(fen)
        pos_start_time = time()
        pos_start_nodes = lsearch.nodes
        for depth in range(1, maxdepth):
            mvs, scr = lsearch.alphaBeta(board, depth)
            pos_time = time() - pos_start_time
            pos_nodes = lsearch.nodes - pos_start_nodes
            pv = " ".join(listToSan(board, mvs))
            time_cs = int(100 * pos_time)
            print(depth, scr, time_cs, pos_nodes, pv)
        print("Searched position", i, "at", int(pos_nodes / pos_time) if pos_time > 0 else pos_nodes, "n/s")
    suite_time = time() - suite_time
    suite_nodes = lsearch.nodes - suite_nodes
    print("Total:", suite_nodes, "nodes in", suite_time, "s: ", suite_nodes /
          suite_time, "n/s")
    lsearch.nodes = 0
예제 #6
0
파일: fen.py 프로젝트: vgupta2507/pychess
 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)
예제 #7
0
    def testPolyglot_1(self):
        """Testing hash keys agree with Polyglot's"""

        for testcase in testcases:
            board = LBoard(Board)
            board.applyFen(testcase[0])
            self.assertEqual(board.hash, testcase[1])
예제 #8
0
파일: fen.py 프로젝트: CarbonFixer/pychess
 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)
예제 #9
0
    def run(cls, fenstr, variant):
        cls._ensureReady()
        if cls.widgets["newgamedialog"].props.visible:
            cls.widgets["newgamedialog"].present()
            return

        cls._hideOthers()
        for button in ("copy_button", "clear_button", "paste_button", "initial_button"):
            cls.widgets[button].show()
        cls.widgets["newgamedialog"].set_title(_("Setup Position"))
        cls.widgets["setupPositionSidePanel"].show()

        cls.setupmodel = SetupModel()
        cls.board_control = BoardControl(cls.setupmodel,
                                         {},
                                         setup_position=True)
        cls.setupmodel.curplayer = SetupPlayer(cls.board_control)
        cls.setupmodel.connect("game_changed", cls.game_changed)

        child = cls.widgets["setupBoardDock"].get_child()
        if child is not None:
            cls.widgets["setupBoardDock"].remove(child)
        cls.widgets["setupBoardDock"].add(cls.board_control)
        cls.board_control.show_all()
        if fenstr is not None:
            lboard = LBoard(variant)
            lboard.applyFen(fenstr)
            cls.setupmodel.boards = [cls.setupmodel.variant(setup=fenstr, lboard=lboard)]
            cls.setupmodel.variations = [cls.setupmodel.boards]
            cls.ini_widgets(fenstr, lboard)
        else:
            fenstr = cls.get_fen()
            cls.ini_widgets(True)
        cls.widgets["fen_entry"].set_text(fenstr)

        cls.setupmodel.start()

        def _validate(gamemodel):
            try:
                fenstr = cls.get_fen()
                cls.setupmodel.variant(setup=fenstr)
                return True
            except (AssertionError, LoadingError, SyntaxError) as e:
                d = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.WARNING,
                                      buttons=Gtk.ButtonsType.OK,
                                      message_format=e.args[0])
                if len(e.args) > 1:
                    d.format_secondary_text(e.args[1])
                d.connect("response", lambda d, a: d.hide())
                d.show()
                return False

        def _callback(gamemodel, p0, p1):
            text = cls.get_fen()
            perspective = perspective_manager.get_perspective("games")
            create_task(perspective.generalStart(
                gamemodel, p0, p1, (StringIO(text), fen, 0, -1)))

        cls._generalRun(_callback, _validate)
예제 #10
0
    def test_toSAN(self):
        """ Testing toSAN() with giveaway king move """

        board = LBoard(GIVEAWAYCHESS)
        board.applyFen("4R3/8/7B/2P5/8/8/PP5k/6k1 b - - 0 28")

        self.assertEqual(toSAN(board, newMove(G1, G2)), "Kgg2")
        self.assertEqual(toSAN(board, newMove(H2, G2)), "Khg2")
예제 #11
0
파일: seirawan.py 프로젝트: ypeng22/pychess
    def test_gating_san_move(self):
        board = LBoard(SCHESS)
        board.applyFen(SCHESSSTART)

        self.assertEqual(repr(Move.Move(parseSAN(board, 'Nf3/H'))), 'g1f3h')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'Nf3/E'))), 'g1f3e')

        self.assertEqual(toSAN(board, newMove(G1, F3, HAWK_GATE)), "Nf3/H")
        self.assertEqual(toSAN(board, newMove(G1, F3, ELEPHANT_GATE)), "Nf3/E")
예제 #12
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
예제 #13
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
예제 #14
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
예제 #15
0
    def test_paresSAN2(self):
        """Testing parseAN and parseSAN with bad promotions moves"""
        
        board = LBoard()
        board.applyFen("4k3/P7/8/8/8/8/8/4K3 w - - 0 1")        

        self.assertRaises(ParsingError, parseAN, board, 'a7a8K')
        self.assertRaises(ParsingError, parseAN, board, 'a7a8')

        self.assertRaises(ParsingError, parseSAN, board, 'a8K')
        self.assertRaises(ParsingError, parseSAN, board, 'a8')
예제 #16
0
    def test_paresSAN2(self):
        """Testing parseAN and parseSAN with bad promotions moves"""

        board = LBoard()
        board.applyFen("4k3/P7/8/8/8/8/8/4K3 w - - 0 1")

        self.assertRaises(ParsingError, parseAN, board, 'a7a8K')
        # If promotion piece is missing pychess assumes queen promotion from 0.99.2
        # self.assertRaises(ParsingError, parseAN, board, 'a7a8')

        self.assertRaises(ParsingError, parseSAN, board, 'a8K')
예제 #17
0
파일: move.py 프로젝트: vgupta2507/pychess
    def test_paresSAN2(self):
        """Testing parseAN and parseSAN with bad promotions moves"""

        board = LBoard()
        board.applyFen("4k3/P7/8/8/8/8/8/4K3 w - - 0 1")

        self.assertRaises(ParsingError, parseAN, board, 'a7a8K')
        self.assertRaises(ParsingError, parseAN, board, 'a7a8')

        self.assertRaises(ParsingError, parseSAN, board, 'a8K')
        self.assertRaises(ParsingError, parseSAN, board, 'a8')
예제 #18
0
    def testFRCCastlingUCI(self):
        """Testing UCI engine FRC castling move"""
        print()

        fen = "rbq1krb1/pp1pp1pp/2p1n3/5p2/2PP1P1n/4B1N1/PP2P1PP/RBQNKR2 w FAfa - 2 6"
        print(fen)
        board = LBoard(FISCHERRANDOMCHESS)
        board.applyFen(fen)
        # print board
        moves = [move for move in genCastles(board)]
        self.assertTrue(parseAN(board, "e1g1") in moves)
예제 #19
0
    def testFRCCastlingUCI(self):
        """Testing UCI engine FRC castling move"""
        print()

        fen = "rbq1krb1/pp1pp1pp/2p1n3/5p2/2PP1P1n/4B1N1/PP2P1PP/RBQNKR2 w FAfa - 2 6"
        print(fen)
        board = LBoard(FISCHERRANDOMCHESS)
        board.applyFen(fen)
        # print board
        moves = [move for move in genCastles(board)]
        self.assertTrue(parseAN(board, "e1g1") in moves)
예제 #20
0
파일: seirawan.py 프로젝트: ypeng22/pychess
    def test_gating_castle_at_rook_wOOO_SAN(self):
        FEN = "r2ek2r/5pp1/1pp1pnp1/2pp1h2/3P4/2P1PP2/PP1N2PP/R3K1HR/E w KQHEAkq - 2 16"
        board = LBoard(SCHESS)
        board.applyFen(FEN)

        self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O-O'))), 'e1c1')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O-O/Ea1'))), 'a1e1e')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O-O/Ee1'))), 'e1c1e')

        self.assertEqual(toSAN(board, newMove(E1, C1, QUEEN_CASTLE)), "O-O-O")
        self.assertEqual(toSAN(board, newMove(A1, E1, ELEPHANT_GATE_AT_ROOK)), "O-O-O/Ea1")
        self.assertEqual(toSAN(board, newMove(E1, C1, ELEPHANT_GATE)), "O-O-O/Ee1")
예제 #21
0
    def add_variation(self, board, moves, comment="", score="", emit=True):
        board0 = board
        board = board0.clone()
        board.board.prev = None

        # this prevents annotation panel node searches to find this instead of board0
        board.board.hash = -1

        if comment:
            board.board.children.append(comment)

        variation = [board]

        for move in moves:
            new = board.move(move)
            if len(variation) == 1:
                new.board.prev = board0.board
                variation[0].board.next = new.board
            else:
                new.board.prev = board.board
                board.board.next = new.board
            variation.append(new)
            board = new

        if board0.board.next is None:
            # If we are in the latest played board, and want to add a variation
            # we have to add a not played yet board first
            # which can hold the variation as his child
            from pychess.Utils.lutils.LBoard import LBoard
            null_board = LBoard()
            null_board.prev = board0.board
            board0.board.next = null_board

        board0.board.next.children.append(
            [vboard.board for vboard in variation])
        if score:
            variation[-1].board.children.append(score)

        head = None
        for vari in self.variations:
            if board0 in vari:
                head = vari
                break

        variation[0] = board0
        self.variations.append(head[:board0.ply - self.lowply] + variation)
        self.needsSave = True
        if emit:
            self.emit("variation_added", board0.board.next.children[-1],
                      board0.board.next)
        return self.variations[-1]
예제 #22
0
파일: fen.py 프로젝트: zhaoshaojun/pychess
    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)
예제 #23
0
    def feed_book(self, records, positions):
        BOOK_DEPTH_MAX = conf.get("book_depth_max")

        for rec in records:
            model = GameModel()

            if rec["Result"] == DRAW:
                score = (1, 1)
            elif rec["Result"] == WHITEWON:
                score = (2, 0)
            elif rec["Result"] == BLACKWON:
                score = (0, 2)
            else:
                score = (0, 0)

            fenstr = rec["FEN"]
            variant = self.chessfile.get_variant(rec)

            if variant:
                model.variant = name2variant[variant]
                board = LBoard(model.variant.variant)
            else:
                model.variant = NormalBoard
                board = LBoard()

            if fenstr:
                try:
                    board.applyFen(fenstr)
                except SyntaxError:
                    continue
            else:
                board.applyFen(FEN_START)

            boards = [board]

            movetext = self.chessfile.get_movetext(rec)
            boards = self.chessfile.parse_movetext(movetext, boards[0], -1)

            for board in boards:
                if board.plyCount > BOOK_DEPTH_MAX:
                    break
                move = board.lastMove
                if move is not None:
                    poly_move = toPolyglot(board.prev, move)
                    # move_str = "%s%s" % (reprCord[FCORD(move)], reprCord[TCORD(move)])
                    # print("%0.16x" % board.prev.hash, poly_move, board.prev.asFen(), move_str)
                    if board.prev.hash in positions:
                        if poly_move in positions[board.prev.hash]:
                            positions[board.prev.hash][poly_move] += score[
                                board.prev.color
                            ]
                        else:
                            positions[board.prev.hash][poly_move] = score[
                                board.prev.color
                            ]
                    else:
                        # board.prev.asFen(), move_str,
                        positions[board.prev.hash] = {
                            poly_move: score[board.prev.color]
                        }
예제 #24
0
파일: seirawan.py 프로젝트: ypeng22/pychess
    def test_promotion(self):
        # promotion moves
        FEN = "r4knr/1bpp1Pp1/pp3b2/q2pep1p/3N4/P1N5/1PPQBPPP/R1B1K2R[hHE] w KQ - 1 17"
        board = LBoard(SCHESS)
        board.applyFen(FEN)
        print("--------")
        print(board)

        moves = set()
        for move in genAllMoves(board):
            moves.add(toAN(board, move))

        self.assertIn("f7g8=H", moves)
        self.assertIn("f7g8=E", moves)
예제 #25
0
    def add_variation(self, board, moves, comment="", score="", emit=True):
        board0 = board
        board = board0.clone()
        board.board.prev = None

        # this prevents annotation panel node searches to find this instead of board0
        board.board.hash = -1

        if comment:
            board.board.children.append(comment)

        variation = [board]

        for move in moves:
            new = board.move(move)
            if len(variation) == 1:
                new.board.prev = board0.board
                variation[0].board.next = new.board
            else:
                new.board.prev = board.board
                board.board.next = new.board
            variation.append(new)
            board = new

        if board0.board.next is None:
            # If we are in the latest played board, and want to add a variation
            # we have to add a not played yet board first
            # which can hold the variation as his child
            from pychess.Utils.lutils.LBoard import LBoard
            null_board = LBoard()
            null_board.prev = board0.board
            board0.board.next = null_board

        board0.board.next.children.append(
            [vboard.board for vboard in variation])
        if score:
            variation[-1].board.children.append(score)

        head = None
        for vari in self.variations:
            if board0 in vari:
                head = vari
                break

        variation[0] = board0
        self.variations.append(head[:board0.ply - self.lowply] + variation)
        self.needsSave = True
        if emit:
            self.emit("variation_added", board0.board.next.children[-1], board0.board.next)
        return self.variations[-1]
예제 #26
0
    def test_paresSAN1(self):
        """Testing parseSAN with unambiguous notations variants"""

        board = LBoard()
        board.applyFen("4k2B/8/8/8/8/8/8/B3K3 w - - 0 1")

        self.assertEqual(repr(Move(parseSAN(board, 'Ba1b2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bh8b2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'Bab2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bhb2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'B1b2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'B8b2'))), 'h8b2')

        board = LBoard()
        board.applyFen("4k2B/8/8/8/8/8/1b6/B3K3 w - - 0 1")

        self.assertEqual(repr(Move(parseSAN(board, 'Ba1xb2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bh8xb2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'Baxb2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bhxb2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'B1xb2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'B8xb2'))), 'h8b2')
예제 #27
0
    def testFRCCastling(self):
        """Testing FRC castling movegen"""
        print()

        for fen, castles in data:
            print(fen)
            board = LBoard(FISCHERRANDOMCHESS)
            board.applyFen(fen)
            # print board
            moves = [move for move in genCastles(board)]
            self.assertEqual(len(moves), len(castles))
            for i, castle in enumerate(castles):
                kfrom, kto, flag = castle
                self.assertEqual(moves[i], newMove(kfrom, kto, flag))
예제 #28
0
    def testFRCCastling(self):
        """Testing FRC castling movegen"""
        print()

        for fen, castles in data:
            print(fen)
            board = LBoard(FISCHERRANDOMCHESS)
            board.applyFen(fen)
            # print board
            moves = [move for move in genCastles(board)]
            self.assertEqual(len(moves), len(castles))
            for i, castle in enumerate(castles):
                kfrom, kto, flag = castle
                self.assertEqual(moves[i], newMove(kfrom, kto, flag))
예제 #29
0
class EvalTestCase(unittest.TestCase):
    
    def setUp (self):
        self.board = LBoard(NORMALCHESS)
        self.board.applyFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w - - 0 1")
    
    def test1(self):
        """Testing eval symmetry with startboard (WHITE)"""
        score = evaluateComplete(self.board, color=WHITE)
        self.assertEqual(score, 0)
    
    def test2(self):
        """Testing eval symmetry with startboard (BLACK)"""
        score = evaluateComplete(self.board, color=BLACK)
        self.assertEqual(score, 0)
    
    def test3(self):
        """Testing eval symmetry of each function"""
        funcs = (f for f in dir(leval) if f.startswith("eval"))
        funcs = (getattr(leval,f) for f in funcs)
        funcs = (f for f in funcs if callable(f) \
                                    and f != leval.evaluateComplete\
                                    and f != leval.evalMaterial\
                                    and f != leval.evalPawnStructure\
                                    and f != leval.evalTrappedBishops)
        
        sw, phasew = leval.evalMaterial (self.board, WHITE)
        sb, phaseb = leval.evalMaterial (self.board, BLACK)

        self.assertEqual(phasew, phaseb)
        
        pawnScore, passed, weaked = leval.cacheablePawnInfo (self.board, phasew)
        sw = leval.evalPawnStructure (self.board, WHITE, phasew, passed, weaked)

        pawnScore, passed, weaked = leval.cacheablePawnInfo (self.board, phaseb)
        sb = leval.evalPawnStructure (self.board, BLACK, phaseb, passed, weaked)

        self.assertEqual(sw, sb)

        sw = leval.evalTrappedBishops (self.board, WHITE)
        sb = leval.evalTrappedBishops (self.board, BLACK)

        self.assertEqual(sw, sb)

        for func in funcs:
            sw = func(self.board, WHITE, phasew)
            sb = func(self.board, BLACK, phaseb)
            #print func, sw, sb
            self.assertEqual(sw, sb)
예제 #30
0
파일: movegen.py 프로젝트: bboutkov/pychess
    def movegen(self, positions, variant):
        for i, (fen, depths) in enumerate(positions):
            print(i + 1, "/", len(positions), "-", fen)
            board = LBoard(variant)
            board.applyFen(fen)
            hash = board.hash

            for depth, suposedMoveCount in depths:
                if depth > self.MAXDEPTH:
                    break
                self.count = 0
                print("searching depth %d for %d moves" % (depth, suposedMoveCount))
                self.perft(board, depth, [])
                self.assertEqual(board.hash, hash)
                self.assertEqual(self.count, suposedMoveCount)
예제 #31
0
    def movegen(self, positions, variant):
        for i, (fen, depths) in enumerate(positions):
            print(i + 1, "/", len(positions), "-", fen)
            board = LBoard(variant)
            board.applyFen(fen)
            hash = board.hash

            for depth, suposedMoveCount in depths:
                if depth > self.MAXDEPTH:
                    break
                self.count = 0
                print("searching depth %d for %d moves" % (depth, suposedMoveCount))
                self.perft(board, depth, [])
                self.assertEqual(board.hash, hash)
                self.assertEqual(self.count, suposedMoveCount)
예제 #32
0
    def test_parseFAN(self):
        """Testing parseFAN"""

        board = LBoard()
        board.applyFen("rnbqkbnr/8/8/8/8/8/8/RNBQKBNR w KQkq - 0 1")        

        for lmove in genAllMoves(board):
            board.applyMove(lmove)
            if board.opIsChecked():
                board.popMove()
                continue

            board.popMove()

            fan = toFAN(board, lmove)
            self.assertEqual(parseFAN(board, fan), lmove)
예제 #33
0
    def test_white_promotion(self):
        FEN = "k7/7P/8/8/8/8/8/7K w - - 0 1"
        board = LBoard(LIGHTBRIGADECHESS)
        board.applyFen(FEN)
        print("--------")
        print(board)

        moves = set()
        for move in genAllMoves(board):
            moves.add(toAN(board, move))

        self.assertIn("h7h8=Q", moves)
        self.assertNotIn("h7h8", moves)
        self.assertNotIn("h7h8=R", moves)
        self.assertNotIn("h7h8=B", moves)
        self.assertNotIn("h7h8=N", moves)
        self.assertNotIn("h7h8=K", moves)
예제 #34
0
    def test_black_promotion(self):
        FEN = "k7/8/8/8/8/8/p7/7K b - - 0 1"
        board = LBoard(LIGHTBRIGADECHESS)
        board.applyFen(FEN)
        print("--------")
        print(board)

        moves = set()
        for move in genAllMoves(board):
            moves.add(toAN(board, move))

        self.assertIn("a2a1=N", moves)
        self.assertNotIn("a2a1", moves)
        self.assertNotIn("a2a1=R", moves)
        self.assertNotIn("a2a1=B", moves)
        self.assertNotIn("a2a1=Q", moves)
        self.assertNotIn("a2a1=K", moves)
예제 #35
0
 def __onPlayBoardCreated (self, boardManager, board):
     
     self.mytime = int(board["mins"])*60
     self.increment = int(board["incr"])
     self.gameno = board["gameno"]
     self.lastPly = -1
     
     self.acceptedTimesettings.append((self.mytime, self.increment))
     
     self.tellHome("Starting a game (%s, %s) gameno: %s" %
             (board["wname"], board["bname"], board["gameno"]))
     
     if board["bname"].lower() == self.connection.getUsername().lower():
         self.playingAs = BLACK
     else:
         self.playingAs = WHITE
     
     self.board = LBoard(NORMALCHESS)
예제 #36
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
예제 #37
0
    def add_variation(self, board, moves, comment="", score=""):
        board0 = board
        board = board0.clone()
        board.board.prev = None

        variation = [board]

        for move in moves:
            new = board.move(move)
            if len(variation) == 1:
                new.board.prev = board0.board
                variation[0].board.next = new.board
            else:
                new.board.prev = board.board
                board.board.next = new.board
            variation.append(new)
            board = new

        if board0.board.next is None:
            # If we are in the latest played board, and want to add a variation
            # we have to add a not played yet board first
            # which can hold the variation as his child
            from pychess.Utils.lutils.LBoard import LBoard

            null_board = LBoard()
            null_board.prev = board0.board
            null_board.plyCount = board0.board.plyCount + 1
            board0.board.next = null_board

        board0.board.next.children.append([board.board for board in variation])

        head = None
        for vari in self.variations:
            if board0 in vari:
                head = vari
                break

        variation[0] = board0
        self.variations.append(head[: board0.ply - self.lowply] + variation)
        self.needsSave = True
        self.emit("variation_added", board0.board.next.children[-1], board0.board.next, comment, score)
        return self.variations[-1]
예제 #38
0
    def add_variation(self, board, moves, comment="", score=""):
        board0 = board
        board = board0.clone()
        board.board.prev = None

        variation = [board]

        for move in moves:
            new = board.move(move)
            if len(variation) == 1:
                new.board.prev = board0.board
                variation[0].board.next = new.board
            else:
                new.board.prev = board.board
                board.board.next = new.board
            variation.append(new)
            board = new

        if board0.board.next is None:
            # If we are in the latest played board, and want to add a variation
            # we have to add a not played yet board first
            # which can hold the variation as his child
            from pychess.Utils.lutils.LBoard import LBoard
            null_board = LBoard()
            null_board.prev = board0.board
            null_board.plyCount = board0.board.plyCount + 1
            board0.board.next = null_board

        board0.board.next.children.append([board.board for board in variation])

        head = None
        for vari in self.variations:
            if board0 in vari:
                head = vari
                break

        variation[0] = board0
        self.variations.append(head[:board0.ply - self.lowply] + variation)
        self.needsSave = True
        self.emit("variation_added", board0.board.next.children[-1],
                  board0.board.next, comment, score)
        return self.variations[-1]
예제 #39
0
    def __init__(self):
        PyChess.__init__(self)
        self.board = LBoard(NORMALCHESS)
        self.board.applyFen(FEN_START)

        self.forced = False
        self.analyzing = False
        self.thread = None

        self.basetime = 0

        self.features = {
            "ping": 1,
            "setboard": 1,
            "playother": 1,
            "san": 1,
            "usermove": 1,
            "time": 1,
            "draw": 1,
            "sigint": 0,
            "sigterm": 0,
            "reuse": 1,
            "analyze": 1,
            "myname": "PyChess %s" % pychess.VERSION,
            "variants": "normal,wildcastle,nocastle,fischerandom,crazyhouse,losers,suicide,atomic," + \
                        "kingofthehill,3check,asean,cambodian,makruk,sittuyin",
            "colors": 0,
            "ics": 0,
            "name": 0,
            "pause": 0, # Unimplemented
            "nps": 0, # Unimplemented
            "debug": 1,
            "memory": 0, # Unimplemented
            "smp": 0, # Unimplemented
            "egt": "gaviota",
            "option": "skipPruneChance -slider 0 0 100"
        }
        python = sys.executable.split("/")[-1]
        python_version = "%s.%s.%s" % sys.version_info[0:3]
        self.print("# %s [%s %s]" %
                   (self.features["myname"], python, python_version))
예제 #40
0
 def __init__ (self):
     PyChess.__init__(self)
     self.board = LBoard(NORMALCHESS)
     self.board.applyFen(FEN_START)
     
     self.forced = False
     self.analyzing = False
     self.worker = None
     
     self.features = {
         "setboard": 1,
         "analyze": 1,
         "san": 1,
         "usermove": 1,
         "reuse": 0,
         "draw": 1,
         "sigterm": 1,
         "colors": 1,
         "variants": "normal,nocastle,fischerandom",
         "myname": "PyChess %s" % pychess.VERSION
     }
예제 #41
0
    def test_paresSAN1(self):
        """Testing parseSAN with unambiguous notations variants"""
        
        board = LBoard()
        board.applyFen("4k2B/8/8/8/8/8/8/B3K3 w - - 0 1")        

        self.assertEqual(repr(Move(parseSAN(board, 'Ba1b2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bh8b2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'Bab2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bhb2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'B1b2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'B8b2'))), 'h8b2')


        board = LBoard()
        board.applyFen("4k2B/8/8/8/8/8/1b6/B3K3 w - - 0 1")        

        self.assertEqual(repr(Move(parseSAN(board, 'Ba1xb2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bh8xb2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'Baxb2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'Bhxb2'))), 'h8b2')

        self.assertEqual(repr(Move(parseSAN(board, 'B1xb2'))), 'a1b2')
        self.assertEqual(repr(Move(parseSAN(board, 'B8xb2'))), 'h8b2')
예제 #42
0
    def __onGameCreated(self, boardManager, ficsgame):

        base = int(ficsgame.minutes) * 60
        inc = int(ficsgame.inc)
        self.clock[:] = base, base
        self.increment[:] = inc, inc
        self.gameno = ficsgame.gameno
        self.lastPly = -1

        self.acceptedTimesettings.append((base, inc))

        self.tellHome(
            "Starting a game (%s, %s) gameno: %s" %
            (ficsgame.wplayer.name, ficsgame.bplayer.name, ficsgame.gameno))

        if ficsgame.bplayer.name.lower() == self.connection.getUsername(
        ).lower():
            self.playingAs = BLACK
        else:
            self.playingAs = WHITE

        self.board = LBoard(NORMALCHESS)
예제 #43
0
    def movegen(self, positions):
        for i, (fen, depths) in enumerate(positions):
            board = LBoard(FISCHERRANDOMCHESS)
            fen = fen.split()
            castl = fen[2]
            castl = castl.replace("K", "H")
            castl = castl.replace("Q", "A")
            castl = castl.replace("k", "h")
            castl = castl.replace("q", "a")
            fen[2] = castl
            fen = ' '.join(fen)

            print(i+1, "/", len(positions), "-", fen)
            board.applyFen(fen)
            
            for depth, suposedMoveCount in enumerate(depths):
                if depth+1 > self.MAXDEPTH: break
                self.count = 0
                print("searching depth %d for %d moves" % \
                        (depth+1, suposedMoveCount))
                self.perft (board, depth+1, [])
                self.assertEqual(self.count, suposedMoveCount)
예제 #44
0
    def movegen(self, positions):
        for i, (fen, depths) in enumerate(positions):
            board = LBoard(FISCHERRANDOMCHESS)
            fen = fen.split()
            castl = fen[2]
            castl = castl.replace("K", "H")
            castl = castl.replace("Q", "A")
            castl = castl.replace("k", "h")
            castl = castl.replace("q", "a")
            fen[2] = castl
            fen = ' '.join(fen)

            print(i + 1, "/", len(positions), "-", fen)
            board.applyFen(fen)

            for depth, suposedMoveCount in enumerate(depths):
                if depth + 1 > self.MAXDEPTH:
                    break
                self.count = 0
                print("searching depth %d for %d moves" % (depth + 1, suposedMoveCount))
                self.perft(board, depth + 1, [])
                self.assertEqual(self.count, suposedMoveCount)
예제 #45
0
class EvalTestCase(unittest.TestCase):
    
    def setUp (self):
        self.board = LBoard(NORMALCHESS)
        self.board.applyFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w - - 0 1")
    
    def test1(self):
        """Testing eval symmetry with startboard (WHITE)"""
        score = evaluateComplete(self.board, color=WHITE, balanced=True)
        self.assertEqual(score, 0)
    
    def test2(self):
        """Testing eval symmetry with startboard (BLACK)"""
        score = evaluateComplete(self.board, color=BLACK, balanced=True)
        self.assertEqual(score, 0)
    
    def test3(self):
        """Testing eval symmetry between colors with balanced=False"""
        scorew = evaluateComplete(self.board, color=WHITE)
        scoreb = evaluateComplete(self.board, color=BLACK)
        self.assertEqual(scorew, scoreb)
    
    def test4(self):
        """Testing eval symmetry of each function"""
        funcs = (f for f in dir(leval) if f.startswith("eval"))
        funcs = (getattr(leval,f) for f in funcs)
        funcs = (f for f in funcs if callable(f) and f != leval.evalMaterial)
        
        sw, phasew = leval.evalMaterial (self.board, WHITE)
        sb, phaseb = leval.evalMaterial (self.board, BLACK)
        self.assertEqual(phasew, phaseb)
        
        for func in funcs:
            sw = func(self.board, WHITE, phasew)
            sb = func(self.board, BLACK, phaseb)
            #print func, sw, sb
            self.assertEqual(sw, sb)
예제 #46
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
예제 #47
0
파일: GameModel.py 프로젝트: btrent/knave
    def add_variation(self, board, moves):
        board0 = board
        board = board0.clone()
        board.board.prev = None
        
        variation = [board]
        
        for move in moves:
            new = board.move(move)
            if len(variation) == 1:
                new.board.prev = board0.board
                variation[0].board.next = new.board
            else:
                new.board.prev = board.board
                board.board.next = new.board
            variation.append(new)
            board = new
        
        if board0.board.next is None:
            from pychess.Utils.lutils.LBoard import LBoard
            null_board = LBoard()
            null_board.prev = board0.board
            board0.board.next = null_board

        board0.board.next.children.append([board.board for board in variation])

        head = None
        for vari in self.variations:
            if board0 in vari:
                head = vari
                break
                
        variation[0] = board0
        self.variations.append(head[:board0.ply-self.lowply] + variation)
        self.needsSave = True
        #self.emit("variations_changed")
        return self.variations[-1]
예제 #48
0
    def feed_book(self, records, positions):
        for rec in records:
            model = GameModel()

            if rec["Result"] == DRAW:
                score = (1, 1)
            elif rec["Result"] == WHITEWON:
                score = (2, 0)
            elif rec["Result"] == BLACKWON:
                score = (0, 2)
            else:
                score = (0, 0)

            fenstr = rec["FEN"]
            variant = self.chessfile.get_variant(rec)

            if variant:
                model.variant = name2variant[variant]
                board = LBoard(model.variant.variant)
            else:
                model.variant = NormalBoard
                board = LBoard()

            if fenstr:
                try:
                    board.applyFen(fenstr)
                except SyntaxError as err:
                    continue
            else:
                board.applyFen(FEN_START)

            boards = [board]

            movetext = self.chessfile.get_movetext(rec)
            boards = self.chessfile.parse_movetext(movetext, boards[0], -1)

            for board in boards:
                if board.plyCount > BOOK_DEPTH:
                    break
                move = board.lastMove
                if move is not None:
                    poly_move = toPolyglot(board.prev, move)
                    # move_str = "%s%s" % (reprCord[FCORD(move)], reprCord[TCORD(move)])
                    # print("%0.16x" % board.prev.hash, poly_move, board.prev.asFen(), move_str)
                    if board.prev.hash in positions:
                        if poly_move in positions[board.prev.hash]:
                            positions[board.prev.hash][poly_move] += score[board.prev.color]
                        else:
                            positions[board.prev.hash][poly_move] = score[board.prev.color]
                    else:
                        # board.prev.asFen(), move_str,
                        positions[board.prev.hash] = {poly_move: score[board.prev.color]}
예제 #49
0
    def __init__(self):
        PyChess.__init__(self)
        self.board = LBoard(NORMALCHESS)
        self.board.applyFen(FEN_START)

        self.forced = False
        self.analyzing = False
        self.thread = None

        self.basetime = 0

        self.features = {
            "ping": 1,
            "setboard": 1,
            "playother": 1,
            "san": 1,
            "usermove": 1,
            "time": 1,
            "draw": 1,
            "sigint": 0,
            "sigterm": 0,
            "reuse": 1,
            "analyze": 1,
            "myname": "PyChess %s" % pychess.VERSION,
            "variants": "normal,wildcastle,nocastle,fischerandom,crazyhouse," +
                        "losers,suicide,giveaway,horde,atomic," +
                        "kingofthehill,3check,asean,cambodian,makruk,sittuyin",
            "colors": 0,
            "ics": 0,
            "name": 0,
            "pause": 0,  # Unimplemented
            "nps": 0,  # Unimplemented
            "debug": 1,
            "memory": 0,  # Unimplemented
            "smp": 0,  # Unimplemented
            "egt": "gaviota",
            "option": "skipPruneChance -slider 0 0 100"
        }
        python = sys.executable.split("/")[-1]
        python_version = "%s.%s.%s" % sys.version_info[0:3]
        self.print("# %s [%s %s]" %
                   (self.features["myname"], python, python_version))
예제 #50
0
 def __onGameCreated (self, boardManager, ficsgame):
     
     base = int(ficsgame.minutes)*60
     inc = int(ficsgame.inc)
     self.clock[:] = base, base
     self.increment[:] = inc, inc
     self.gameno = ficsgame.gameno
     self.lastPly = -1
     
     self.acceptedTimesettings.append((base, inc))
     
     self.tellHome("Starting a game (%s, %s) gameno: %s" %
             (ficsgame.wplayer.name, ficsgame.bplayer.name, ficsgame.gameno))
     
     if ficsgame.bplayer.name.lower() == self.connection.getUsername().lower():
         self.playingAs = BLACK
     else:
         self.playingAs = WHITE
     
     self.board = LBoard(NORMALCHESS)
예제 #51
0
파일: PyChessCECP.py 프로젝트: btrent/knave
    def __init__ (self):
        PyChess.__init__(self)
        self.board = LBoard(NORMALCHESS)
        self.board.applyFen(FEN_START)
        
        self.forced = False
        self.analyzing = False
        self.thread = None

        self.basetime = 0
        
        self.features = {
            "ping": 1,
            "setboard": 1,
            "playother": 1,
            "san": 1,
            "usermove": 1,
            "time": 1,
            "draw": 1,
            "sigint": 0,
            "sigterm": 0,
            "reuse": 1,
            "analyze": 1,
            "myname": "PyChess %s" % pychess.VERSION,
            "variants": "normal,wildcastle,nocastle,fischerandom,crazyhouse,losers,suicide,atomic",
            "colors": 0,
            "ics": 0,
            "name": 0,
            "pause": 0, # Unimplemented
            "nps": 0, # Unimplemented
            "debug": 1,
            "memory": 1,
            "smp": 0, # Unimplemented
            # "egt": "gaviota", # TODO: re-enable
            "option": "skipPruneChance -slider 0 0 100"
        }
예제 #52
0
            def on_book_created(persp, event):
                self.assertTrue(os.path.isfile(BIN))

                book.path = BIN
                book.bookfile = True

                testcase = testcases[0]
                board = LBoard(Board)
                board.applyFen(testcase[0])
                openings = book.getOpenings(board)
                self.assertEqual(sorted(openings), sorted([(newMove(E2, E4), 2, 0), (newMove(A2, A4), 0, 0)]))

                testcase = testcases[-1]
                board = LBoard(Board)
                board.applyFen(testcase[0])
                openings = book.getOpenings(board)
                self.assertEqual(openings, [])

                event.set()
예제 #53
0
from pychess.System.Log import log
from pychess.System.prefix import addDataPrefix
from pychess.Utils.lutils.LBoard import LBoard
from pychess.Utils.lutils.lmove import toSAN, toFAN
from pychess.Savers.pgn import move_count
from pychess.Savers.pgnbase import nag2symbol
from pychess.widgets.Background import set_textview_color
from pychess.widgets.ChessClock import formatTime
from pychess.Utils.TimeModel import TimeModel

__title__ = _("Annotation")
__active__ = True
__icon__ = addDataPrefix("glade/panel_annotation.svg")
__desc__ = _("Annotated game")

EMPTY_BOARD = LBoard()
EMPTY_BOARD.applyFen(FEN_EMPTY)

"""
We are maintaining a list of nodes to help manipulate the textbuffer.
Node can represent a move, comment or variation (start/end) marker.
Nodes are dicts with keys like:
board  = in move node it's the lboard of move
         in comment node it's the lboard where the comment belongs to
         in end variation marker node it's the first lboard of the variation
         in start variation marker is's None
start  = the beginning offest of the node in the textbuffer
end    = the ending offest of the node in the textbuffer
parent = the parent lboard if the node is a move in a variation, otherwise None
vari   = in end variation node it's the start variation marker node
         in start variation node it's None
예제 #54
0
파일: PyChessCECP.py 프로젝트: btrent/knave
    def run (self):
        while True:
            try:
                line = raw_input()
            except EOFError:
                line = "quit"
            lines = line.split()
            if 1:
            #try:
                if not lines:
                    continue
     
                ########## CECP commands ##########
                # See http://www.gnu.org/software/xboard/engine-intf.html#8
                
                elif lines[0] == "xboard":
                    pass
     
                elif lines[0] == "protover":
                    stringPairs = ["=".join([k, '"%s"' % v if type(v) is str else str(v)]) for k,v in self.features.iteritems()]
                    print "feature %s" % " ".join(stringPairs)
                    print "feature done=1"
                
                elif lines[0] in ("accepted", "rejected"):
                    # We only really care about one case:
                    if tuple(lines) == ("rejected", "debug"):
                        self.debug = False
     
                elif lines[0] == "new":
                    self.__stopSearching()
                    self.board = LBoard(NORMALCHESS)
                    self.board.applyFen(FEN_START)
                    self.forced = False
                    self.playingAs = BLACK
                    self.clock[:] = self.basetime, self.basetime
                    self.searchtime = 0
                    self.sd = MAXPLY
                    if self.analyzing:
                        self.__analyze()
                
                elif lines[0] == "variant":
                    if len(lines) > 1:
                        if lines[1] == "fischerandom":
                            self.board.variant = FISCHERRANDOMCHESS
                        elif lines[1] == "crazyhouse":
                            self.board.variant = CRAZYHOUSECHESS
                            self.board.iniHouse()
                        elif lines[1] == "wildcastle":
                            self.board.variant = WILDCASTLESHUFFLECHESS
                        elif lines[1] == "losers":
                            self.board.variant = LOSERSCHESS
                        elif lines[1] == "suicide":
                            self.board.variant = SUICIDECHESS
                        elif lines[1] == "atomic":
                            self.board.variant = ATOMICCHESS
                            self.board.iniAtomic()
                
                elif lines[0] == "quit":
                    self.forced = True
                    self.__stopSearching()
                    sys.exit(0)
                    
                elif lines[0] == "random":
                    leval.random = True
     
                elif lines[0] == "force":
                    if not self.forced and not self.analyzing:
                        self.forced = True
                        self.__stopSearching()
                
                elif lines[0] == "go":
                    self.playingAs = self.board.color
                    self.forced = False
                    self.__go()
                
                elif lines[0] == "playother":
                    self.playingAs = 1-self.board.color
                    self.forced = False
                    # TODO: start pondering, if possible
                
                elif lines[0] in ("black", "white"):
                    newColor = lines[0] == "black" and BLACK or WHITE
                    self.__stopSearching()
                    self.playingAs = 1-newColor
                    if self.board.color != newColor:
                        self.board.setColor(newColor)
                        self.board.setEnpassant(None)
                    if self.analyzing:
                        self.__analyze()
                
                elif lines[0] == "level":
                    self.movestogo = int(lines[1])
                    inc = int(lines[3])
                    minutes = lines[2].split(":")
                    # Per protocol spec, strip off any non-numeric suffixes.
                    for i in xrange(len(minutes)):
                        minutes[i] = re.match(r'\d*', minutes[i]).group()
                    self.basetime = int(minutes[0])*60
                    if len(minutes) > 1 and minutes[1]:
                        self.basetime += int(minutes[1])
                    self.clock[:] = self.basetime, self.basetime
                    self.increment = inc, inc
                
                elif lines[0] == "st":
                    self.searchtime = float(lines[1])
     
                elif lines[0] == "sd":
                    self.sd = int(lines[1])
                
                # Unimplemented: nps
                
                elif lines[0] == "time":
                    self.clock[self.playingAs] = float(lines[1])/100.
                
                elif lines[0] == "otim":
                    self.clock[1-self.playingAs] = float(lines[1])/100.
                
                elif lines[0] == "usermove":
                    self.__stopSearching()
                    try:
                        move = parseAny (self.board, lines[1])
                    except ParsingError, e:
                        print "Error (unknown command):", lines[1]
                        print self.board
                        continue
                    if not validateMove(self.board, move):
                        print "Illegal move", lines[1]
                        print self.board
                        continue
                    self.board.applyMove(move)
                    self.playingAs = self.board.color
                    if not self.forced and not self.analyzing:
                        self.__go()
                    if self.analyzing:
                        self.__analyze()
                
                elif lines[0] == "?":
                    if not self.forced and not self.analyzing:
                        self.__stopSearching()
                
                elif lines[0] == "ping":
                    print "pong", lines[1]
                    
                elif lines[0] == "draw":
                    if self.__willingToDraw():
                        print "offer draw"
                
                elif lines[0] == "result":
                    # We don't really care what the result is at the moment.
                    pass
                    
                elif lines[0] == "setboard":
                    self.__stopSearching()
                    try:
                        self.board = LBoard(self.board.variant)
                        fen = " ".join(lines[1:])
                        self.board.applyFen(fen.replace("[", "/").replace("]", ""))
                    except SyntaxError as e:
                        print "tellusererror Illegal position:", str(e)
                    if self.analyzing:
                        self.__analyze()
                
                # "edit" is unimplemented. See docs. Exiting edit mode returns to analyze mode.
     
                elif lines[0] == "hint":
                    pass # TODO: Respond "Hint: MOVE" if we have an expected reply
                
                elif lines[0] == "bk":
                    entries = getOpenings(self.board)
                    if entries:
                        totalWeight = sum(entry[1] for entry in entries)
                        for entry in entries:
                            print "\t%s\t%02.2f%%" % (toSAN(self.board, entry[0]), entry[1] * 100.0 / totalWeight)
                
                elif lines[0] == "undo":
                    self.__stopSearching()
                    self.board.popMove()
                    if self.analyzing:
                        self.__analyze()
     
                elif lines[0] == "remove":
                    self.__stopSearching()
                    self.board.popMove()
                    self.board.popMove()
                    if self.analyzing:
                        self.__analyze()
                
                elif lines[0] in ("hard", "easy"):
                    self.ponder = (lines[0] == "hard")
                
                elif lines[0] in ("post", "nopost"):
                    self.post = (lines[0] == "post")
                
                elif lines[0] == "analyze":
                    self.analyzing = True
                    self.__analyze()
     
                elif lines[0] in ("name", "rating", "ics", "computer"):
                    pass # We don't care.
     
                # Unimplemented: pause, resume
     
                elif lines[0] == "memory":
                    # FIXME: this is supposed to control the *total* memory use.
                    if lsearch.searching:
                        print "Error (already searching):", line
                    else:
                        limit = int(lines[1])
                        if limit < 1:
                            print "Error (limit too low):", line
                        else:
                            pass
                            # TODO implement
                            #lsearch.setHashSize(limit)
     
                elif lines[0] == "cores":
                    pass # We aren't SMP-capable.
     
                elif lines[0] == "egtpath":
                    # TODO: Accept "egtpath TYPE PATH" commands, at least for Gaviota EGTBs
                    pass
     
                elif lines[0] == "option" and len(lines) > 1:
                    name, eq, value = lines[1].partition("=")
                    if value: value = int(value) # CECP spec says option values are *always* numeric
                    if name == "skipPruneChance":
                        if 0 <= value <= 100:
                            self.skipPruneChance = value / 100.0
                        else:
                            print "Error (argument must be an integer 0..100):", line
     
                ########## CECP analyze mode commands ##########
                # See http://www.gnu.org/software/xboard/engine-intf.html#11
     
                elif lines[0] == "exit":
                    if self.analyzing:
                        self.__stopSearching()
                        self.analyzing = False
     
                # Periodic updates (".") are not implemented.
     
                ########## Custom commands ##########
     
                elif lines[0] == "egtb":
                    enableEGTB()
                
                elif lines[0] == "benchmark":
                    benchmark()
                
                elif lines[0] == "profile":
                    if len(lines) > 1:
                        import cProfile
                        cProfile.runctx("benchmark()", locals(), globals(), lines[1])
                    else:
                        print "Usage: profile outputfilename"
                
                elif len(lines) == 1:
                    # A GUI without usermove support might try to send a move.
                    try:
                        move = parseAny (self.board, line)
                    except:
                        print "Error (unknown command):", line
                        continue
                    if not validateMove(self.board, move):
                        print "Illegal move", lines[0]
                        print self.board
                        continue
                    self.__stopSearching()
                    self.board.applyMove(move)
                    self.playingAs = self.board.color
                    if not self.forced and not self.analyzing:
                        self.__go()
                    if self.analyzing:
                        self.__analyze()

                else:
                    print "Error (unknown command):", line
예제 #55
0
from pychess.Database.model import engine, metadata, collection, event,\
                            site, player, game, annotator, ini_collection

CHUNK = 1000

EVENT, SITE, PLAYER, ANNOTATOR, COLLECTION = range(5)

removeDic = {
    ord(unicode("'")): None,
    ord(unicode(",")): None,
    ord(unicode(".")): None,
    ord(unicode("-")): None,
    ord(unicode(" ")): None,
}

LBoard_FEN_START = LBoard()
LBoard_FEN_START.applyFen(FEN_START)

class PgnImport():
    def __init__(self):
        self.conn = engine.connect()
        
        self.ins_collection = collection.insert()
        self.ins_event = event.insert()
        self.ins_site = site.insert()
        self.ins_player = player.insert()
        self.ins_annotator = annotator.insert()
        self.ins_game = game.insert()
        
        self.collection_dict = {}
        self.event_dict = {}
예제 #56
0
파일: pgn.py 프로젝트: bboutkov/pychess
    def loadToModel(self, rec, position=-1, model=None):
        """ Parse game text and load game record header tags to a GameModel object """

        if not model:
            model = GameModel()

        if self.pgn_is_string:
            rec = self.games[0]
            game_date = rec["Date"]
            result = rec["Result"]
            variant = rec["Variant"]
        else:
            game_date = self.get_date(rec)
            result = reprResult[rec["Result"]]
            variant = self.get_variant(rec)

        # the seven mandatory PGN headers
        model.tags['Event'] = rec["Event"]
        model.tags['Site'] = rec["Site"]
        model.tags['Date'] = game_date
        model.tags['Round'] = rec["Round"]
        model.tags['White'] = rec["White"]
        model.tags['Black'] = rec["Black"]
        model.tags['Result'] = result

        if model.tags['Date']:
            date_match = re.match(".*(\d{4}).(\d{2}).(\d{2}).*",
                                  model.tags['Date'])
            if date_match:
                year, month, day = date_match.groups()
                model.tags['Year'] = year
                model.tags['Month'] = month
                model.tags['Day'] = day

        # non-mandatory tags
        for tag in ('Annotator', 'ECO', 'WhiteElo', 'BlackElo', 'TimeControl'):
            value = rec[tag]
            if value:
                model.tags[tag] = value
            else:
                model.tags[tag] = ""

        if not self.pgn_is_string:
            model.info = self.tag_database.get_info(rec)

        if model.tags['TimeControl']:
            secs, gain = parseTimeControlTag(model.tags['TimeControl'])
            model.timed = True
            model.timemodel.secs = secs
            model.timemodel.gain = gain
            model.timemodel.minutes = secs / 60
            for tag, color in (('WhiteClock', WHITE), ('BlackClock', BLACK)):
                if hasattr(rec, tag):
                    try:
                        millisec = parseClockTimeTag(rec[tag])
                        # We need to fix when FICS reports negative clock time like this
                        # [TimeControl "180+0"]
                        # [WhiteClock "0:00:15.867"]
                        # [BlackClock "23:59:58.820"]
                        start_sec = (
                            millisec - 24 * 60 * 60 * 1000
                        ) / 1000. if millisec > 23 * 60 * 60 * 1000 else millisec / 1000.
                        model.timemodel.intervals[color][0] = start_sec
                    except ValueError:
                        raise LoadingError(
                            "Error parsing '%s'" % tag)

        fenstr = rec["FEN"]

        if variant:
            if variant not in name2variant:
                raise LoadingError("Unknown variant %s" % variant)

            model.tags["Variant"] = variant
            # Fixes for some non statndard Chess960 .pgn
            if (fenstr is not None) and variant == "Fischerandom":
                parts = fenstr.split()
                parts[0] = parts[0].replace(".", "/").replace("0", "")
                if len(parts) == 1:
                    parts.append("w")
                    parts.append("-")
                    parts.append("-")
                fenstr = " ".join(parts)

            model.variant = name2variant[variant]
            board = LBoard(model.variant.variant)
        else:
            model.variant = NormalBoard
            board = LBoard()

        if fenstr:
            try:
                board.applyFen(fenstr)
            except SyntaxError as err:
                board.applyFen(FEN_EMPTY)
                raise LoadingError(
                    _("The game can't be loaded, because of an error parsing FEN"),
                    err.args[0])
        else:
            board.applyFen(FEN_START)

        boards = [board]

        del model.moves[:]
        del model.variations[:]

        self.error = None
        movetext = self.get_movetext(rec)

        boards = self.parse_movetext(movetext, boards[0], position)

        # The parser built a tree of lboard objects, now we have to
        # create the high level Board and Move lists...

        for board in boards:
            if board.lastMove is not None:
                model.moves.append(Move(board.lastMove))

        self.has_emt = False
        self.has_eval = False

        def walk(model, node, path):
            if node.prev is None:
                # initial game board
                board = model.variant(setup=node.asFen(), lboard=node)
            else:
                move = Move(node.lastMove)
                try:
                    board = node.prev.pieceBoard.move(move, lboard=node)
                except:
                    raise LoadingError(
                        _("Invalid move."),
                        "%s%s" % (move_count(node, black_periods=True), move))

            if node.next is None:
                model.variations.append(path + [board])
            else:
                walk(model, node.next, path + [board])

            for child in node.children:
                if isinstance(child, list):
                    if len(child) > 1:
                        # non empty variation, go walk
                        walk(model, child[1], list(path))
                else:
                    if not self.has_emt:
                        self.has_emt = child.find("%emt") >= 0
                    if not self.has_eval:
                        self.has_eval = child.find("%eval") >= 0

        # Collect all variation paths into a list of board lists
        # where the first one will be the boards of mainline game.
        # model.boards will allways point to the current shown variation
        # which will be model.variations[0] when we are in the mainline.
        walk(model, boards[0], [])
        model.boards = model.variations[0]
        self.has_emt = self.has_emt and "TimeControl" in model.tags
        if self.has_emt or self.has_eval:
            if self.has_emt:
                blacks = len(model.moves) // 2
                whites = len(model.moves) - blacks

                model.timemodel.intervals = [
                    [model.timemodel.intervals[0][0]] * (whites + 1),
                    [model.timemodel.intervals[1][0]] * (blacks + 1),
                ]
                secs, gain = parseTimeControlTag(model.tags['TimeControl'])
                model.timemodel.intervals[0][0] = secs
                model.timemodel.intervals[1][0] = secs
            for ply, board in enumerate(boards):
                for child in board.children:
                    if isinstance(child, str):
                        if self.has_emt:
                            match = movetime.search(child)
                            if match:
                                movecount, color = divmod(ply + 1, 2)
                                hour, minute, sec, msec = match.groups()
                                prev = model.timemodel.intervals[color][
                                    movecount - 1]
                                hour = 0 if hour is None else int(hour[:-1])
                                minute = 0 if minute is None else int(minute[:-1])
                                msec = 0 if msec is None else int(msec)
                                msec += int(sec) * 1000 + int(
                                    minute) * 60 * 1000 + int(
                                        hour) * 60 * 60 * 1000
                                model.timemodel.intervals[color][
                                    movecount] = prev - msec / 1000. + gain

                        if self.has_eval:
                            match = moveeval.search(child)
                            if match:
                                sign, num, fraction, depth = match.groups()
                                sign = 1 if sign is None or sign == "+" else -1
                                num = int(num) if int(
                                    num) == MATE_VALUE else int(num)
                                fraction = 0 if fraction is None else int(
                                    fraction)
                                value = sign * (num * 100 + fraction)
                                depth = "" if depth is None else depth
                                if board.color == BLACK:
                                    value = -value
                                model.scores[ply] = ("", value, depth)
            log.debug("pgn.loadToModel: intervals %s" %
                      model.timemodel.intervals)

        # Find the physical status of the game
        model.status, model.reason = getStatus(model.boards[-1])

        # Apply result from .pgn if the last position was loaded
        if position == -1 or len(model.moves) == position - model.lowply:
            status = rec["Result"]
            if status in (WHITEWON, BLACKWON) and status != model.status:
                model.status = status
                model.reason = WON_RESIGN
            elif status == DRAW and status != model.status:
                model.status = DRAW
                model.reason = DRAW_AGREE

        # If parsing gave an error we throw it now, to enlarge our possibility
        # of being able to continue the game from where it failed.
        if self.error:
            raise self.error

        return model
예제 #57
0
    def do_import(self, filename):
        print(filename)
        # collect new names not in they dict yet
        self.collection_data = []
        self.event_data = []
        self.site_data = []
        self.player_data = []
        self.annotator_data = []
        
        # collect new games and commit them in big chunks for speed
        self.game_data = []

        if filename.lower().endswith(".zip") and zipfile.is_zipfile(filename):
            zf = zipfile.ZipFile(filename, "r")
            files = [f for f in zf.namelist() if f.lower().endswith(".pgn")]
        else:
            zf = None
            files = [filename]
        
        for pgnfile in files:
            if zf is None:
                cf = pgn_load(open(pgnfile, "rU"))
            else:
                cf = pgn_load(zf.open(pgnfile, "rU"))
             
            # use transaction to avoid autocommit slowness
            trans = self.conn.begin()
            try:
                for i, game in enumerate(cf.games):
                    #print i+1#, cf.get_player_names(i)
                    movelist = array("H")
                    comments = []
                    cf.error = None

                    fenstr = cf._getTag(i, "FEN")
                    variant = cf.get_variant(i)

                    # Fixes for some non statndard Chess960 .pgn
                    if variant==0 and (fenstr is not None) and "Chess960" in cf._getTag(i,"Event"):
                        cf.tagcache[i]["Variant"] = "Fischerandom"
                        variant = 1
                        parts = fenstr.split()
                        parts[0] = parts[0].replace(".", "/").replace("0", "")
                        if len(parts) == 1:
                            parts.append("w")
                            parts.append("-")
                            parts.append("-")
                        fenstr = " ".join(parts)
                    
                    if variant:
                        board = LBoard(FISCHERRANDOMCHESS)
                    else:
                        board = LBoard()

                    if fenstr:
                        try:
                            board.applyFen(fenstr)
                        except SyntaxError as e:
                            print(_("The game #%s can't be loaded, because of an error parsing FEN") % (i+1), e.args[0])
                            continue
                    else:
                        board = LBoard_FEN_START.clone()

                    boards = [board]
                    movetext = cf.get_movetext(i)
                    boards = cf.parse_string(movetext, boards[0], -1)

                    if cf.error is not None:
                        print("ERROR in game #%s" % (i+1), cf.error.args[0])
                        continue

                    walk(boards[0], movelist, comments)
                    
                    if not movelist:
                        if (not comments) and (cf._getTag(i, 'White') is None) and (cf._getTag(i, 'Black') is None):
                            print("empty game")
                            continue
                    
                    event_id = self.get_id(cf._getTag(i, 'Event'), event, EVENT)

                    site_id = self.get_id(cf._getTag(i, 'Site'), site, SITE)

                    game_date = cf._getTag(i, 'Date')
                    if game_date and not '?' in game_date:
                        ymd = game_date.split('.')
                        if len(ymd) == 3:
                            game_year, game_month, game_day = map(int, ymd)
                        else:
                            game_year, game_month, game_day = int(game_date[:4]), None, None
                    elif game_date and not '?' in game_date[:4]:
                        game_year, game_month, game_day = int(game_date[:4]), None, None
                    else:
                        game_year, game_month, game_day = None, None, None

                    game_round = cf._getTag(i, 'Round')

                    white, black = cf.get_player_names(i)
                    white_id = self.get_id(white, player, PLAYER)
                    black_id = self.get_id(black, player, PLAYER)

                    result = cf.get_result(i)
     
                    white_elo = cf._getTag(i, 'WhiteElo')
                    white_elo = int(white_elo) if white_elo and white_elo.isdigit() else None
                    
                    black_elo = cf._getTag(i, 'BlackElo')
                    black_elo = int(black_elo) if black_elo and black_elo.isdigit() else None
     
                    ply_count = cf._getTag(i, "PlyCount")
     
                    event_date = cf._getTag(i, 'EventDate')
     
                    eco = cf._getTag(i, "ECO")
                    eco = eco[:3] if eco else None

                    fen = cf._getTag(i, "FEN")
     
                    variant = cf.get_variant(i)
                    
                    board = cf._getTag(i, "Board")
                    
                    annotator = cf._getTag(i, "Annotator")
                    annotator_id = self.get_id(annotator, annotator, ANNOTATOR)

                    collection_id = self.get_id(unicode(pgnfile), collection, COLLECTION)

                    self.game_data.append({
                        'event_id': event_id,
                        'site_id': site_id,
                        'date_year': game_year,
                        'date_month': game_month,
                        'date_day': game_day,
                        'round': game_round,
                        'white_id': white_id,
                        'black_id': black_id,
                        'result': result,
                        'white_elo': white_elo,
                        'black_elo': black_elo,
                        'ply_count': ply_count,
                        'eco': eco,
                        'fen': fen,
                        'variant': variant,
                        'board': board,
                        'annotator_id': annotator_id,
                        'collection_id': collection_id,
                        'movelist': movelist.tostring(),
                        'comments': unicode("|".join(comments)),
                        })

                    if len(self.game_data) >= CHUNK:
                        if self.collection_data:
                            self.conn.execute(self.ins_collection, self.collection_data)
                            self.collection_data = []

                        if self.event_data:
                            self.conn.execute(self.ins_event, self.event_data)
                            self.event_data = []

                        if self.site_data:
                            self.conn.execute(self.ins_site, self.site_data)
                            self.site_data = []

                        if self.player_data:
                            self.conn.execute(self.ins_player, self.player_data)
                            self.player_data = []

                        if self.annotator_data:
                            self.conn.execute(self.ins_annotator, self.annotator_data)
                            self.annotator_data = []

                        self.conn.execute(self.ins_game, self.game_data)
                        self.game_data = []
                        print(pgnfile, i+1)
                    
                if self.collection_data:
                    self.conn.execute(self.ins_collection, self.collection_data)
                    self.collection_data = []

                if self.event_data:
                    self.conn.execute(self.ins_event, self.event_data)
                    self.event_data = []

                if self.site_data:
                    self.conn.execute(self.ins_site, self.site_data)
                    self.site_data = []

                if self.player_data:
                    self.conn.execute(self.ins_player, self.player_data)
                    self.player_data = []

                if self.annotator_data:
                    self.conn.execute(self.ins_annotator, self.annotator_data)
                    self.annotator_data = []

                if self.game_data:
                    self.conn.execute(self.ins_game, self.game_data)
                    self.game_data = []

                print(pgnfile, i+1)
                trans.commit()

            except ProgrammingError as e:
                trans.rollback()
                print("Importing %s failed! %s" % (file, e))