Example #1
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))
Example #2
0
    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")
Example #3
0
    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")
Example #4
0
    def test_default_gating_avail(self):
        board = LBoard(SCHESS)
        board.applyFen(SCHESSSTART)

        print(board)
        print(toString(board.virgin[0]))
        print(toString(board.virgin[1]))

        self.assertEqual(board.virgin[0], brank8[1])
        self.assertEqual(board.virgin[1], brank8[0])

        board = LBoard(SCHESS)
        FEN = "r1hqerk1/pp1nbppp/2pp1nb1/4p3/2PPP3/2N1B1PP/PP2NPB1/RH1QK2R/E w KQHEDA - 2 10"
        board.applyFen(FEN)
        print("-----------")
        print(board)

        move = parseSAN(board, "O-O")
        board.applyMove(move)
        castl = board.asFen().split()[2]

        self.assertNotIn("Q", castl)
        self.assertNotIn("K", castl)
        self.assertNotIn("E", castl)
        self.assertNotIn("H", castl)
Example #5
0
def get_board(gamepgn, movenum):
    #make a pyboard at that spot.
    moves_to_here = gamepgn.moves[:movenum]
    board = LBoard.LBoard(variant=3)
    board.applyFen(gamepgn.fen)
    for move in moves_to_here :
        longmove = lmove.parseSAN(board, move)
        board.applyMove(longmove)
    return board
Example #6
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')
Example #7
0
 def __onAmbiguousMove(self, errorManager, move):
     # This is really a fix for fics, but sometimes it is necessary
     if determineAlgebraicNotation(move) == SAN:
         self.board.popMove()
         move_ = parseSAN(self.board, move)
         lanmove = toLAN(self.board, move_)
         self.board.applyMove(move_)
         self.connection.bm.sendMove(lanmove)
     else:
         self.connection.cm.tellOpponent(
             "I'm sorry, I wanted to move %s, but FICS called " % move +
             "it 'Ambigious'. I can't find another way to express it, " +
             "so you can win")
         self.connection.bm.resign()
Example #8
0
 def __onAmbiguousMove (self, errorManager, move):
     # This is really a fix for fics, but sometimes it is necessary
     if determineAlgebraicNotation(move) == SAN:
         self.board.popMove()
         move_ = parseSAN(self.board, move)
         lanmove = toLAN(self.board, move_)
         self.board.applyMove(move_)
         self.connection.bm.sendMove(lanmove)
     else:
         self.connection.cm.tellOpponent(
                 "I'm sorry, I wanted to move %s, but FICS called " % move +
                 "it 'Ambigious'. I can't find another way to express it, " +
                 "so you can win")
         self.connection.bm.resign()
Example #9
0
    def test_board(self):
        FEN = "r2qk2r/pppbbppp/4pn2/1N1p4/1n1P4/4PN2/PPPBBPPP/R2QK2R[heHE] w KQkq - 10 8"
        board = SchessBoard(setup=FEN)
        # print("--------")
        # print(board)
        self.assertEqual(board.data[0][7].color, WHITE)
        self.assertEqual(board.data[0][7].piece, ROOK)

        board = board.move(Move.Move(parseSAN(board.board, 'O-O/Hh1')))
        # board.printPieces()

        self.assertEqual(board.data[0][7].color, WHITE)
        self.assertEqual(board.data[0][7].piece, HAWK)

        moves = "c3 c5 e3 d5 Nf3/E Nc6/H d4 e5 Nxe5 Nxe5 dxe5 Hxe5 e4 Nf6 Bf4/H Hc6 e5 Nd7 Be2 Nxe5 Bxe5 Hxe5 Bb5+ Bd7 Ee2 Bd6 Exe5+ Bxe5 Bxd7+ Qxd7/E"
        board = SchessBoard(setup=SCHESSSTART)
        for san in moves.split():
            move = parseSAN(board.board, san)
            board = board.move(Move.Move(move))
            # print(san)
            # board.printPieces()

        self.assertEqual(board.data[7][3].color, BLACK)
        self.assertEqual(board.data[7][3].piece, ELEPHANT)
Example #10
0
 def __onMoveCalculated (self, worker, sanmove):
     if worker.isCancelled() or not sanmove:
         return
     self.board.applyMove(parseSAN(self.board,sanmove))
     self.connection.bm.sendMove(sanmove)
     self.extendlog(["Move sent %s" % sanmove])
