Opening books format

Discussion of chess software programming and technical issues.

Moderators: bob, hgm, Harvey Williamson

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
James Constance
Posts: 353
Joined: Wed Mar 08, 2006 7:36 pm
Location: UK

Opening books format

Post by James Constance » Mon Apr 14, 2008 10:41 am

I'd quite like to create a PPC applicaion that can read information from opening books, such as .abk files or .ctg files or any other.

Can anyone point me to an online resource that explains how the files are formatted?

Thanks

Osipov Jury
Posts: 186
Joined: Mon Jan 21, 2008 1:07 pm
Location: Russia

Re: Opening books format

Post by Osipov Jury » Mon Apr 14, 2008 11:01 am

I write my own simple converter from .abk to .pgn format. If you want, i can send you this program with source code.

User avatar
Bill Rogers
Posts: 3562
Joined: Thu Mar 09, 2006 2:54 am
Location: San Jose, California

Re: Opening books format

Post by Bill Rogers » Mon Apr 14, 2008 4:26 pm

Osipov
If you wouldn't mind could you send me a copy too?
Thanks
Bill

MirceaH
Posts: 47
Joined: Mon Mar 13, 2006 3:21 pm

Re: Opening books format

Post by MirceaH » Mon Apr 14, 2008 5:09 pm

Hi Iuri,

I think everyone is interested in such various conversions routines.

Regards,
Mircea

James Constance
Posts: 353
Joined: Wed Mar 08, 2006 7:36 pm
Location: UK

Re: Opening books format

Post by James Constance » Tue Apr 15, 2008 6:53 am

Many thanks, Jury. That would be very useful. I'll send you my email in a Personal Message.

Osipov Jury
Posts: 186
Joined: Mon Jan 21, 2008 1:07 pm
Location: Russia

Re: Opening books format

Post by Osipov Jury » Tue Apr 15, 2008 10:33 am

Code: Select all

#include "stdio.h"
#include "io.h"
#include "windows.h"

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,"[White \"Alpha\"]\n");
  fprintf(ft,"[Black \"Beta\"]\n\n");
}

void print_move(unsigned char move_from, unsigned char move_to,
  unsigned char move_promo, int ply)
{ 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) fprintf(ft,"Q");  // allways queen: this is incorrect
  fprintf(ft," ");
  linelength += 5;
}

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

  if &#40;argc < 2&#41; &#123;
    printf&#40;"Simple command-line converter from ABK to PGN\n");
    printf&#40;"Usage&#58; abk.exe <abk_file>\n");
    printf&#40;"Result PGN-file&#58; out.pgn\n");
    exit&#40;0&#41;;
  &#125;
  ft = fopen&#40;argv&#91;1&#93;, "rb");
  if &#40;ft == NULL&#41; &#123;
    printf&#40;"Cann't open file %s\n",argv&#91;1&#93;);
    exit&#40;0&#41;;
  &#125;
  filesize = filelength&#40;fileno&#40;ft&#41;);
  book = malloc&#40;filesize&#41;;
  fread&#40;book, filesize / sizeof&#40;struct BOOK&#41;, sizeof&#40;struct BOOK&#41;, ft&#41;;
  fclose&#40;ft&#41;;
  ft = fopen&#40;"out.pgn","w");
  print_head&#40;);
  ply = 0;
  node&#91;0&#93; = 900;   // offset to first node in abk-file
  while &#40;1&#41; &#123;
    print_move&#40;book&#91;node&#91;ply&#93;&#93;.move_from, book&#91;node&#91;ply&#93;&#93;.move_to,
      book&#91;node&#91;ply&#93;&#93;.move_promo, ply&#41;;
    if &#40;book&#91;node&#91;ply&#93;&#93;.first_child > 0&#41; &#123;   // current game
      moves&#91;ply&#93;.move_from = book&#91;node&#91;ply&#93;&#93;.move_from;
      moves&#91;ply&#93;.move_to   = book&#91;node&#91;ply&#93;&#93;.move_to;
      moves&#91;ply&#93;.move_promo = book&#91;node&#91;ply&#93;&#93;.move_promo;
      node&#91;ply + 1&#93; = book&#91;node&#91;ply&#93;&#93;.first_child;
      ply++;
    &#125;
    else &#123;   // new game
      fprintf&#40;ft,"\n\n");
      node&#91;ply&#93; = book&#91;node&#91;ply&#93;&#93;.next_sibling;
      while &#40;node&#91;ply&#93; < 0&#41; &#123;
        ply--;
        if &#40;ply < 0&#41; &#123; fclose&#40;ft&#41;; exit&#40;0&#41;; &#125;
        node&#91;ply&#93; = book&#91;node&#91;ply&#93;&#93;.next_sibling;
      &#125;
      print_head&#40;);
      linelength = 0;
      for &#40;i = 0; i < ply; i++) &#123;
        print_move&#40;moves&#91;i&#93;.move_from, moves&#91;i&#93;.move_to, moves&#91;i&#93;.move_promo, i&#41;;
      &#125;
    &#125;
    if &#40;node&#91;ply&#93; >= filesize / &#40;int&#41;sizeof&#40;struct BOOK&#41;) &#123;
      printf&#40;"Error&#58; out of file\n");
      fclose&#40;ft&#41;;
      exit&#40;0&#41;;
    &#125;
  &#125;
