Opening books format

Discussion of chess software programming and technical issues.

Moderator: Ras

mhalstern
Posts: 484
Joined: Wed Nov 18, 2009 1:09 am

Re: Opening books format

Post by mhalstern »

Thanks for all of the code and links.

Has anybody written a program to convert to and from the chessbase *.ctg format?

If so, pls post and or link.
Stephan Vermeire (Brutus)
Posts: 34
Joined: Sun Oct 12, 2008 6:32 pm

Re: Opening books format

Post by Stephan Vermeire (Brutus) »

Hi Marc,

CTG-files have a completely different structure than .pgn files. With CTG, each unique position is stored regardless of how we came there. In pgn a specific sequence of moves is stored. That makes it harder to convert thse formats than other formats.

As far as I know, there is no program available to convert ctg. Check this also:
http://www.open-aurec.com/wbforum/viewt ... tg#p190852

Best wishes,
Stephan
User avatar
jshriver
Posts: 1358
Joined: Wed Mar 08, 2006 9:41 pm
Location: Morgantown, WV, USA

Re: Opening books format

Post by jshriver »

I'd be willing to write one pending abk isn't patented or will get me sued :)
Will have to research it later to see what the format looks like.

Any other formats people want dumped to PGN?

-Josh
Michel
Posts: 2292
Joined: Mon Sep 29, 2008 1:50 am

Re: Opening books format

Post by Michel »

Any other formats people want dumped to PGN?
Dumping to PGN is not the only issue. One also needs to know how Arena assigns probabilities to moves. I asked a while ago here if it was known how Arena does this but there was no reply. So I guess it is not known.
Stephan Vermeire (Brutus)
Posts: 34
Joined: Sun Oct 12, 2008 6:32 pm

Re: Opening books format

Post by Stephan Vermeire (Brutus) »

jshriver wrote:I'd be willing to write one pending abk isn't patented or will get me sued :)
Will have to research it later to see what the format looks like.

-Josh
Hi Joshua,

In case you want to write a ctg->pgn adapter, I can give you some code that is capable of probing ctg-databases. It won't be too hard to alter that into a converter.

I have written an object with the following functions:

Code: Select all

class book{
public:
	book();
	void setBookPath(char* newBookPath);
	int probeBook(char* pFEN, char* pMove);
	void setRandomness(int rnd); //With this you can set: best move only or one of the best moves
                .....
};
When you enter a FEN ("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"), the move is returned in SAN-format (like e2e4). With this code you can probe specific positions and retrieve all moves and statistics that have been stored in the database. This link is very useful also: http://rybkaforum.net/cgi-bin/rybkaforu ... ?pid=26942

Let me know if you are interested in this code. I haven't published it due too legal reasons (don't want to be sued either :wink:)

Stephan
yoshiharu
Posts: 56
Joined: Sat Nov 11, 2006 11:14 pm

Re: Opening books format

Post by yoshiharu »

Hi everybody,

I made a few corrections to the source, because of two small bugs.
Now it goes like the following:

Code: Select all

// Author Juri Osipov - mods by Dann Corbit, Lance Perkins - couple of bugs fixed by Mauro Riccardi
#include <windows.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <io.h> 

static const char prm[] = "RNBQRNBQ"; 

struct BOOK { 
    unsigned char   move_from; 
    unsigned char   move_to; 
    unsigned char   move_promo; 
    unsigned char   priority; 
    unsigned int    games; 
    unsigned int    won_games; 
    unsigned int    lost_games; 
    unsigned int    hz; 
    int             first_child; 
    int             next_sibling; 
}   *book; 

FILE           *ft; 
int             linelength = 0; 

void            print_head() 
{ 
    fprintf(ft, "[Event \"?\"]\n"); 
    fprintf(ft, "[Site \"?\"]\n"); 
    fprintf(ft, "[Date \"????.??.??\"]\n"); 
    fprintf(ft, "[Round \"?\"]\n"); 
    fprintf(ft, "[Result \"*\"]\n"); 
    fprintf(ft, "[White \"?\"]\n"); 
    fprintf(ft, "[Black \"?\"]\n\n"); 
} 


void print_move(unsigned char move_from, unsigned char move_to,char move_promo, int ply) 
{ 
    if ((move_from >> 3) + 1 == 32 && (move_to >> 3) + 1 == 32) return; 
    if (linelength > 80) { 
        fprintf(ft, "\n"); 
        linelength = 0; 
    } 
    if ((ply & 1) == 0) { 
        fprintf(ft, "%d.", ply / 2 + 1); 
        linelength += 3; 
    } 
    fprintf(ft, "%c%d%c%d", 
            (move_from & 7) + 'a', (move_from >> 3) + 1, 
            (move_to & 7) + 'a', (move_to >> 3) + 1); 

    if (move_promo) {  // from Lance Perkins        
        fprintf(ft,"%c", prm[abs(move_promo)-1]); 
    } 
    fprintf(ft, " "); 
    linelength += 5; 
} 