Example #11
0
 def __onMoveCalculated(self, worker, sanmove):
     if worker.isCancelled() or not sanmove:
         return
     self.board.applyMove(parseSAN(self.board, sanmove))
     self.connection.bm.sendMove(sanmove)
     self.extendlog(["Move sent %s" % sanmove])
Example #12
0
    def parse_string(self, string, board, position, variation=False):
        """Recursive parses a movelist part of one game.
        
           Arguments:
           srting - str (movelist)
           board - lboard (initial position)
           position - int (maximum ply to parse)
           variation- boolean (True if the string is a variation)"""
        
        boards = []
        boards_append = boards.append
        
        last_board = board
        if variation:
            # this board used only to hold initial variation comments
            boards_append(LBoard(board.variant))
        else:
            # initial game board
            boards_append(board)
        
        status = None
        parenthesis = 0
        v_string = ""
        for m in re.finditer(pattern, string):
            group, text = m.lastindex, m.group(m.lastindex)
            if parenthesis > 0:
                v_string += ' '+text

            if group == VARIATION_END:
                parenthesis -= 1
                if parenthesis == 0:
                    v_last_board.children.append(self.parse_string(v_string[:-1], last_board.prev, position, variation=True))
                    v_string = ""
                    continue

            elif group == VARIATION_START:
                parenthesis += 1
                if parenthesis == 1:
                    v_last_board = last_board

            if parenthesis == 0:
                if group == FULL_MOVE:
                    if not variation:
                        if position != -1 and last_board.plyCount >= position:
                            break

                    mstr = m.group(MOVE)
                    try:
                        lmove = parseSAN(last_board, mstr)
                    except ParsingError, e:
                        # TODO: save the rest as comment
                        # last_board.children.append(string[m.start():])
                        notation, reason, boardfen = e.args
                        ply = last_board.plyCount
                        if ply % 2 == 0:
                            moveno = "%d." % (ply/2+1)
                        else: moveno = "%d..." % (ply/2+1)
                        errstr1 = _("The game can't be read to end, because of an error parsing move %(moveno)s '%(notation)s'.") % {
                                    'moveno': moveno, 'notation': notation}
                        errstr2 = _("The move failed because %s.") % reason
                        self.error = LoadingError (errstr1, errstr2)
                        break
                    except:
                        ply = last_board.plyCount
                        if ply % 2 == 0:
                            moveno = "%d." % (ply/2+1)
                        else: moveno = "%d..." % (ply/2+1)
                        errstr1 = _( "Error parsing move %(moveno)s %(mstr)s") % {"moveno": moveno, "mstr": mstr}
                        self.error = LoadingError (errstr1, "")
                        break
Example #13
0
 def ondone(result):
     if not self.forced:
         self.board.applyMove(parseSAN(self.board, result))
         self.print("move %s" % result)
Example #14
0
 def ondone (result):
     self.board.applyMove(parseSAN(self.board,result))
     print "move %s" % result
Example #15
0
 def ondone(result):
     if not self.forced:
         self.board.applyMove(parseSAN(self.board, result))
         self.print("move %s" % result)