&#125;

pijl

Re: Opening books format

Post by pijl » Tue Apr 15, 2008 3:03 pm

Osipov Jury wrote:

Code: Select all

  if &#40;move_promo&#41; fprintf&#40;ft,"Q");  // allways queen&#58; this is incorrect
I just made my own converter, which is rather simple to do. Instead of reading in the whole book, I fseek-ed through the file, following the move pointers. Windows will cache the file in memory anyway.

I did investigate the values for promotion as well:
Values for move_promo are signed and can have 9 values:
0: no promotion
-1, 1: rook promotion
-2, 2: knight promotion
-3, 3: bishop promotion
-4, 4: queen promotion
Richard.
Last edited by pijl on Tue Apr 15, 2008 3:06 pm, edited 1 time in total.

User avatar
beachknight
Posts: 3533
Joined: Tue Jan 09, 2007 7:33 pm
Location: Antalya, Turkey
Contact:

Re: Opening books format

Post by beachknight » Tue Apr 15, 2008 3:05 pm

Excellent, Yuri.

I wanted to merge all my arena opening books.
and there were no such code or utility.

Thank you!

Next step would be to create an online
converter that processes abk book to pgn.

With such a tool, I can obtain all pgns back;
process them further if necessary and create
my huge Arena book.

Any takers?

Best,
hi, merhaba, hallo HT

Ron Murawski
Posts: 397
Joined: Sun Oct 29, 2006 3:38 am
Location: Schenectady, NY
Contact:

Re: Opening books format

Post by Ron Murawski » Tue Apr 15, 2008 5:12 pm

There are several utility programs available at pitt.edu at this directory:
ftp://ftp.pitt.edu/group/student-activities/chess/CONV/

This index file has capsule descriptions of the contents:
ftp://ftp.pitt.edu/group/student-activi ... 0index.cnv

Ron

Dann Corbit
Posts: 10205
Joined: Wed Mar 08, 2006 7:57 pm
Location: Redmond, WA USA
Contact:

Re: Opening books format

Post by Dann Corbit » Wed Apr 16, 2008 12:37 am

I made a few small changes for my own purposes (mostly for post processing, since the PGN standard demands the 7 mandatory tags):

Code: Select all

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>

struct BOOK &#123;
    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;
&#125;   *book;

FILE           *ft;
int             linelength = 0;