int main(int argc, char *argv[]) 
{ 
    int             i, 
                    ply; 
    size_t          filesize; 
    int             node[1000]; 
    struct MOVE { 
        unsigned char   move_from; 
        unsigned char   move_to; 
        unsigned char   move_promo; 
    }   moves[1000]; 

    if (argc < 2) { 
        printf("Simple command-line converter from ABK to PGN\n"); 
        printf("Usage: abk.exe <abk_file>\n"); 
        printf("Result PGN-file: out.pgn\n"); 
        exit(0); 
    } 
    ft = fopen(argv[1], "rb"); 
    if (ft == NULL) { 
        printf("Can't open file %s\n", argv[1]); 
        exit(0); 
    } 
    filesize = filelength(fileno(ft)); 
    book = malloc(filesize); 
    fread(book, filesize / sizeof(struct BOOK), sizeof(struct BOOK), ft); 
    fclose(ft); 
    ft = fopen("out.pgn", "w"); 
    print_head(); 
    ply = 0; 
    node[0] = 900;  // offset to first node in abk-file 

    for (;;) { 
        print_move(book[node[ply]].move_from, book[node[ply]].move_to, 
                   book[node[ply]].move_promo, ply); 
        if (book[node[ply]].first_child > 0) {  // current game 

            moves[ply].move_from = book[node[ply]].move_from; 
            moves[ply].move_to = book[node[ply]].move_to; 
            moves[ply].move_promo = book[node[ply]].move_promo; 
            node[ply + 1] = book[node[ply]].first_child; 
            ply++; 
        } else { // new game 
            fprintf(ft, "\n*\n\n"); 
            node[ply] = book[node[ply]].next_sibling; 
            while (node[ply] < 0) { 
                ply--; 
                if (ply < 0) { 
                    fclose(ft);                     
                    exit(0); 
                } 
                node[ply] = book[node[ply]].next_sibling; 
            } 
            print_head(); 
            linelength = 0; 
            for (i = 0; i < ply; i++) { 
                print_move(moves[i].move_from, moves[i].move_to, moves[i].move_promo, i); 
            } 
        } 
        if (node[ply] >= filesize / (int) sizeof(struct BOOK)) { 
            printf("Error: out of file\n"); 
            fclose(ft); 
            exit(0); 
        } 
    } 
    return 0; 
} 

Cheers, Mauro
User avatar
jshriver
Posts: 1358
Joined: Wed Mar 08, 2006 9:41 pm
Location: Morgantown, WV, USA

Re: Opening books format

Post by jshriver »

I made some small mods too to get this to work under linux (any unix really).

I've never used #ifdef for win vs unix systems but here are the additions and changes.

Add:
#include <stdlib.h>
#include <sys/stat.h>
Remove windows.h and io.h

struct stat filecheck;

then removed the filesize line and replace with this:

stat(argv[1], &filecheck);
filesize = filecheck.st_size;

-Josh
Dann Corbit
Posts: 12790
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: Opening books format

Post by Dann Corbit »

Maybe:

Code: Select all

// Author Juri Osipov - mods by Dann Corbit, Lance Perkins - couple of bugs fixed by Mauro Riccardi
#ifdef _MSC_VER
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#include <sys/stat.h>
static struct stat filecheck;
#endif
#include <stdio.h>
#include <stdlib.h>

static const char prm[] = "RNBQRNBQ";

struct BOOK {
    unsigned char   move_from;
    unsigned char   move_to;
    unsigned char   move_promo;
    unsigned char   priority;
    unsigned int    games;
    unsigned int    won_games;
    unsigned int    lost_games;
    unsigned int    hz;
    int             first_child;
    int             next_sibling;
}   *book;

FILE           *ft;
int             linelength = 0;

void            print_head()
{
    fprintf(ft, "[Event \"?\"]\n");
    fprintf(ft, "[Site \"?\"]\n");
    fprintf(ft, "[Date \"????.??.??\"]\n");
    fprintf(ft, "[Round \"?\"]\n");
    fprintf(ft, "[Result \"*\"]\n");
    fprintf(ft, "[White \"?\"]\n");
    fprintf(ft, "[Black \"?\"]\n\n");
}


