Exemple #1
0
def tip_mobility(model, ply, phase):

    board = model.getBoardAtPly(ply).board
    colorBackup = board.color

    # People need a chance to get developed
    # if model.ply < 16:
    #    return

    board.setColor(WHITE)
    wmoves = len([
        move for move in genAllMoves(board)
        if KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN
        and bitPosArray[TCORD(move)]
        & brank48[WHITE] and staticExchangeEvaluate(board, move) >= 0
    ])

    board.setColor(BLACK)
    bmoves = len([
        move for move in genAllMoves(board)
        if KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN
        and bitPosArray[TCORD(move)]
        & brank48[BLACK] and staticExchangeEvaluate(board, move) >= 0
    ])

    board.setColor(colorBackup)

    if wmoves - phase >= (bmoves + 1) * 7:
        yield wmoves - bmoves, _("Black has a rather cramped position")
    elif wmoves - phase >= (bmoves + 1) * 3:
        yield wmoves - bmoves, _("Black has a slightly cramped position")
    elif bmoves - phase >= (wmoves + 1) * 7:
        yield wmoves - bmoves, _("White has a rather cramped position")
    elif bmoves - phase >= (wmoves + 1) * 3:
        yield wmoves - bmoves, _("White has a slightly cramped position")
Exemple #2
0
def tip_mobility(model, ply, phase):

    board = model.getBoardAtPly(ply).board
    colorBackup = board.color

    # People need a chance to get developed
    # if model.ply < 16:
    #    return

    board.setColor(WHITE)
    wmoves = len([move for move in genAllMoves(board) if
                  KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN and
                  bitPosArray[TCORD(move)] & brank48[WHITE] and
                  staticExchangeEvaluate(board, move) >= 0])

    board.setColor(BLACK)
    bmoves = len([move for move in genAllMoves(board) if
                  KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN and
                  bitPosArray[TCORD(move)] & brank48[BLACK] and
                  staticExchangeEvaluate(board, move) >= 0])

    board.setColor(colorBackup)

    if wmoves - phase >= (bmoves + 1) * 7:
        yield wmoves - bmoves, _("Black has a rather cramped position")
    elif wmoves - phase >= (bmoves + 1) * 3:
        yield wmoves - bmoves, _("Black has a slightly cramped position")
    elif bmoves - phase >= (wmoves + 1) * 7:
        yield wmoves - bmoves, _("White has a rather cramped position")
    elif bmoves - phase >= (wmoves + 1) * 3:
        yield wmoves - bmoves, _("White has a slightly cramped position")
Exemple #3
0
    def test_apply_pop(self):
        """Testing Atomic applyMove popMove"""

        board = LBoard(variant=ATOMICCHESS)
        board.applyFen(FEN)
        print(board)
        hist_exploding_around0 = [a[:] for a in board.hist_exploding_around]
        print_apply_pop = False

        for lmove1 in genAllMoves(board):
            board.applyMove(lmove1)
            if board.opIsChecked():
                if print_apply_pop: print("popMove1 (invalid)", Move(lmove1))
                board.popMove()
                continue

            hist_exploding_around1 = [
                a[:] for a in board.hist_exploding_around
            ]
            for lmove2 in genAllMoves(board):
                board.applyMove(lmove2)
                if print_apply_pop: print("   applyMove2", Move(lmove2))
                if board.opIsChecked():
                    if print_apply_pop:
                        print("   popMove2 (invalid)", Move(lmove2))
                    board.popMove()
                    continue

                hist_exploding_around2 = [
                    a[:] for a in board.hist_exploding_around
                ]
                for lmove3 in genAllMoves(board):
                    board.applyMove(lmove3)
                    if print_apply_pop: print("      applyMove3", Move(lmove3))
                    if board.opIsChecked():
                        if print_apply_pop:
                            print("      popMove3 (invalid)", Move(lmove3))
                        board.popMove()
                        continue

                    board.popMove()
                    if print_apply_pop: print("      popMove3", Move(lmove3))

                    self.assertEqual(hist_exploding_around2,
                                     board.hist_exploding_around)

                board.popMove()
                if print_apply_pop: print("   popMove2", Move(lmove2))

                self.assertEqual(hist_exploding_around1,
                                 board.hist_exploding_around)

            board.popMove()
            if print_apply_pop: print("popMove1", Move(lmove1))

            self.assertEqual(hist_exploding_around0,
                             board.hist_exploding_around)
Exemple #4
0
    def test_apply_pop(self):
        """Testing Atomic applyMove popMove"""

        board = LBoard(variant=ATOMICCHESS)
        board.applyFen(FEN1)
        print(board)
        hist_exploding_around0 = [a[:] for a in board.hist_exploding_around]
        print_apply_pop = False

        for lmove1 in genAllMoves(board):
            board.applyMove(lmove1)
            if board.opIsChecked():
                if print_apply_pop: print("popMove1 (invalid)", Move(lmove1))
                board.popMove()
                continue
                
            hist_exploding_around1 = [a[:] for a in board.hist_exploding_around]
            for lmove2 in genAllMoves(board):
                board.applyMove(lmove2)
                if print_apply_pop: print("   applyMove2", Move(lmove2))
                if board.opIsChecked():
                    if print_apply_pop: print("   popMove2 (invalid)", Move(lmove2))
                    board.popMove()
                    continue

                hist_exploding_around2 = [a[:] for a in board.hist_exploding_around]
                for lmove3 in genAllMoves(board):
                    board.applyMove(lmove3)
                    if print_apply_pop: print("      applyMove3", Move(lmove3))
                    if board.opIsChecked():
                        if print_apply_pop: print("      popMove3 (invalid)", Move(lmove3))
                        board.popMove()
                        continue

                    board.popMove()
                    if print_apply_pop: print("      popMove3", Move(lmove3))

                    self.assertEqual(hist_exploding_around2, board.hist_exploding_around)

                board.popMove()
                if print_apply_pop: print("   popMove2", Move(lmove2))

                self.assertEqual(hist_exploding_around1, board.hist_exploding_around)
                
            board.popMove()
            if print_apply_pop: print("popMove1", Move(lmove1))

            self.assertEqual(hist_exploding_around0, board.hist_exploding_around)