void            print_head&#40;)
&#123;
    fprintf&#40;ft, "*\n\n");
    fprintf&#40;ft, "&#91;Event \"?\"&#93;\n");
    fprintf&#40;ft, "&#91;Site \"?\"&#93;\n");
    fprintf&#40;ft, "&#91;Date \"????.??.??\"&#93;\n");
    fprintf&#40;ft, "&#91;Round \"?\"&#93;\n");
    fprintf&#40;ft, "&#91;Result \"*\"&#93;\n");
    fprintf&#40;ft, "&#91;White \"?\"&#93;\n");
    fprintf&#40;ft, "&#91;Black \"?\"&#93;\n\n");
&#125;

void print_move&#40;unsigned char move_from, unsigned char move_to, unsigned char move_promo, int ply&#41;
&#123;
    if (&#40;move_from >> 3&#41; + 1 == 32 && &#40;move_to >> 3&#41; + 1 == 32&#41; return;
    if &#40;linelength > 80&#41; &#123;
        fprintf&#40;ft, "\n");
        linelength = 0;
    &#125;
    if (&#40;ply & 1&#41; == 0&#41; &#123;
        fprintf&#40;ft, "%d.", ply / 2 + 1&#41;;
        linelength += 3;
    &#125;
    fprintf&#40;ft, "%c%d%c%d",
            &#40;move_from & 7&#41; + 'a', &#40;move_from >> 3&#41; + 1,
            &#40;move_to & 7&#41; + 'a', &#40;move_to >> 3&#41; + 1&#41;;
    if &#40;move_promo&#41;
        fprintf&#40;ft, "Q");       // allways queen&#58; this is incorrect

    fprintf&#40;ft, " ");
    linelength += 5;
&#125;

int main&#40;int argc, char *argv&#91;&#93;)
&#123;
    int             i,
                    ply;
    size_t          filesize;
    int             node&#91;1000&#93;;
    struct MOVE &#123;
        unsigned char   move_from;
        unsigned char   move_to;
        unsigned char   move_promo;
    &#125;   moves&#91;1000&#93;;

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

    for (;;) &#123;
        print_move&#40;book&#91;node&#91;ply&#93;&#93;.move_from, book&#91;node&#91;ply&#93;&#93;.move_to,
                   book&#91;node&#91;ply&#93;&#93;.move_promo, ply&#41;;
        if &#40;book&#91;node&#91;ply&#93;&#93;.first_child > 0&#41; &#123;  // current game

            moves&#91;ply&#93;.move_from = book&#91;node&#91;ply&#93;&#93;.move_from;
            moves&#91;ply&#93;.move_to = book&#91;node&#91;ply&#93;&#93;.move_to;
            moves&#91;ply&#93;.move_promo = book&#91;node&#91;ply&#93;&#93;.move_promo;
            node&#91;ply + 1&#93; = book&#91;node&#91;ply&#93;&#93;.first_child;
            ply++;
        &#125; else &#123; // new game
            fprintf&#40;ft, "\n");
            node&#91;ply&#93; = book&#91;node&#91;ply&#93;&#93;.next_sibling;
            while &#40;node&#91;ply&#93; < 0&#41; &#123;
                ply--;
                if &#40;ply < 0&#41; &#123;
                    fclose&#40;ft&#41;;
                    exit&#40;0&#41;;
                &#125;
                node&#91;ply&#93; = book&#91;node&#91;ply&#93;&#93;.next_sibling;
            &#125;
            print_head&#40;);
            linelength = 0;
            for &#40;i = 0; i < ply; i++) &#123;
                print_move&#40;moves&#91;i&#93;.move_from, moves&#91;i&#93;.move_to, moves&#91;i&#93;.move_promo, i&#41;;
            &#125;
        &#125;
        if &#40;node&#91;ply&#93; >= filesize / &#40;int&#41; sizeof&#40;struct BOOK&#41;) &#123;
            printf&#40;"Error&#58; out of file\n");
            fclose&#40;ft&#41;;
            exit&#40;0&#41;;
        &#125;
    &#125;
    return 0;
&#125;

Post Reply