void print_move(unsigned char move_from, unsigned char move_to,char move_promo, int ply)
{
    if ((move_from >> 3) + 1 == 32 && (move_to >> 3) + 1 == 32) return;
    if (linelength > 80) {
        fprintf(ft, "\n");
        linelength = 0;
    }
    if ((ply & 1) == 0) {
        fprintf(ft, "%d.", ply / 2 + 1);
        linelength += 3;
    }
    fprintf(ft, "%c%d%c%d",
            (move_from & 7) + 'a', (move_from >> 3) + 1,
            (move_to & 7) + 'a', (move_to >> 3) + 1);

    if (move_promo) {  // from Lance Perkins
        fprintf(ft,"%c", prm[abs(move_promo)-1]);
    }
    fprintf(ft, " ");
    linelength += 5;
}

int main(int argc, char *argv[])
{
    int             i, ply;
    size_t          filesize;
    int             node[1000];
    struct MOVE {
        unsigned char   move_from;
        unsigned char   move_to;
        unsigned char   move_promo;
    }   moves[1000];

    if (argc < 2) {
        printf("Simple command-line converter from ABK to PGN\n");
        printf("Usage: abk.exe <abk_file>\n");
        printf("Result PGN-file: out.pgn\n");
        exit(0);
    }
    ft = fopen(argv[1], "rb");
    if (ft == NULL) {
        printf("Can't open file %s\n", argv[1]);
        exit(0);
    }
#ifdef _MSC_VER
    filesize = filelength(fileno(ft));
#else
    stat(argv[1], &filecheck);
    filesize = filecheck.st_size;
#endif

    book = malloc(filesize);
    fread(book, filesize / sizeof(struct BOOK), sizeof(struct BOOK), ft);
    fclose(ft);
    ft = fopen("out.pgn", "w");
    print_head();
    ply = 0;
    node[0] = 900;  // offset to first node in abk-file

    for (;;) {
        print_move(book[node[ply]].move_from, book[node[ply]].move_to,
                   book[node[ply]].move_promo, ply);
        if (book[node[ply]].first_child > 0) {  // current game

            moves[ply].move_from = book[node[ply]].move_from;
            moves[ply].move_to = book[node[ply]].move_to;
            moves[ply].move_promo = book[node[ply]].move_promo;
            node[ply + 1] = book[node[ply]].first_child;
            ply++;
        } else { // new game
            fprintf(ft, "\n*\n\n");
            node[ply] = book[node[ply]].next_sibling;
            while (node[ply] < 0) {
                ply--;
                if (ply < 0) {
                    fclose(ft);
                    exit(0);
                }
                node[ply] = book[node[ply]].next_sibling;
            }
            print_head();
            linelength = 0;
            for (i = 0; i < ply; i++) {
                print_move(moves[i].move_from, moves[i].move_to, moves[i].move_promo, i);
            }
        }
        if (node[ply] >= filesize / (int) sizeof(struct BOOK)) {
            printf("Error: out of file\n");
            fclose(ft);
            exit(0);
        }
    }
    return 0;
}

/*
/home/cnxuser> gcc abk2pgn.c
/home/cnxuser> ./a.out
Simple command-line converter from ABK to PGN
Usage: abk.exe <abk_file>
Result PGN-file: out.pgn

c:\tmp>cl /W1 /Ox abk2pgn.c
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

abk2pgn.c
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:abk2pgn.exe
abk2pgn.obj

c:\tmp>abk2pgn
Simple command-line converter from ABK to PGN
Usage: abk.exe <abk_file>
Result PGN-file: out.pgn

*/
User avatar
Graham Banks
Posts: 44522
Joined: Sun Feb 26, 2006 10:52 am
Location: Auckland, NZ

Re: Opening books format

Post by Graham Banks »

mhalstern wrote:Thanks for all of the code and links.

Has anybody written a program to convert to and from the chessbase *.ctg format?

If so, pls post and or link.
My friend, Nigel Pattinson, wrote a utility that will convert the Chessmaster books into ctg format. Would that be useful to you?
http://homepages.paradise.net.nz/npatti ... kPage.html

Cheers,
Graham.
gbanksnz at gmail.com
alpha123
Posts: 660
Joined: Sat Dec 05, 2009 5:13 am
Location: Colorado, USA

Re: Opening books format

Post by alpha123 »

Graham Banks wrote:
mhalstern wrote:Thanks for all of the code and links.

Has anybody written a program to convert to and from the chessbase *.ctg format?

If so, pls post and or link.
My friend, Nigel Pattinson, wrote a utility that will convert the Chessmaster books into ctg format. Would that be useful to you?
http://homepages.paradise.net.nz/npatti ... kPage.html

Cheers,
Graham.
Well, that might be useful to me.... Thanks!
I assume he reverse engineered the .ctg format to do that, so could he write a .ctg to .pgn or .ctg to .abk converter?

Thanks,
Peter