Exemple #5
0
    def test_gating_castle_at_rook_wOO(self):
        FEN = "r2qk2r/pppbbppp/4pn2/1N1p4/1n1P4/4PN2/PPPBBPPP/R2QK2R[heHE] w KQkq - 10 8"
        board = LBoard(SCHESS)
        board.applyFen(FEN)

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

        self.assertIn("h1e1h", moves)
        self.assertIn("h1e1e", moves)

        self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O/Hh1'))), 'h1e1h')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'O-O/Eh1'))), 'h1e1e')

        self.assertEqual(toSAN(board, newMove(H1, E1, HAWK_GATE_AT_ROOK)), "O-O/Hh1")
        self.assertEqual(toSAN(board, newMove(H1, E1, ELEPHANT_GATE_AT_ROOK)), "O-O/Eh1")

        fen = board.asFen()
        move = parseAN(board, "h1e1e")
        board.applyMove(move)
        print("h1e1e")
        print(board)

        self.assertEqual(placement(board.asFen()), "r2qk2r/pppbbppp/4pn2/1N1p4/1n1P4/4PN2/PPPBBPPP/R2Q1RKE[heH]")

        board.popMove()
        self.assertEqual(placement(board.asFen()), placement(fen))
Exemple #6
0
    def test_gating_castle_at_rook_bOO(self):
        board = LBoard(SCHESS)
        board.applyFen(SCHESSSTART)

        for move in "e2e3 e7e6 g1f3 c7c6 c2c3 d7d5 d2d4 g8f6 h2h3 f6e4 d1c2 b8d7 f1d3 f7f5 e1g1e d8c7 e1e2 f8e7 c2d1".split():
            board.applyMove(parseAN(board, move))

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

        self.assertIn("h8e8h", moves)
        self.assertIn("h8e8e", moves)

        fen = board.asFen()
        move = parseAN(board, "h8e8h")
        board.applyMove(move)
        print("h8e8e")
        print(board)

        self.assertEqual(placement(board.asFen()), "r1b2rkh/ppqnb1pp/2p1p3/3p1p2/3Pn3/2PBPN1P/PP2EPP1/RNBQ1RK1[eH]")

        board.popMove()
        self.assertEqual(placement(board.asFen()), placement(fen))
Exemple #7
0
    def test_gating_castle_at_rook_wOOO(self):
        board = LBoard(SCHESS)
        board.applyFen(SCHESSSTART)

        for move in "e2e4 d7d6 d1e2 c8d7 g1f3 g8f6 e4e5 f6d5 e2e4 d5b6 d2d3 d7c6 e4f5 c6d7 f5g5 g7g6 f3d4 h7h5 g5f4 d6e5 f4h4 f8g7 d4f3 d7g4 b1c3 f7f6 c3e4 d8d5 e4c3 d5c5 c1e3 c5d6 h2h3 g4f3 g2f3 e8g8h".split():
            board.applyMove(parseAN(board, move))

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

        self.assertIn("a1e1h", moves)
        self.assertIn("a1e1e", moves)

        fen = board.asFen()
        parseAN(board, "a1e1e")
        board.applyMove(move)
        print("a1e1e")
        print(board)

        self.assertEqual(placement(board.asFen()), "rn2hrk1/ppp1p1b1/1n1q1pp1/4p2p/7Q/2NPBP1P/PPP2P2/E1KR1B1R[eH]")

        board.popMove()
        self.assertEqual(placement(board.asFen()), placement(fen))
Exemple #8
0
    def test_gating_king_move(self):
        board = LBoard(SCHESS)
        board.applyFen(SCHESSSTART)

        for move in "e2e3 e7e5 d1h5 d8e7 h5g4 b8c6 g1f3 d7d5 g4h4 e7c5 h4a4 e5e4 d2d4 c5e7 f3d2 e7b4 a4b4 c6b4".split():
            board.applyMove(parseAN(board, move))
        print("--------")
        print(board)

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

        self.assertIn("e1d1e", moves)
        self.assertIn("e1d1h", moves)

        fen = board.asFen()
        move = parseAN(board, "e1d1e")
        board.applyMove(move)
        print("e1d1e")
        print(board)

        self.assertEqual(placement(board.asFen()), "r1b1kbnr/ppp2ppp/8/3p4/1n1Pp3/4P3/PPPN1PPP/RNBKEB1R[heH]")

        board.popMove()
        self.assertEqual(placement(board.asFen()), placement(fen))
Exemple #9
0
    def test_pdb_database_get_bitboards(self):
        """Testing .pdb database get_bitboards"""

        db = self.load_test_pgn()

        board = LBoard()
        board.applyFen(FEN_START)

        for ply in range(4):
            bb_candidates = {}
            for lmove in genAllMoves(board):
                board.applyMove(lmove)
                if board.opIsChecked():
                    board.popMove()
                    continue
                bb_candidates[board.friends[0] | board.friends[1]] = lmove
                board.popMove()

            bitboards = db.get_bitboards(ply, bb_candidates)
            print("==========")
            for row in bitboards:
                print(row)
            print("----------")
            self.assertEqual(len(bitboards), BITBOARD_COUNT[ply])
            self.assertEqual(sum([row[1] for row in bitboards]), GAME_COUNT)
    def check_or_mate():
        board_clone = board.clone()
        board_clone.applyMove(move)
        sign = ""
        if board_clone.isChecked():
            for altmove in genAllMoves(board_clone):
                if board.variant == ATOMICCHESS:
                    from pychess.Variants.atomic import kingExplode

                    if kingExplode(
                        board_clone, altmove, 1 - board_clone.color
                    ) and not kingExplode(board_clone, altmove, board_clone.color):
                        sign = "+"
                        break
                    elif kingExplode(board_clone, altmove, board_clone.color):
                        continue
                board_clone.applyMove(altmove)
                if board_clone.opIsChecked():
                    board_clone.popMove()
                    continue
                sign = "+"
                break
            else:
                sign = "#"
        return sign
Exemple #11
0
def simple_activity (model, ply, phase):

    board = model.getBoardAtPly(ply).board
    oldboard = model.getBoardAtPly(ply-1).board
    color = 1-board.color
    move = model.getMoveAtPly(ply-1).move
    fcord = FCORD(move)
    tcord = TCORD(move)

    board.setColor(1-board.color)
    moves = len([m for m in genAllMoves(board) if FCORD(m) == tcord])
    board.setColor(1-board.color)
    oldmoves = len([m for m in genAllMoves(oldboard) if FCORD(m) == fcord])

    if moves > oldmoves:
        yield (moves-oldmoves)/2, _("places a %(piece)s more active: %(cord)s") % {
                'piece': reprPiece[board.arBoard[tcord]].lower(), 'cord': reprCord[tcord]}