Example #16
0
    def simple_parse_movetext(self, string, board, movelist, bitboards):
        """Parses a movelist part of one game.
           If find anything not being a move immediately returns False
           It fills list of lmoves parsed with parseSAN() and
           list of integers representing a board with occupied fields bitboard

           Arguments:
           srting - str (movelist)
           board - lboard (FEN_START)
           movelist - an empty array("H") to fill
           bitboards - an empty list to fill

           Return: True if parser find moves only."""

        movelist_append = movelist.append

        for m in re.finditer(pattern, string):
            group, text = m.lastindex, m.group(m.lastindex)
            if group in (COMMENT_BRACE, COMMENT_NAG, VARIATION_END,
                         VARIATION_START, COMMENT_REST):
                return False

            elif group == FULL_MOVE:
                if m.group(MOVE_COMMENT):
                    return False

                mstr = m.group(MOVE)
                try:
                    lmove = parseSAN(board, mstr, full=False)
                except ParsingError as err:
                    notation, reason, boardfen = err.args
                    ply = board.plyCount
                    if ply % 2 == 0:
                        moveno = "%d." % (ply // 2 + 1)
                    else:
                        moveno = "%d..." % (ply // 2 + 1)
                    errstr1 = _(
                        "The game can't be read to end, because of an error parsing move %(moveno)s '%(notation)s'."
                    ) % {
                        'moveno': moveno,
                        'notation': notation
                    }
                    errstr2 = _("The move failed because %s.") % reason
                    self.error = LoadingError(errstr1, errstr2)
                    break
                except:
                    ply = board.plyCount
                    if ply % 2 == 0:
                        moveno = "%d." % (ply // 2 + 1)
                    else:
                        moveno = "%d..." % (ply // 2 + 1)
                    errstr1 = _("Error parsing move %(moveno)s %(mstr)s") % {
                        "moveno": moveno,
                        "mstr": mstr
                    }
                    self.error = LoadingError(errstr1, "")
                    break

                bitboards.append(board.friends[0] | board.friends[1])
                board.applyMove(lmove, full=False)
                movelist_append(lmove)

            elif group == RESULT:
                pass
            else:
                print("Unknown:", text)

        return True
Example #17
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')
Example #18
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')
Example #19
0
    def parse_movetext(self, string, board, position, variation=False):
        """Recursive parses a movelist part of one game.

           Arguments:
           srting - str (movelist)
           board - lboard (initial position)
           position - int (maximum ply to parse)
           variation- boolean (True if the string is a variation)"""

        boards = []
        boards_append = boards.append

        last_board = board
        if variation:
            # this board used only to hold initial variation comments
            boards_append(LBoard(board.variant))
        else:
            # initial game board
            boards_append(board)

        # status = None
        parenthesis = 0
        v_string = ""
        v_last_board = None
        for m in re.finditer(pattern, string):
            group, text = m.lastindex, m.group(m.lastindex)
            if parenthesis > 0:
                v_string += ' ' + text

            if group == VARIATION_END:
                parenthesis -= 1
                if parenthesis == 0:
                    if last_board.prev is None:
                        errstr1 = _("Error parsing %(mstr)s") % {"mstr": string}
                        self.error = LoadingError(errstr1, "")
                        return boards  # , status

                    v_last_board.children.append(
                        self.parse_movetext(v_string[:-1], last_board.prev, position, variation=True))
                    v_string = ""
                    continue

            elif group == VARIATION_START:
                parenthesis += 1
                if parenthesis == 1:
                    v_last_board = last_board

            if parenthesis == 0:
                if group == FULL_MOVE:
                    if not variation:
                        if position != -1 and last_board.plyCount >= position:
                            break

                    mstr = m.group(MOVE)
                    try:
                        lmove = parseSAN(last_board, mstr)
                    except ParsingError as err:
                        # TODO: save the rest as comment
                        # last_board.children.append(string[m.start():])
                        notation, reason, boardfen = err.args
                        ply = last_board.plyCount
                        if ply % 2 == 0:
                            moveno = "%d." % (ply // 2 + 1)
                        else:
                            moveno = "%d..." % (ply // 2 + 1)
                        errstr1 = _(
                            "The game can't be read to end, because of an error parsing move %(moveno)s '%(notation)s'.") % {
                                'moveno': moveno,
                                'notation': notation}
                        errstr2 = _("The move failed because %s.") % reason
                        self.error = LoadingError(errstr1, errstr2)
                        break
                    except:
                        ply = last_board.plyCount
                        if ply % 2 == 0:
                            moveno = "%d." % (ply // 2 + 1)
                        else:
                            moveno = "%d..." % (ply // 2 + 1)
                        errstr1 = _(
                            "Error parsing move %(moveno)s %(mstr)s") % {
                                "moveno": moveno,
                                "mstr": mstr}
                        self.error = LoadingError(errstr1, "")
                        break

                    new_board = last_board.clone()
                    new_board.applyMove(lmove)

                    if m.group(MOVE_COMMENT):
                        new_board.nags.append(symbol2nag(m.group(
                            MOVE_COMMENT)))

                    new_board.prev = last_board

                    # set last_board next, except starting a new variation
                    if variation and last_board == board:
                        boards[0].next = new_board
                    else:
                        last_board.next = new_board

                    boards_append(new_board)
                    last_board = new_board

                elif group == COMMENT_REST:
                    last_board.children.append(text[1:])

                elif group == COMMENT_BRACE:
                    comm = text.replace('{\r\n', '{').replace('\r\n}', '}')
                    comm = comm[1:-1].splitlines()
                    comment = ' '.join([line.strip() for line in comm])
                    if variation and last_board == board:
                        # initial variation comment
                        boards[0].children.append(comment)
                    else:
                        last_board.children.append(comment)

                elif group == COMMENT_NAG:
                    last_board.nags.append(text)

                # TODO
                elif group == RESULT:
                    # if text == "1/2":
                    #    status = reprResult.index("1/2-1/2")
                    # else:
                    #    status = reprResult.index(text)
                    break

                else:
                    print("Unknown:", text)

        return boards  # , status
Example #20
0
    def parse_movetext(self, string, board, position, variation=False):
        """Recursive parses a movelist part of one game.

           Arguments:
           srting - str (movelist)
           board - lboard (initial position)
           position - int (maximum ply to parse)
           variation- boolean (True if the string is a variation)"""

        boards = []
        boards_append = boards.append

        last_board = board
        if variation:
            # this board used only to hold initial variation comments
            boards_append(LBoard(board.variant))
        else:
            # initial game board
            boards_append(board)

        # status = None
        parenthesis = 0
        v_string = ""
        v_last_board = None
        for m in re.finditer(pattern, string):
            group, text = m.lastindex, m.group(m.lastindex)
            if parenthesis > 0:
                v_string += ' ' + text

            if group == VARIATION_END:
                parenthesis -= 1
                if parenthesis == 0:
                    if last_board.prev is None:
                        errstr1 = _("Error parsing %(mstr)s") % {"mstr": string}
                        self.error = LoadingError(errstr1, "")
                        return boards  # , status

                    v_last_board.children.append(
                        self.parse_movetext(v_string[:-1], last_board.prev, position, variation=True))
                    v_string = ""
                    continue

            elif group == VARIATION_START:
                parenthesis += 1
                if parenthesis == 1:
                    v_last_board = last_board

            if parenthesis == 0:
                if group == FULL_MOVE:
                    if not variation:
                        if position != -1 and last_board.plyCount >= position:
                            break

                    mstr = m.group(MOVE)
                    try:
                        lmove = parseSAN(last_board, mstr)
                    except ParsingError as err:
                        # TODO: save the rest as comment
                        # last_board.children.append(string[m.start():])
                        notation, reason, boardfen = err.args
                        ply = last_board.plyCount
                        if ply % 2 == 0:
                            moveno = "%d." % (ply // 2 + 1)
                        else:
                            moveno = "%d..." % (ply // 2 + 1)
                        errstr1 = _(
                            "The game can't be read to end, because of an error parsing move %(moveno)s '%(notation)s'.") % {
                                'moveno': moveno,
                                'notation': notation}
                        errstr2 = _("The move failed because %s.") % reason
                        self.error = LoadingError(errstr1, errstr2)
                        break
                    except Exception:
                        ply = last_board.plyCount
                        if ply % 2 == 0:
                            moveno = "%d." % (ply // 2 + 1)
                        else:
                            moveno = "%d..." % (ply // 2 + 1)
                        errstr1 = _(
                            "Error parsing move %(moveno)s %(mstr)s") % {
                                "moveno": moveno,
                                "mstr": mstr}
                        self.error = LoadingError(errstr1, "")
                        break

                    new_board = last_board.clone()
                    new_board.applyMove(lmove)

                    if m.group(MOVE_COMMENT):
                        new_board.nags.append(symbol2nag(m.group(
                            MOVE_COMMENT)))

                    new_board.prev = last_board

                    # set last_board next, except starting a new variation
                    if variation and last_board == board:
                        boards[0].next = new_board
                    else:
                        last_board.next = new_board

                    boards_append(new_board)
                    last_board = new_board

                elif group == COMMENT_REST:
                    last_board.children.append(text[1:])

                elif group == COMMENT_BRACE:
                    comm = text.replace('{\r\n', '{').replace('\r\n}', '}')
                    comm = comm[1:-1].splitlines()
                    comment = ' '.join([line.strip() for line in comm])
                    if variation and last_board == board:
                        # initial variation comment
                        boards[0].children.append(comment)
                    else:
                        last_board.children.append(comment)

                elif group == COMMENT_NAG:
                    last_board.nags.append(text)

                # TODO
                elif group == RESULT:
                    # if text == "1/2":
                    #    status = reprResult.index("1/2-1/2")
                    # else:
                    #    status = reprResult.index(text)
                    break

                else:
                    print("Unknown:", text)

        return boards  # , status
Example #21
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()
    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()