3

Let's imagine I have a pgn file with each game starting from a tactical position, and I want to identify the games where the solution was the only one. Basically an engine would have to evaluate several possible moves, and the evaluation margin between the first best move and the second best move would have to be above a certain threshold (e.g. >3.00 pawns). I do not want to load up manually every game and look at the engine evaluation - that's the step I am hoping to eliminate.

I am interested to hear of any GUI based solutions, or even script based (e.g. modifications to this - http://sourceforge.net/p/scid/mailman/message/29220017/ - I like this script, but can't get it up and running easily because SCID TCL interpreter on Windows seems to come without Expect package ...)

  • Try contacting the guy who wrote the tactical server chesstempo.com through the chesstempo discussion forum. All the tactical puzzles there have been extracted from game databases through an algorithm that recognizes positions that have a tactical blow. It is possible that this solves the problem posed here. The guy is available for discussion or even the forum members may know the technical details. – DrCapablasker Oct 27 '14 at 6:28
  • 1
    If you are doing this in order to find tactics exercises, please also note that a position where the best move is +20 and the second best move is +5 is not a very good one. – JiK Oct 28 '14 at 8:16
  • Yes, finding tactical exercises is my goal. Good point though, so if I could put into a script - I would also cap it so that second best move is no higher than 2.00 (i.e. also clearly winning). – Joe Oct 29 '14 at 14:55
2

It is not too difficult to do this with a python script: You basically start the engine as a subprocess and communicate via "uci". I'll post some not very pretty code snippets and try to explain what you have to do:

engine=subprocess.Popen('./stockfish-5-        64',universal_newlines=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,)

def put(command):
    print command
    engine.stdin.write(command+'\n')

    if command!='quit':
        engine.stdin.write('isready\n')
        while(True):
            text=engine.stdout.readline().strip()   
            print
            print text
            print
            if text == 'readyok':
                return

def get():
    engine.stdin.write('isready\n')
    while(True):
        text=engine.stdout.readline().strip()
        print text
        if text == 'readyok':
            break
        if text !='':
            print text

def getResult(depth):
    Result=[]
    while(True):
        text=engine.stdout.readline().strip()   
        liste=text.split()  
        if text[:22]=="info depth "+str(depth)+" seldepth" and liste[15]=='1':
            Result=[]
        if text[:22]=="info depth "+str(depth)+" seldepth":
            Result.append(text)


        if text[:8] == 'bestmove':
            break

    Scores=[]
    for line in Result:
        liste=line.split()
        Scores.append(liste[7])     

    return Scores

def Game_Analysis(game):
    scorestring=''
    moves=''
    for x in range(len(game)-1):
        moves+=game[x]+' '
        command='position startpos moves '+moves
        put(command)    
        get()
        put('go depth 15')
        Scores=getResult(15)
        for score in Scores:
            scorestring+=score+' '
        scorestring+='\n'
    return scorestring


get()
put('uci')
get()
put('setoption name MultiPV value 20')      
get()

print Game_Analysis(game)

put('stop')
put('quit')

So, get() and put() are for communicating with the engine.

put('uci') starts the dialog.

put('setoption name MultiPV value 20') tells the engine to return the best twenty moves. (In your case you really only need 2)

command='position startpos moves '+moves
put(command) This sets up the position, unfortunately the moves aren't pgn but in uci-format. So you'll probably have to transcribe or use FEN.

In GetResult() I extract the 20 best scores of the position. Then you only need to look for a big difference between move one and move two.

Game_Analysis(game) extracts the 20 best scores for every position in a game, here given as a list of uci-formated moves.

To deal with the uci-format and really understand these commands you should have a look at the uci=Universal Chess Interface.

  • this is fantastic, I will give it a go when I have a chance. to confirm - game (in print Game_Analysis(game)) is a string which is a game representation in UCI format? My input is in pgn, but I might be able to plug-in pgn-extract to get UCI out of it ... chess.stackexchange.com/questions/2895/… – Joe Dec 16 '14 at 16:37
  • No, "game" is actually a list of moves. The moves are strings in the uci-format. So "moves+=game[x]+' '" adds another move to the string of moves that are executed from the starting position, to reach the position that is evaluated. – BlindKungFuMaster Dec 16 '14 at 18:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.