Exemple #12
0
 def _genPossibleBoards(self, ply):
     possibleBoards = []
     curboard = self.view.model.getBoardAtPly(ply, self.view.shownVariationIdx)
     for lmove in lmovegen.genAllMoves(curboard.board):
         move = Move(lmove)
         board = curboard.move(move)
         possibleBoards.append(board)
     return possibleBoards
Exemple #13
0
 def _genPossibleBoards(self, ply):
     possibleBoards = []
     curboard = self.view.model.getBoardAtPly(ply)
     for lmove in lmovegen.genAllMoves(curboard.board):
         move = Move(lmove)
         board = curboard.move(move)
         possibleBoards.append(board)
     return possibleBoards
Exemple #14
0
def simple_activity(model, ply, phase):

    board = model.getBoardAtPly(ply).board
    oldboard = model.getBoardAtPly(ply - 1).board
    move = model.getMoveAtPly(ply - 1).move
    fcord = FCORD(move)
    tcord = TCORD(move)

    board.setColor(1 - board.color)
    moves = len([m for m in genAllMoves(board) if FCORD(m) == tcord])
    board.setColor(1 - board.color)
    oldmoves = len([m for m in genAllMoves(oldboard) if FCORD(m) == fcord])

    if moves > oldmoves:
        yield (moves -
               oldmoves) / 2, _("places a %(piece)s more active: %(cord)s") % {
                   'piece': reprPiece[board.arBoard[tcord]].lower(),
                   'cord': reprCord[tcord]}
Exemple #15
0
 def get_bb_candidates(board):
     bb_candidates = {}
     for lmove in genAllMoves(board):
         board.applyMove(lmove)
         if board.opIsChecked():
             board.popMove()
             continue
         bb_candidates[board.friends[0] | board.friends[1]] = lmove
         board.popMove()
     return bb_candidates
Exemple #16
0
 def _genPossibleBoards(self, ply):
     possibleBoards = []
     if len(self.view.model.players) == 2 and self.view.model.isEngine2EngineGame():
         return possibleBoards
     curboard = self.view.model.getBoardAtPly(ply, self.view.shownVariationIdx)
     for lmove in lmovegen.genAllMoves(curboard.board.clone()):
         move = Move(lmove)
         board = curboard.move(move)
         possibleBoards.append(board)
     return possibleBoards
Exemple #17
0
    def test_genAllMoves(self):
        """Testing validate move in Sittuyin variant"""
        board = SittuyinBoard(setup=FEN4)
        print(board)

        moves = set()
        for move in genAllMoves(board.board):
            moves.add(toAN(board.board, move))
        # pseudo legal moves
        m = set(("f6e7", "f6f7", "f6g7", "f6e6", "f6g6", "f6e5", "f6f5", "f6g5", "d5c6", "d5d6", "d5e6=F", "d5c4=F"))
        self.assertEqual(moves, m)
Exemple #18
0
def get_all_moves(request: WSGIRequest) -> JsonResponse:
    board = _get_board(request)
    from_coord = int(request.GET.get("index"))

    potential_moves = _get_potential_board_moves(from_coord, board)

    all_legal_moves = [Move(move) for move in genAllMoves(board.board)]

    legal_destinations = _get_legal_destinations(potential_moves,
                                                 all_legal_moves)

    return JsonResponse({"moves": legal_destinations})
Exemple #19
0
 def _genPossibleBoards(self, ply):
     possibleBoards = []
     if self.setup_position:
         return possibleBoards
     if len(self.view.model.players) == 2 and self.view.model.isEngine2EngineGame():
         return possibleBoards
     curboard = self.view.model.getBoardAtPly(ply, self.view.shownVariationIdx)
     for lmove in lmovegen.genAllMoves(curboard.board.clone()):
         move = Move(lmove)
         board = curboard.move(move)
         possibleBoards.append(board)
     return possibleBoards
Exemple #20
0
    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)
Exemple #21
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)
Exemple #22
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)
Exemple #23
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)
Exemple #24
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)
Exemple #25
0
    def perft(self, board, depth, prevmoves):
        if depth == 0:
            self.count += 1
            return
        
        for move in genAllMoves(board):
            board.applyMove(move)
            if board.opIsChecked():
                board.popMove()
                continue

            # Validator test
            board.popMove()
            self.assertTrue(validateMove(board, move))

            board.applyMove (move)
            self.perft(board, depth-1, prevmoves)
            board.popMove()
Exemple #26
0
def do_perft(board, depth, root):
    nodes = 0
    if depth == 0:
        return 1
    
    for move in genAllMoves(board):
        board.applyMove(move)
        if board.opIsChecked():
            board.popMove()
            continue

        count = do_perft(board, depth-1, root-1)
        nodes += count
        board.popMove()
        if root > 0:
            print("%8s %10d %10d" % (toLAN(board, move), count, nodes))

    return nodes
Exemple #27
0
    def perft(self, board, depth, prevmoves):
        if depth == 0:
            self.count += 1
            return

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

            # Validator test
            board.popMove()
            self.assertTrue(validateMove(board, move))

            board.applyMove(move)
            self.perft(board, depth - 1, prevmoves)
            board.popMove()
Exemple #28
0
    def update_tree(self, load_games=True):
        bb = self.board.friends[0] | self.board.friends[1]
        self.gamelist.ply = self.board.plyCount
        self.gamelist.chessfile.build_where_bitboards(self.board.plyCount, bb)
        self.gamelist.offset = 0
        self.gamelist.chessfile.build_query()
        if load_games and self.filtered:
            self.gamelist.load_games()

        bb_candidates = {}
        for lmove in genAllMoves(self.board):
            self.board.applyMove(lmove)
            if self.board.opIsChecked():
                self.board.popMove()
                continue
            bb_candidates[self.board.friends[0]
                          | self.board.friends[1]] = lmove
            self.board.popMove()

        result = []
        # print("get_bitboards() for %s bb_candidates" % len(bb_candidates))
        bb_list = self.gamelist.chessfile.get_bitboards(
            self.board.plyCount + 1, bb_candidates)

        for bb, count, white_won, blackwon, draw, white_elo_avg, black_elo_avg in bb_list:
            try:
                result.append((bb_candidates[bb], count, white_won, blackwon,
                               draw, white_elo_avg, black_elo_avg))
                # print("OK      ", bb, count, white_won, blackwon, draw, white_elo_avg, black_elo_avg)
            except KeyError:
                # print("KeyError", bb, count, white_won, blackwon, draw, white_elo_avg, black_elo_avg)
                pass

        self.clear_tree()

        for lmove, count, white_won, blackwon, draw, white_elo_avg, black_elo_avg in result:
            perf = 0 if not count else round(
                (white_won * 100. + draw * 50.) / count)
            elo_avg = white_elo_avg if self.board.color == WHITE else black_elo_avg
            self.liststore.append(
                [lmove, toSAN(self.board, lmove), count, perf, elo_avg])
