示例#1
0
文件: test.py 项目: Hjax/sunfish
def findbest(f, times):
    print('Calibrating search speed...')
    pos = xboard.parseFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    CAL_NODES = 10000
    start = time.time()
    _ = sunfish.search(pos, CAL_NODES)
    factor = CAL_NODES/(time.time()-start)

    print('Running benchmark with %.1f nodes per second...' % factor)
    print('-'*60)
    totalpoints = 0
    totaltests = 0
    for k, line in enumerate(f):
        fen, opts = parseEPD(line)
        pos = xboard.parseFEN(fen)
        color = 0 if fen.split()[1] == 'w' else 1
        # am -> avoid move; bm -> best move
        am = parseSAN(pos,color,opts['am']) if 'am' in opts else None
        bm = parseSAN(pos,color,opts['bm']) if 'bm' in opts else None
        points = 0
        print(opts['id'], end=' ', flush=True)
        for t in times:
            move, _ = sunfish.search(pos, factor*t)
            mark = renderSAN(pos, move)
            if am and move != am or bm and move == bm:
                mark += '(1)'
                points += 1
                totalpoints += 1
            else:
                mark += '(0)'
            print(mark, end=' ', flush=True)
            totaltests + 1
        print(points)
    print('-'*60)
    print('Total Points: %d/%d', totalpoints, totaltests)
示例#2
0
文件: test.py 项目: Hjax/sunfish
def play(version1_version2_maxn_rand):
    ''' returns 1 if fish1 won, 0 for draw and -1 otherwise '''
    version1, version2, maxn, rand = version1_version2_maxn_rand
    fish1 = importlib.import_module(version1)
    fish2 = importlib.import_module(version2)
    pos = xboard.parseFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    old = None
    tdelta = 0
    for d in range(200):
        nodes = maxn
        nodes *= (1+abs(tdelta)/5) if (tdelta<0)==(d%2==0) else 1
        nodes *= .75+random.random()/2
        before = time.time()
        m, score = (fish1 if d%2==0 else fish2).search(pos, nodes)
        tdelta += (time.time()-before)*(1 if d%2==0 else -1)
        if m is not None:
            pos = pos.move(m)
            # Test repetition draws
            if d%4==0:
                if pos.board == old:
                    return 0
                old = pos.board
        else:
            assert score < -1000
            return 1 if d%2 == 1 else -1
    else:
        print('200 moves reached')
        return 0
示例#3
0
def play(version1_version2_secs_fen):
    ''' returns 1 if fish1 won, 0 for draw and -1 otherwise '''
    version1, version2, secs, fen = version1_version2_secs_fen
    fish = [importlib.import_module(version1),
            importlib.import_module(version2)]
    nodes = [5000, 5000]
    times = [0, 0]
    pos = xboard.parseFEN(fen)
    old = None
    for d in range(200):
        t = time.time()
        maxn = nodes[d%2] * (times[(d+1)%2]+secs) / (times[d%2]+secs)
        m, score = fish[d%2].search(pos, maxn)
        times[d%2] += time.time() - t
        nodes[d%2] *= (secs/(time.time()-t))**.3
        if m is not None:
            pos = pos.move(m)
            # Test repetition draws
            if d%4==0:
                if pos.board == old:
                    return None
                old = pos.board
        else:
            if score > 30000:
                assert False
                # This means we move and kill the opponent king.
                # But then the opponent made an illegal move last time???
                return version1 if d%2 == 0 else version2
            if score > -1000:
                print("How did we get here, if we didn't lose?")
                print(pos, m, score)
                return None
            return version1 if d%2 == 1 else version2
    return None