Exemple #29
0
    def test_moves_from_startpos(self):
        board = LBoard(SCHESS)
        board.applyFen(SCHESSSTART)

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

            board.applyMove(move)
            board.popMove()
            self.assertEqual(placement(board.asFen()), placement(SCHESSSTART))

        self.assertIn("b1a3e", moves)
        self.assertIn("b1a3h", moves)
        self.assertIn("b1c3e", moves)
        self.assertIn("b1c3h", moves)

        self.assertIn("g1f3e", moves)
        self.assertIn("g1f3h", moves)
        self.assertIn("g1h3e", moves)
        self.assertIn("g1h3h", moves)
Exemple #30
0
    def test_disambig_gating_san(self):
        FEN = "rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/2N5/PP2PPPP/RHBQKBNR[Eeh] b KQACDEFGHkqabcdefh - 1 3"
        board = LBoard(SCHESS)
        board.applyFen(FEN)

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

        self.assertIn("f6d7", moves)
        self.assertNotIn("f6d7/H", moves)
        self.assertNotIn("f6d7/E", moves)
        self.assertIn("b8d7", moves)
        self.assertIn("b8d7h", moves)
        self.assertIn("b8d7e", moves)

        self.assertEqual(repr(Move.Move(parseSAN(board, 'Nfd7'))), 'f6d7')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'Nbd7'))), 'b8d7')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'Nbd7/H'))), 'b8d7h')
        self.assertEqual(repr(Move.Move(parseSAN(board, 'Nbd7/E'))), 'b8d7e')
Exemple #31
0
 def check_or_mate():
     board_clone = board.clone()
     board_clone.applyMove(move)
     sign = ""
     if board_clone.isChecked():
         for altmove in genAllMoves (board_clone):
             if board.variant == ATOMICCHESS:
                 from pychess.Variants.atomic import kingExplode
                 if kingExplode(board_clone, altmove, 1-board_clone.color) and \
                     not kingExplode(board_clone, altmove, board_clone.color):
                     sign = "+"
                     break
                 elif kingExplode(board_clone, altmove, board_clone.color):
                     continue
             board_clone.applyMove(altmove)
             if board_clone.opIsChecked():
                 board_clone.popMove()
                 continue
             sign = "+"
             break
         else:
             sign = "#"
     return sign