示例#4
0
def play(version1_version2_maxn_rand):
    ''' returns 1 if fish1 won, 0 for draw and -1 otherwise '''
    version1, version2, maxn, rand = version1_version2_maxn_rand
    fish1 = importlib.import_module(version1)
    fish2 = importlib.import_module(version2)
    pos = xboard.parseFEN(
        'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    old = None
    tdelta = 0
    for d in range(200):
        nodes = maxn
        nodes *= (1 + abs(tdelta) / 5) if (tdelta < 0) == (d % 2 == 0) else 1
        nodes *= .75 + random.random() / 2
        before = time.time()
        m, score = (fish1 if d % 2 == 0 else fish2).search(pos, nodes)
        tdelta += (time.time() - before) * (1 if d % 2 == 0 else -1)
        if m is not None:
            pos = pos.move(m)
            # Test repetition draws
            if d % 4 == 0:
                if pos.board == old:
                    return 0
                old = pos.board
        else:
            assert score < -1000
            return 1 if d % 2 == 1 else -1
    else:
        print('200 moves reached')
        return 0
示例#5
0
def allmate(path):
    with open(path) as f:
        for line in f:
            line = line.strip()
            print(line)

            pos = xboard.parseFEN(line)
            _, score = sunfish.search(pos, maxn=1e9)
            if score < sunfish.MATE_VALUE:
                print("Unable to find mate. Only got score = %d" % score)
                break
示例#6
0
def allmate(path):
    with open(path) as f:
        for line in f:
            line = line.strip()
            print(line)

            pos = xboard.parseFEN(line)
            _, score = sunfish.search(pos, maxn=1e9)
            if score < sunfish.MATE_VALUE:
                print("Unable to find mate. Only got score = %d" % score)
                break
示例#7
0
def findbest(f, times):
    print('Calibrating search speed...')
    pos = xboard.parseFEN(xboard.FEN_INITIAL)
    CAL_NODES = 100000
    start = time.time()
    _ = sunfish.search(pos, CAL_NODES)
    factor = sunfish.nodes/(time.time()-start)

    print('Running benchmark with %.1f nodes per second...' % factor)
    print('Printing best move after seconds', times)
    print('-'*60)
    totalpoints = 0
    totaltests = 0
    for line in f:
        fen, opts = parseEPD(line, opt_dict=True)
        if type(opts) != dict or ('am' not in opts and 'bm' not in opts):
            print("Line didn't have am/bm in opts", line, opts)
            continue
        pos = xboard.parseFEN(fen)
        color = xboard.WHITE if fen.split()[1] == 'w' else xboard.BLACK
        # am -> avoid move; bm -> best move
        am = parseSAN(pos,color,opts['am']) if 'am' in opts else None
        bm = parseSAN(pos,color,opts['bm']) if 'bm' in opts else None
        print('Looking for am/bm', opts.get('am'), opts.get('bm'))
        points = 0
        print(opts.get('id','unnamed'), end=' ', flush=True)
        for t in times:
            move, _ = sunfish.search(pos, factor*t)
            mark = renderSAN(pos,color,move)
            if am and move != am or bm and move == bm:
                mark += '(1)'
                points += 1
            else:
                mark += '(0)'
            print(mark, end=' ', flush=True)
            totaltests += 1
        print(points)
        totalpoints += points
    print('-'*60)
    print('Total Points: %d/%d', totalpoints, totaltests)
示例#8
0
def selfplay(maxn=200):
    """ Start a game sunfish vs. sunfish """
    pos = xboard.parseFEN(xboard.FEN_INITIAL)
    for d in range(200):
        # Always print the board from the same direction
        board = pos.board if d % 2 == 0 else pos.rotate().board
        print(' '.join(board))
        m, _ = sunfish.search(pos, maxn)
        if m is None:
            print("Game over")
            break
        print("\nmove", xboard.mrender(d%2, pos, m))
        pos = pos.move(m)
示例#9
0
 def test_san(self):
     pgn_file = os.path.join(os.path.dirname(__file__), 'tests/pgns.pgn')
     for line in open(pgn_file):
         msans = [msan for i, msan in enumerate(line.split()[:-1]) if i%3!=0]
         pos = xboard.parseFEN(xboard.FEN_INITIAL)
         for i, msan in enumerate(msans):
             move = parseSAN(pos, i%2, msan)
             if re.search('=[BNR]', msan):
                 # Sunfish doesn't support underpromotion
                 break
             msan_back = renderSAN(pos, i%2, move)
             self.assertEqual(msan_back, msan,
                     "Sunfish didn't correctly reproduce the SAN move")
             pos = pos.move(move)
示例#10
0
def selfplay():
    """ Start a game sunfish vs. sunfish """
    pos = xboard.parseFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    for d in range(200):
        # Always print the board from the same direction
        board = pos.board if d % 2 == 0 else pos.rotate().board
        print(' '.join(board))

        m, _ = sunfish.search(pos, maxn=200)
        if m is None:
            print("Game over")
            break
        print("\nmove", xboard.mrender(d%2, pos, m))
        pos = pos.move(m)
示例#11
0
def findbest(path, times):
    print('Calibrating search speed...')
    pos = xboard.parseFEN(
        'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    CAL_NODES = 10000
    start = time.time()
    _ = sunfish.search(pos, CAL_NODES)
    factor = CAL_NODES / (time.time() - start)

    print('Running benchmark with %.1f nodes per second...' % factor)
    print('-' * 60)
    totalpoints = 0
    totaltests = 0
    with open(path) as f:
        for k, line in enumerate(f):
            fen, opts = parseEPD(line)
            pos = xboard.parseFEN(fen)
            color = 0 if fen.split()[1] == 'w' else 1
            # am -> avoid move; bm -> best move
            am = parseSAN(pos, color, opts['am']) if 'am' in opts else None
            bm = parseSAN(pos, color, opts['bm']) if 'bm' in opts else None
            points = 0
            print(opts['id'], end=' ', flush=True)
            for t in times:
                move, _ = sunfish.search(pos, factor * t)
                mark = renderSAN(pos, move)
                if am and move != am or bm and move == bm:
                    mark += '(1)'
                    points += 1
                    totalpoints += 1
                else:
                    mark += '(0)'
                print(mark, end=' ', flush=True)
                totaltests + 1
            print(points)
    print('-' * 60)
    print('Total Points: %d/%d', totalpoints, totaltests)
示例#12
0
def selfplay(maxn=200):
    """ Start a game sunfish vs. sunfish """
    pos = xboard.parseFEN(
        'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    for d in range(200):
        # Always print the board from the same direction
        board = pos.board if d % 2 == 0 else pos.rotate().board
        print(' '.join(board))

        m, _ = sunfish.search(pos, maxn)
        if m is None:
            print("Game over")
            break
        print("\nmove", xboard.mrender(d % 2, pos, m))
        pos = pos.move(m)
示例#13
0
def quickdraw(f, depth):
    for line in f:
        line = line.strip()
        print(line)

        pos = xboard.parseFEN(line)
        for d in range(depth, 99):
            s0 = sunfish.bound(pos, 0, d)
            s1 = sunfish.bound(pos, 1, d)
            if s0 >= 0 and s1 < 1:
                break
            print(d, s0, s1, xboard.pv(0, pos))
        else:
            print("Fail: Unable to find draw!")
            return
示例#14
0
def quickdraw(f, depth):
    for line in f:
        line = line.strip()
        print(line)

        pos = xboard.parseFEN(line)
        for d in range(depth, 99):
            s0 = sunfish.bound(pos, 0, d)
            s1 = sunfish.bound(pos, 1, d)
            if s0 >= 0 and s1 < 1:
                break
            print(d, s0, s1, xboard.pv(0, pos))
        else:
            print("Fail: Unable to find draw!")
            return
示例#15
0
def allperft(f, depth=4):
    lines = f.readlines()
    for d in range(1, depth+1):
        print("Going to depth {}/{}".format(d, depth))
        for line in lines:
            parts = line.split(';')
            print(parts[0])

            pos, score = xboard.parseFEN(parts[0]), int(parts[d])
            res = sum(1 for _ in collect_tree_depth(expand_position(pos), d))
            if res != score:
                print('=========================================')
                print("ERROR at depth %d. Gave %d rather than %d" % (d, res, score))
                print('=========================================')
                return
        print('')
示例#16
0
def quickmate(path, depth):
    """ Similar to allmate, but uses the `bound` function directly to only
    search for moves that will win us the game """
    with open(path) as f:
        for line in f:
            line = line.strip()
            print(line)

            pos = xboard.parseFEN(line)
            for d in range(depth, 99):
                score = sunfish.bound(pos, sunfish.MATE_VALUE, d)
                if score >= sunfish.MATE_VALUE:
                    break
                print(d, score)
            else:
                print("Unable to find mate. Only got score = %d" % score)
                return
示例#17
0
def quickmate(path, depth):
    """ Similar to allmate, but uses the `bound` function directly to only
    search for moves that will win us the game """
    with open(path) as f:
        for line in f:
            line = line.strip()
            print(line)

            pos = xboard.parseFEN(line)
            for d in range(depth, 99):
                score = sunfish.bound(pos, sunfish.MATE_VALUE, d)
                if score >= sunfish.MATE_VALUE:
                    break
                print(d, score)
            else:
                print("Unable to find mate. Only got score = %d" % score)
                return
示例#18
0
def selfplay():
    """ Start a game sunfish vs. sunfish """
    wa, ba = (['C', 'N', 'E', 'R', 'T',
               'A'])[random.randint(0, 5)], (['c', 'n', 'e', 'r', 't',
                                              'a'])[random.randint(0, 5)]
    #pos = xboard.parseFEN('{}{} 33 rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.format(wa, ba))
    pos = xboard.parseFEN(
        'Ca 33 rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    print(' '.join(pos.board))
    print('#' * 10)
    for d in range(100):
        move, score = sunfish.search(pos, maxn=1e3)
        pos = pos.move(move)
        # Always print the board from the same direction
        board = pos.rotate().board if pos.color else pos.board
        #board = pos.board
        print(' '.join(board))
        print("{}. {}: {}".format(d + 1, (['w', 'b'])[not pos.color],
                                  xboard.mrender(pos, move)))
        print("\n" + str(xboard.printFEN(pos)))
        if pos.second:
            print("second initiated")
            move, score = sunfish.search(pos, maxn=1e2)
            if move:
                print("move found")
                board = pos.rotate().board if pos.color else pos.board
                print(' '.join(board))
                print("{}. {}: {}".format(d + 1, (['w', 'b'])[not pos.color],
                                          xboard.mrender(pos, move)))
                print("\n" + str(xboard.printFEN(pos)))
                pos = pos.move(move)
            else:
                score = 0
                pos = sunfish.Position(pos.board, pos.color, False, pos.score,
                                       pos.wa, pos.ba, pos.ws, pos.bs, pos.wc,
                                       pos.bc, pos.ep, pos.kp)
                pos = pos.rotate()
        if score <= -30000:
            print("Game over. White wins.")
            break
        if score >= 30000:
            print("Game over. Black wins.")
            break
        print('#' * 10)
示例#19
0
def quickmate(f, min_depth=1, draw=False):
    """ Similar to allmate, but uses the `bound` function directly to only
    search for moves that will win us the game """
    if draw:
        return quickdraw(f, min_depth)

    for line in f:
        line = line.strip()
        print(line)

        pos = xboard.parseFEN(line)
        for d in range(min_depth, 99):
            score = sunfish.bound(pos, sunfish.MATE_VALUE, d)
            if score >= sunfish.MATE_VALUE:
                break
            print('Score at depth {}: {}'.format(d, score))
        else:
            print("Unable to find mate. Only got score = %d" % score)
            return
示例#20
0
def quickmate(f, min_depth=1, draw=False):
    """ Similar to allmate, but uses the `bound` function directly to only
    search for moves that will win us the game """
    if draw:
        return quickdraw(f, min_depth)

    for line in f:
        line = line.strip()
        print(line)

        pos = xboard.parseFEN(line)
        for d in range(min_depth, 99):
            score = sunfish.bound(pos, sunfish.MATE_VALUE, d)
            if score >= sunfish.MATE_VALUE:
                break
            print('Score at depth {}: {}'.format(d, score))
        else:
            print("Unable to find mate. Only got score = %d" % score)
            return
示例#21
0
def allperft(path, depth=4):
    for d in range(1, depth+1):
        print("Going to depth %d" % d)
        with open(path) as f:
            for line in f:
                parts = line.split(';')
                print(parts[0])

                pos, score = xboard.parseFEN(parts[0]), int(parts[d])
                res = perft(pos, d)
                if res != score:
                    print('=========================================')
                    print("ERROR at depth %d. Gave %d rather than %d" % (d, res, score))
                    print('=========================================')
                    if d == 1:
                        print(pos)
                    perft(pos, d, divide=True)
                    return
        print('')
示例#22
0
def allperft(f, depth=4):
    lines = f.readlines()
    for d in range(1, depth + 1):
        print("Going to depth %d" % d)
        for line in lines:
            parts = line.split(';')
            print(parts[0])

            pos, score = xboard.parseFEN(parts[0]), int(parts[d])
            res = perft(pos, d)
            if res != score:
                print('=========================================')
                print("ERROR at depth %d. Gave %d rather than %d" %
                      (d, res, score))
                print('=========================================')
                if d == 1:
                    print(pos)
                perft(pos, d, divide=True)
                return
        print('')
示例#23
0
def selfplay():
    """ Start a game sunfish vs. sunfish """
    wa, ba = (['C', 'N', 'E', 'R', 'T', 'A'])[random.randint(0, 5)], (['c', 'n', 'e', 'r', 't', 'a'])[random.randint(0, 5)]
    #pos = xboard.parseFEN('{}{} 33 rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.format(wa, ba))
    pos = xboard.parseFEN('Ca 33 rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
    print(' '.join(pos.board))
    print('#' * 10)
    for d in range(100):
        move, score = sunfish.search(pos, maxn=1e3)
        pos = pos.move(move)
        # Always print the board from the same direction
        board = pos.rotate().board if pos.color else pos.board
        #board = pos.board
        print(' '.join(board))
        print("{}. {}: {}".format(d+1, (['w', 'b'])[not pos.color], xboard.mrender(pos, move)))
        print("\n" + str(xboard.printFEN(pos)))
        if pos.second:
            print("second initiated")
            move, score = sunfish.search(pos, maxn=1e2)
            if move:
                print("move found")
                board = pos.rotate().board if pos.color else pos.board
                print(' '.join(board))
                print("{}. {}: {}".format(d+1, (['w', 'b'])[not pos.color], xboard.mrender(pos, move)))
                print("\n" + str(xboard.printFEN(pos)))
                pos = pos.move(move)
            else:
                score = 0
                pos = sunfish.Position(
                        pos.board, pos.color, False, pos.score,
                        pos.wa, pos.ba, pos.ws, pos.bs,
                        pos.wc, pos.bc, pos.ep, pos.kp)
                pos = pos.rotate()
        if score <= -30000:
            print("Game over. White wins.")
            break
        if score >= 30000:
            print("Game over. Black wins.")
            break
        print('#' * 10)
示例#24
0
 def setUp(self):
     perft_file = os.path.join(os.path.dirname(__file__), 'tests/queen.fen')
     test_trees = [expand_position(xboard.parseFEN(parseEPD(line)[0])) for line in open(perft_file)]
     self.positions = list(itertools.chain(*[flatten_tree(tree, depth=2) for tree in test_trees]))