Exemple #32
0
    def run(self):
        while True:
            try:
                line = raw_input()
            except EOFError:
                line = "quit"
            lines = line.split()

            try:
                if not lines:
                    continue

                log.debug(line, extra={"task": "xboard"})

                ########## CECP commands ##########
                # See http://home.hccnet.nl/h.g.muller/engine-intf.html

                if lines[0] == "xboard":
                    pass

                elif lines[0] == "protover":
                    stringPairs = [
                        "=".join(
                            [k,
                             '"%s"' % v if isinstance(v, str) else str(v)])
                        for k, v in self.features.items()
                    ]
                    self.print("feature %s" % " ".join(stringPairs))
                    self.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.outOfBook = False
                    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[1] == "3check":
                            self.board.variant = THREECHECKCHESS
                        elif lines[1] == "kingofthehill":
                            self.board.variant = KINGOFTHEHILLCHESS
                            self.print("setup (PNBRQKpnbrqk) 8x8+0_fairy %s" %
                                       FEN_START)
                        elif lines[1] == "asean":
                            self.board = LBoard(ASEANCHESS)
                            self.board.applyFen(ASEANSTART)
                        elif lines[1] == "makruk":
                            self.board = LBoard(MAKRUKCHESS)
                            self.board.applyFen(MAKRUKSTART)
                        elif lines[1] == "cambodian":
                            self.board = LBoard(CAMBODIANCHESS)
                            self.board.applyFen(KAMBODIANSTART)
                            self.print(
                                "setup (PN.R.M....SKpn.r.m....sk) 8x8+0_makruk %s"
                                % KAMBODIANSTART)
                            self.print("piece K& KiN")
                            self.print("piece M& FifD")
                        elif lines[1] == "sittuyin":
                            self.board = LBoard(SITTUYINCHESS)
                            self.board.applyFen(SITTUYINSTART)
                            self.print(
                                "setup (PN.R.F....SKpn.r.f....sk) 8x8+6_bughouse %s"
                                % SITTUYINSTART)
                            self.print("piece N& Nj@3")
                            self.print("piece S& FfWj@3")
                            self.print("piece F& Fjb@3")
                            self.print("piece R& R@1")
                            self.print("piece K& Kj@3")
                            self.print("piece P& fmWfcFj@3")

                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 range(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 as e:
                        self.print("Error (unknown command): %s" % lines[1])
                        self.print(self.board)
                        continue
                    if not validateMove(self.board, move):
                        self.print("Illegal move: %s" % lines[1])
                        self.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":
                    self.print("pong %s" % lines[1])

                elif lines[0] == "draw":
                    if self.__willingToDraw():
                        self.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:
                        self.print("tellusererror Illegal position: %s" %
                                   str(e))

                # "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:
                            self.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:
                        self.print("Error (already searching):", line)
                    else:
                        limit = int(lines[1])
                        if limit < 1:
                            self.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":
                    if len(lines) >= 3 and lines[1] == "gaviota":
                        conf.set("egtb_path", conf.get("egtb_path", lines[2]))
                        from pychess.Utils.lutils.lsearch import enableEGTB
                        enableEGTB()

                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:
                            self.print(
                                "Error (argument must be an integer 0..100): %s"
                                % 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] == "moves":
                    self.print(self.board)
                    self.print([
                        toSAN(self.board, move)
                        for move in genAllMoves(self.board)
                    ])

                elif lines[0] == "captures":
                    self.print(self.board)
                    self.print([
                        toSAN(self.board, move)
                        for move in genCaptures(self.board)
                    ])

                elif lines[0] == "evasions":
                    self.print(self.board)
                    self.print([
                        toSAN(self.board, move)
                        for move in genCheckEvasions(self.board)
                    ])

                elif lines[0] == "benchmark":
                    benchmark()

                elif lines[0] == "profile":
                    if len(lines) > 1:
                        import cProfile
                        cProfile.runctx("benchmark()", locals(), globals(),
                                        lines[1])
                    else:
                        self.print("Usage: profile outputfilename")

                elif lines[0] == "perft":
                    root = "0" if len(lines) < 3 else lines[2]
                    depth = "1" if len(lines) == 1 else lines[1]
                    if root.isdigit() and depth.isdigit():
                        perft(self.board, int(depth), int(root))
                    else:
                        self.print("Error (arguments must be integer")

                elif len(lines) == 1:
                    # A GUI without usermove support might try to send a move.
                    try:
                        move = parseAny(self.board, line)
                    except:
                        self.print("Error (unknown command): %s" % line)
                        continue
                    if not validateMove(self.board, move):
                        self.print("Illegal move: %s" % lines[0])
                        self.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:
                    self.print("Error (unknown command): %s" % line)
            except IndexError:
                self.print("Error (missing argument): %s" % line)
Exemple #33
0
    def test_apply_pop(self):
        """Testing Crazyhouse applyMove popMove"""

        board = LBoard(variant=CRAZYHOUSECHESS)
        board.applyFen(FEN2)

        holding0 = (board.holding[0].copy(), board.holding[1].copy())
        promoted0 = board.promoted[:]
        capture_promoting0 = board.capture_promoting
        hist_capture_promoting0 = board.hist_capture_promoting[:]

        print_board_promoted = False
        print_apply_pop = False

        for lmove1 in genAllMoves(board):
            # if lmove1 != parseAN(board, "c7b8=Q"):
            #    continue
            board.applyMove(lmove1)
            if print_apply_pop:
                print("applyMove1", Move(lmove1), board.holding,
                      board.capture_promoting)
            if print_board_promoted:
                print(board.promoted)
            if board.opIsChecked():
                if print_apply_pop:
                    print("popMove1 (invalid)", Move(lmove1))
                board.popMove()
                continue

            holding1 = (board.holding[0].copy(), board.holding[1].copy())
            promoted1 = board.promoted[:]
            capture_promoting1 = board.capture_promoting
            hist_capture_promoting1 = board.hist_capture_promoting[:]
            for lmove2 in genAllMoves(board):
                # if lmove2 != parseAN(board, "e8f7"):
                #   continue
                board.applyMove(lmove2)
                if print_apply_pop:
                    print("   applyMove2", Move(lmove2), board.holding,
                          board.capture_promoting)
                if print_board_promoted:
                    print(board.promoted)
                if board.opIsChecked():
                    if print_apply_pop:
                        print("   popMove2 (invalid)", Move(lmove2))
                    board.popMove()
                    continue

                holding2 = (board.holding[0].copy(), board.holding[1].copy())
                promoted2 = board.promoted[:]
                capture_promoting2 = board.capture_promoting
                hist_capture_promoting2 = board.hist_capture_promoting[:]
                for lmove3 in genAllMoves(board):
                    # if lmove3 != parseAN(board, "b8c8"):
                    #   continue
                    board.applyMove(lmove3)
                    if print_apply_pop:
                        print("      applyMove3", Move(lmove3), board.holding,
                              board.capture_promoting)
                    if print_board_promoted:
                        print(board.promoted)
                    if board.opIsChecked():
                        if print_apply_pop:
                            print("      popMove3 (invalid)", Move(lmove3))
                        board.popMove()
                        continue

                    board.popMove()
                    if print_apply_pop:
                        print("      popMove3", Move(lmove3), board.holding,
                              board.capture_promoting)
                    if print_board_promoted:
                        print(board.promoted)

                    self.assertEqual(holding2, board.holding)
                    self.assertEqual(promoted2, board.promoted)
                    self.assertEqual(capture_promoting2,
                                     board.capture_promoting)
                    self.assertEqual(hist_capture_promoting2,
                                     board.hist_capture_promoting)

                board.popMove()
                if print_apply_pop:
                    print("   popMove2", Move(lmove2), board.holding,
                          board.capture_promoting)
                if print_board_promoted:
                    print(board.promoted)

                self.assertEqual(holding1, board.holding)
                self.assertEqual(promoted1, board.promoted)
                self.assertEqual(capture_promoting1, board.capture_promoting)
                self.assertEqual(hist_capture_promoting1,
                                 board.hist_capture_promoting)

            board.popMove()
            if print_apply_pop:
                print("popMove1", Move(lmove1), board.holding,
                      board.capture_promoting)
            if print_board_promoted:
                print(board.promoted)

            self.assertEqual(holding0, board.holding)
            self.assertEqual(promoted0, board.promoted)
            self.assertEqual(capture_promoting0, board.capture_promoting)
            self.assertEqual(hist_capture_promoting0,
                             board.hist_capture_promoting)
Exemple #34
0
def validateMove(board, move):
    return move in genAllMoves(board)
Exemple #35
0
    def test_apply_pop(self):
        """Testing Crazyhouse applyMove popMove"""

        board = LBoard(variant=CRAZYHOUSECHESS)
        board.applyFen(FEN1)
        
        holding0 = (board.holding[0].copy(), board.holding[1].copy())
        promoted0 = board.promoted[:]
        capture_promoting0 = board.capture_promoting
        hist_capture_promoting0 = board.hist_capture_promoting[:]

        print_board_promoted = False
        print_apply_pop = False

        for lmove1 in genAllMoves(board):
            #if lmove1 != parseAN(board, "c7b8=Q"):
            #    continue
            board.applyMove(lmove1)
            if print_apply_pop: print("applyMove1", Move(lmove1), board.holding, board.capture_promoting)
            if print_board_promoted: print(board.promoted)
            if board.opIsChecked():
                if print_apply_pop: print("popMove1 (invalid)", Move(lmove1))
                board.popMove()
                continue
                
            holding1 = (board.holding[0].copy(), board.holding[1].copy())
            promoted1 = board.promoted[:]
            capture_promoting1 = board.capture_promoting
            hist_capture_promoting1 = board.hist_capture_promoting[:]
            for lmove2 in genAllMoves(board):
                #if lmove2 != parseAN(board, "e8f7"):
                #   continue
                board.applyMove(lmove2)
                if print_apply_pop: print("   applyMove2", Move(lmove2), board.holding, board.capture_promoting)
                if print_board_promoted: print(board.promoted)
                if board.opIsChecked():
                    if print_apply_pop: print("   popMove2 (invalid)", Move(lmove2))
                    board.popMove()
                    continue

                holding2 = (board.holding[0].copy(), board.holding[1].copy())
                promoted2 = board.promoted[:]
                capture_promoting2 = board.capture_promoting
                hist_capture_promoting2 = board.hist_capture_promoting[:]
                for lmove3 in genAllMoves(board):
                    #if lmove3 != parseAN(board, "b8c8"):
                    #   continue
                    board.applyMove(lmove3)
                    if print_apply_pop: print("      applyMove3", Move(lmove3), board.holding, board.capture_promoting)
                    if print_board_promoted: print(board.promoted)
                    if board.opIsChecked():
                        if print_apply_pop: print("      popMove3 (invalid)", Move(lmove3))
                        board.popMove()
                        continue

                    board.popMove()
                    if print_apply_pop: print("      popMove3", Move(lmove3), board.holding, board.capture_promoting)
                    if print_board_promoted: print(board.promoted)

                    self.assertEqual(holding2, board.holding)
                    self.assertEqual(promoted2, board.promoted)
                    self.assertEqual(capture_promoting2, board.capture_promoting)
                    self.assertEqual(hist_capture_promoting2, board.hist_capture_promoting)

                board.popMove()
                if print_apply_pop: print("   popMove2", Move(lmove2), board.holding, board.capture_promoting)
                if print_board_promoted: print(board.promoted)

                self.assertEqual(holding1, board.holding)
                self.assertEqual(promoted1, board.promoted)
                self.assertEqual(capture_promoting1, board.capture_promoting)
                self.assertEqual(hist_capture_promoting1, board.hist_capture_promoting)
                
            board.popMove()
            if print_apply_pop: print("popMove1", Move(lmove1), board.holding, board.capture_promoting)
            if print_board_promoted: print(board.promoted)

            self.assertEqual(holding0, board.holding)
            self.assertEqual(promoted0, board.promoted)
            self.assertEqual(capture_promoting0, board.capture_promoting)
            self.assertEqual(hist_capture_promoting0, board.hist_capture_promoting)
Exemple #36
0
def validateMove(board, move):
    return move in genAllMoves(board)
Exemple #37
0
def toSAN(board, move, localRepr=False):
    """ Returns a Short/Abbreviated Algebraic Notation string of a move
        The board should be prior to the move """
    def check_or_mate():
        board_clone = board.clone()
        board_clone.applyMove(move)
        sign = ""
        if board_clone.isChecked():
            for altmove in genAllMoves(board_clone):
                if board.variant == ATOMICCHESS:
                    from pychess.Variants.atomic import kingExplode
                    if kingExplode(board_clone, altmove, 1 - board_clone.color) and \
                            not kingExplode(board_clone, altmove, board_clone.color):
                        sign = "+"
                        break
                    elif kingExplode(board_clone, altmove, board_clone.color):
                        continue
                board_clone.applyMove(altmove)
                if board_clone.opIsChecked():
                    board_clone.popMove()
                    continue
                sign = "+"
                break
            else:
                sign = "#"
        return sign

    flag = move >> 12

    if flag == NULL_MOVE:
        return "--"

    fcord = (move >> 6) & 63
    if flag == KING_CASTLE:
        return "O-O%s" % check_or_mate()
    elif flag == QUEEN_CASTLE:
        return "O-O-O%s" % check_or_mate()

    tcord = move & 63

    fpiece = fcord if flag == DROP else board.arBoard[fcord]
    tpiece = board.arBoard[tcord]

    part0 = ""
    part1 = ""

    if fpiece != PAWN or flag == DROP:
        if board.variant in (CAMBODIANCHESS, MAKRUKCHESS):
            part0 += reprSignMakruk[fpiece]
        elif board.variant == SITTUYINCHESS:
            part0 += reprSignSittuyin[fpiece]
        elif localRepr:
            part0 += localReprSign[fpiece]
        else:
            part0 += reprSign[fpiece]

    part1 = reprCord[tcord]

    if flag == DROP:
        return "%s@%s%s" % (part0, part1, check_or_mate())

    if fpiece not in (PAWN, KING):
        xs = []
        ys = []

        board_clone = board.clone()
        for altmove in genAllMoves(board_clone, drops=False):
            mfcord = FCORD(altmove)
            if board_clone.arBoard[mfcord] == fpiece and \
                    mfcord != fcord and \
                    TCORD(altmove) == tcord:
                board_clone.applyMove(altmove)
                if not board_clone.opIsChecked():
                    xs.append(FILE(mfcord))
                    ys.append(RANK(mfcord))
                board_clone.popMove()

        x = FILE(fcord)
        y = RANK(fcord)

        if ys or xs:
            if y in ys and x not in xs:
                # If we share rank with another piece, but not file
                part0 += reprFile[x]
            elif x in xs and y not in ys:
                # If we share file with another piece, but not rank
                part0 += reprRank[y]
            elif x in xs and y in ys:
                # If we share both file and rank with other pieces
                part0 += reprFile[x] + reprRank[y]
            else:
                # If we doesn't share anything, it is standard to put file
                part0 += reprFile[x]

    if tpiece != EMPTY or flag == ENPASSANT:
        if not (board.variant == SITTUYINCHESS and fcord == tcord):
            part1 = "x" + part1
            if fpiece == PAWN:
                part0 += reprFile[FILE(fcord)]

    notat = part0 + part1
    if flag in PROMOTIONS:
        if board.variant in (CAMBODIANCHESS, MAKRUKCHESS):
            notat += "=" + reprSignMakruk[PROMOTE_PIECE(flag)]
        elif board.variant == SITTUYINCHESS:
            notat += "=" + reprSignSittuyin[PROMOTE_PIECE(flag)]
        elif localRepr:
            notat += "=" + localReprSign[PROMOTE_PIECE(flag)]
        else:
            notat += "=" + reprSign[PROMOTE_PIECE(flag)]

    return "%s%s" % (notat, check_or_mate())
    def perft(self, board, depth, prevmoves):
        if depth == 0:
            self.count += 1
            return
        
        if board.isChecked():
            # If we are checked we can use the genCheckEvasions function as well
            # as genAllMoves. Here we try both functions to ensure they return
            # the same result.
            nmoves = []
            for nmove in genAllMoves(board):
                board.applyMove(nmove)
                if board.opIsChecked():
                    board.popMove()
                    continue


                nmoves.append(nmove)
                board.popMove()
                # Validator test
                self.assertTrue(validateMove(board, nmove))
            
            cmoves = []
            
            for move in genCheckEvasions(board):
                board.applyMove(move)
                cmoves.append(move)
                board.popMove()
                # Validator test
                self.assertTrue(validateMove(board, move))
            
            # This is not any kind of alphaBeta sort. Only int sorting, to make
            # comparison possible
            nmoves.sort()
            cmoves.sort()
            
            if nmoves == cmoves:
                for move in cmoves:
                    prevmoves.append(toSAN (board, move))
                    board.applyMove(move)
                    self.perft(board, depth-1, prevmoves)
                    board.popMove()
            else:
                print board
                print "nmoves"
                for move in nmoves:
                    print toSAN (board, move)
                print "cmoves"
                for move in cmoves:
                    print toSAN (board, move)
                self.assertEqual(nmoves, cmoves)
                
        else:
            for move in genAllMoves(board):
                board.applyMove(move)
                if board.opIsChecked():
                    board.popMove()
                    continue
                
                # Validator test
                board.popMove()
                self.assertTrue(validateMove(board, move))
                
                # San test
                san = toSAN (board, move)
                try:
                    move2 = parseSAN(board, san)
                except ParsingError, e:
                    print prevmoves
                    raise ParsingError, e
                self.assertEqual (move, move2)
                
                board.applyMove (move)
                
                self.perft(board, depth-1, prevmoves)
                board.popMove()
Exemple #39
0
    def run(self):
        while True:
            try:
                line = get_input()
            except EOFError:
                line = "quit"
            lines = line.split()

            try:
                if not lines:
                    continue

                log.debug(line, extra={"task": "xboard"})

                # CECP commands
                # See http://home.hccnet.nl/h.g.muller/engine-intf.html

                if lines[0] == "xboard":
                    pass

                elif lines[0] == "protover":
                    stringPairs = ["=".join([k, '"%s"' % v if isinstance(
                        v, str) else str(v)]) for k, v in self.features.items()]
                    self.print("feature %s" % " ".join(stringPairs))
                    self.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.outOfBook = False
                    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] == "giveaway":
                            self.board.variant = GIVEAWAYCHESS
                        elif lines[1] == "atomic":
                            self.board.variant = ATOMICCHESS
                            self.board.iniAtomic()
                        elif lines[1] == "3check":
                            self.board.variant = THREECHECKCHESS
                        elif lines[1] == "kingofthehill":
                            self.board.variant = KINGOFTHEHILLCHESS
                            self.print("setup (PNBRQKpnbrqk) 8x8+0_fairy %s" %
                                       FEN_START)
                        elif lines[1] == "horde":
                            self.board = LBoard(HORDECHESS)
                            self.board.applyFen(HORDESTART)
                        elif lines[1] == "asean":
                            self.board = LBoard(ASEANCHESS)
                            self.board.applyFen(ASEANSTART)
                        elif lines[1] == "makruk":
                            self.board = LBoard(MAKRUKCHESS)
                            self.board.applyFen(MAKRUKSTART)
                        elif lines[1] == "cambodian":
                            self.board = LBoard(CAMBODIANCHESS)
                            self.board.applyFen(KAMBODIANSTART)
                            self.print(
                                "setup (PN.R.M....SKpn.r.m....sk) 8x8+0_makruk %s"
                                % KAMBODIANSTART)
                            self.print("piece K& KiN")
                            self.print("piece M& FifD")
                        elif lines[1] == "sittuyin":
                            self.board = LBoard(SITTUYINCHESS)
                            self.board.applyFen(SITTUYINSTART)
                            self.print(
                                "setup (PN.R.F....SKpn.r.f....sk) 8x8+6_bughouse %s"
                                % SITTUYINSTART)
                            self.print("piece N& Nj@3")
                            self.print("piece S& FfWj@3")
                            self.print("piece F& Fjb@3")
                            self.print("piece R& R@1")
                            self.print("piece K& Kj@3")
                            self.print("piece P& fmWfcFj@3")

                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 range(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 as err:
                        self.print("Error (unknown command): %s" % lines[1])
                        self.print(self.board.prepr(ascii=ASCII))
                        continue
                    if not validateMove(self.board, move):
                        self.print("Illegal move: %s" % lines[1])
                        self.print(self.board.prepr(ascii=ASCII))
                        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":
                    self.print("pong %s" % lines[1])

                elif lines[0] == "draw":
                    if self.__willingToDraw():
                        self.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 err:
                        self.print("tellusererror Illegal position: %s" %
                                   str(err))

                # "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:
                            self.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:
                        self.print("Error (already searching):", line)
                    else:
                        limit = int(lines[1])
                        if limit < 1:
                            self.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":
                    if len(lines) >= 3 and lines[1] == "gaviota":
                        conf.set("egtb_path", conf.get("egtb_path", lines[2]))
                        from pychess.Utils.lutils.lsearch import enableEGTB
                        enableEGTB()

                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:
                            self.print(
                                "Error (argument must be an integer 0..100): %s"
                                % 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] == "moves":
                    self.print(self.board.prepr(ascii=ASCII))
                    self.print([toSAN(self.board, move)
                                for move in genAllMoves(self.board)])

                elif lines[0] == "captures":
                    self.print(self.board.prepr(ascii=ASCII))
                    self.print([toSAN(self.board, move)
                                for move in genCaptures(self.board)])

                elif lines[0] == "evasions":
                    self.print(self.board.prepr(ascii=ASCII))
                    self.print([toSAN(self.board, move)
                                for move in genCheckEvasions(self.board)])

                elif lines[0] == "benchmark":
                    if len(lines) > 1:
                        benchmark(int(lines[1]))
                    else:
                        benchmark()

                elif lines[0] == "profile":
                    if len(lines) > 1:
                        import cProfile
                        cProfile.runctx("benchmark()", locals(), globals(),
                                        lines[1])
                    else:
                        self.print("Usage: profile outputfilename")

                elif lines[0] == "perft":
                    root = "0" if len(lines) < 3 else lines[2]
                    depth = "1" if len(lines) == 1 else lines[1]
                    if root.isdigit() and depth.isdigit():
                        perft(self.board, int(depth), int(root))
                    else:
                        self.print("Error (arguments must be integer")

                elif lines[0] == "stop_unittest":
                    break

                elif len(lines) == 1:
                    # A GUI without usermove support might try to send a move.
                    try:
                        move = parseAny(self.board, line)
                    except ParsingError:
                        self.print("Error (unknown command): %s" % line)
                        continue
                    if not validateMove(self.board, move):
                        self.print("Illegal move: %s" % lines[0])
                        self.print(self.board.prepr(ascii=ASCII))
                        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:
                    self.print("Error (unknown command): %s" % line)
            except IndexError:
                self.print("Error (missing argument): %s" % line)
Exemple #40
0
    def perft(self, board, depth, prevmoves):
        if depth == 0:
            self.count += 1
            return

        if board.isChecked():
            # If we are checked we can use the genCheckEvasions function as well
            # as genAllMoves. Here we try both functions to ensure they return
            # the same result.
            nmoves = []
            for nmove in genAllMoves(board):
                board.applyMove(nmove)
                if board.opIsChecked():
                    board.popMove()
                    continue

                nmoves.append(nmove)
                board.popMove()
                # Validator test
                self.assertTrue(validateMove(board, nmove))

            cmoves = []

            for move in genCheckEvasions(board):
                board.applyMove(move)
                if board.opIsChecked():
                    board.popMove()
                    continue

                cmoves.append(move)
                board.popMove()
                # Validator test
                self.assertTrue(validateMove(board, move))

            # This is not any kind of alphaBeta sort. Only int sorting, to make
            # comparison possible
            nmoves.sort()
            cmoves.sort()

            if nmoves == cmoves:
                for move in cmoves:
                    prevmoves.append(toSAN(board, move))
                    board.applyMove(move)
                    self.perft(board, depth - 1, prevmoves)
                    board.popMove()
            else:
                print(board)
                print("nmoves")
                for move in nmoves:
                    print(toSAN(board, move))
                print("cmoves")
                for move in cmoves:
                    print(toSAN(board, move))
                self.assertEqual(nmoves, cmoves)

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

                # Validator test
                board.popMove()
                self.assertTrue(validateMove(board, move))

                # San test
                san = toSAN(board, move)
                # print(san)
                try:
                    move2 = parseSAN(board, san)
                except ParsingError as e:
                    print(prevmoves)
                    raise ParsingError(e)
                self.assertEqual(move, move2)

                board.applyMove(move)

                self.perft(board, depth - 1, prevmoves)
                board.popMove()
Exemple #41
0
def toSAN (board, move, localRepr=False):
    """ Returns a Short/Abbreviated Algebraic Notation string of a move 
        The board should be prior to the move """
    
    # Has to be importet at calltime, as lmovegen imports lmove
    #from lmovegen import genAllMoves

    def check_or_mate():
        board_clone = board.clone()
        board_clone.applyMove(move)
        sign = ""
        if board_clone.isChecked():
            for altmove in genAllMoves (board_clone):
                if board.variant == ATOMICCHESS:
                    from pychess.Variants.atomic import kingExplode
                    if kingExplode(board_clone, altmove, 1-board_clone.color) and \
                        not kingExplode(board_clone, altmove, board_clone.color):
                        sign = "+"
                        break
                    elif kingExplode(board_clone, altmove, board_clone.color):
                        continue
                board_clone.applyMove(altmove)
                if board_clone.opIsChecked():
                    board_clone.popMove()
                    continue
                sign = "+"
                break
            else:
                sign = "#"
        return sign
    
    flag = move >> 12
    
    if flag == NULL_MOVE:
        return "--"
    
    fcord = (move >> 6) & 63
    if flag == KING_CASTLE:
        return "O-O%s" % check_or_mate()
    elif flag == QUEEN_CASTLE:
        return "O-O-O%s" % check_or_mate()
    
    tcord = move & 63
    
    fpiece = fcord if flag == DROP else board.arBoard[fcord]
    tpiece = board.arBoard[tcord]
    
    part0 = ""
    part1 = ""
    
    if fpiece != PAWN or flag == DROP:
        if localRepr:
            part0 += localReprSign[fpiece]
        else:
            part0 += reprSign[fpiece]
    
    part1 = reprCord[tcord]

    if flag == DROP:
        return "%s@%s%s" % (part0, part1, check_or_mate())
    
    if not fpiece in (PAWN, KING):
        xs = []
        ys = []
        
        board_clone = board.clone()
        for altmove in genAllMoves(board_clone, drops=False):
            mfcord = FCORD(altmove)
            if board_clone.arBoard[mfcord] == fpiece and \
                    mfcord != fcord and \
                    TCORD(altmove) == tcord:
                board_clone.applyMove(altmove)
                if not board_clone.opIsChecked():
                    xs.append(FILE(mfcord))
                    ys.append(RANK(mfcord))
                board_clone.popMove()

        x = FILE(fcord)
        y = RANK(fcord)
        
        if ys or xs:
            if y in ys and not x in xs:
                # If we share rank with another piece, but not file
                part0 += reprFile[x]
            elif x in xs and not y in ys:
                # If we share file with another piece, but not rank
                part0 += reprRank[y]
            elif x in xs and y in ys:
                # If we share both file and rank with other pieces
                part0 += reprFile[x] + reprRank[y]
            else:
                # If we doesn't share anything, it is standard to put file
                part0 += reprFile[x]
    
    if tpiece != EMPTY or flag == ENPASSANT:
        part1 = "x" + part1
        if fpiece == PAWN:
            part0 += reprFile[FILE(fcord)]
    
    notat = part0 + part1
    if flag in PROMOTIONS:
        if localRepr:
            notat += "="+localReprSign[PROMOTE_PIECE(flag)]
        else:
            notat += "="+reprSign[PROMOTE_PIECE(flag)]
    
    return "%s%s" % (notat, check_or_mate())