chess_db.pl -- PGN and chess game databases.

This library produces chess games databases from PGN files and provides some
predicates for manipulating these databases.

Once connected to a number of chess_db databases, all kinds of information about the games
can be interrogated. (see chess_db_openning/2 for an example).

Ideally we want to hook this pack to a web-page interface for playing the games as we select them.

Installation:

?- pack_install( chess_db ).

The pack includes code to:

There are two example databases in data/ and an example program, examples/short.pl

Dependencies

Packs:

prosqlite
(1.5)
db_facts
(0.5)
stoics_lib
(1.0)
options
(1.0)
debug_call
(1.1)

Basics

By default, chess database dirs contain 3 sqlite databases:

game_info.sqlite
contains game_info(Gid,Key,Val) info about each game
game_move.sqlite
table is of form game_move(Gid,Num,Turn,Move)
game_orig.sqlite
table is game_orig(Gid,Orig); where Orig is the verbatim of the section in the PGN for that game

A number of databases can be connected at the same time.

For example a number of databases can be declared in dir/1 terms within file:
~/.pl/chess_db_connect.pl see options_append/3.

Example

?- [pack('chess_db/examples/short.pl')].
?- short.      % creates a chess_db in subdirectory short/ from data/4ncl_short.pgn
               % and displays the game ids for games that start with [e4,e6] (French defense)
...

?- french.     % creates a new pgn file from the base for the 2 games in short/ that start with e4,e6
% Handles already exist, for chess_db directory: '/home/nicos/pl/packs/src/chess_db/examples/short'
gid(chdbs(<sqlite>(0x71b4f0),<sqlite>(0xe577f0),<sqlite>(0xe13400)):1)
gid(chdbs(<sqlite>(0x71b4f0),<sqlite>(0xe577f0),<sqlite>(0xe13400)):31)
writting_to_file(short/french.pgn)
true.

% open file french.pgn on program that can play the games

Mini tutorial

The above example in detail.

?- debug( chess_db(original) ).

Spits the original games as they are added to the database.

?- chess_db( pack('chess_db/data/4ncl_short.pgn'), [dir('short'),create(true)] ).
.....
1. e4 e6 2. d4 d5 3. Nd2 Be7 4. Bd3 c5 5. dxc5 Nf6 6. Qe2 O-O 7. Ngf3 a5 8. O-O
Na6 9. e5 Nd7 10. Nb3 Ndxc5 11. Bb5 Bd7 12. Bxd7 Qxd7 13. Nbd4 Ne4 14. Be3 f5
15. Qb5 Qxb5 16. Nxb5 Rfc8 17. c3 Nac5 18. Nfd4 Ra6 19. f3 Ng5 20. Rad1 Nf7 21.
f4 Ne4 1/2-1/2

true.

Create a database in fresh directory short/. The DB will be populated with games from pgn file chess_db/data/4ncl_short.pgn
The database is closed after populated.

?- chess_db_connect( [dir('short'),profile(false)] ).
true.

Connect to the new database. The connections are managed internally.

?- findall( Gid, (chess_db_openning([e4,e6],Gid),write(Gid),nl), Gids ).
chdbs(<sqlite>(0x276c930),<sqlite>(0x278f320),<sqlite>(0x2792450)):1
chdbs(<sqlite>(0x276c930),<sqlite>(0x278f320),<sqlite>(0x2792450)):31
Gids = [chdbs(<sqlite>(0x276c930), <sqlite>(0x278f320), <sqlite>(0x2792450)):1, chdbs(<sqlite>(0x276c930), <sqlite>(0x278f320), <sqlite>(0x2792450)):31].

Interrogate (all connected) databases for games starting with the sequence [e4,e6] (French defense).

?- debug(chess_db).

Turn general debug messaging on.

?- chess_db_connect( [dir('short'),profile(false)] ).
% Handles already exist, for chess_db directory: '/home/nicos/pl/packs/private/chess_db/short'

Re-connecting is handled fine.

?- PgnF = 'short/french.pgn', chess_db_openning_pgn( [e4,e6], PgnF ).

Creates a new pgn file containing 2 games in their original script with the PGN file.
Moves are matched to game_move/4 and are pulled from game_orig/2.

?- halt.
% chessx short/french.pgn

You can view the two games in your favourite game PGN viewer. In this case chessx in Linux.

Debug terms

Listens to:

Pack predicates

working with games

info interactions

manage database connections

miscellaneous

Pack info

author
- nicos angelopoulos
version
- 0.1 2018/3/18
- 0.2 2018/3/20
See also
- http://stoics.org.uk/~nicos/sware/chess_db
- https://github.com/nicos-angelopoulos/chess_db
- [pack('chess_db/examples/short.pl')]
- pack(prosqlite), pack(db_facts), pack(stoics_lib), pack(options)
 pgn(+PgnF, -Pgn)
pgn(+PgnF, +Pgn)
pgn(+PgnIn, -PgnOut)
Reads-from and writes-to between PGN files and Pgn term representations.
It can also be used to ensure second argument is a Pgn term when either a file or Pgn term is given as ground first argument.

A Pgn term is of the form: pgn(Info,Moves,Res,Orig). Where, <br>

?- pgn( 4nclall1718.pgn, Pgn ).  % in data/
?- pgn( '18.03.10-Hampstead.pgn', Pgn ).

fixme:

  1. if we have result from both Info and end of moves, make sure they are the same <br>
  2. if the info missing and the result from endo of moves exists, then add it to info
author
- nicos angelopoulos
version
- 0.1 2018/03/14
To be done
- complement the 2 ways of getting the result.
- currently valuation marks and variations are thrown away
 chess_db(+PgnOrF)
 chess_db(+PngOrF, +Opts)
Add games from a PGN file or a PGN term, PgnOrF, to the chess database pointed to by Opts.

Opts

create(Create=false)
if true create dir and/or db files if they do not exist
dir(Dir=_51890)
directory for database
position(Pos=false)
if true, use position table

Options can also be picked up from ~/.pl/chess_db.pl (see options_append/3).

?- working_directory( Old, pack('chess_db/examples') ), assert( push_dir(Old) ).
?- Opts = [dir('/tmp/chess_dbase'),create(true)],
   chess_db( '18.03.10-Hampstead.pgn', Opts ).
author
- nicos angelopoulos
version
- 0.1 2018/3/14
See also
- options_append/3
 chess_db_list(+Dir)
A simple, on-screen dump of all data in a chess games database.
Likely to be only useful for debugging.
?- chess_db_list( short ).
author
- nicos angelopoulos
version
- 0.1 2018/3/14
 chess_db_max_id(+HandleST, -Max)
For a handle or term of handles (in which case the first argument is used), return the Max id of the first column of the game_info on the Handle.
?- chess_db_current( CdbHs ), chess_db_max_id( CdbHs, Max ).
Max = 31.
author
- nicos angelopoulos
version
- 0.1 2018/3/15
 chess_db_connect(Opts)
Connect a number of chess_dbs as open db handles that will
be available to a number of predicates that access the information,
for example chess_db_openning/3.

Opts

create(Create=false)
if true create dir and/or db files if they do not exist
dir(Dir=_63638)
directory of chess database (multiple are allowed, see chess_db_connect/1)
profile(Prof=Prof)
whether to mix, true, or ignore, false, profile based dir options (see options_append/4) if no dir(Dir) option is present in Opts, then Prof is ignored

Note, that standard databases can be defined long term in ~/.pl/chess_db_connect.pl

% cat ~/.pl/chess_db_connect.pl
dir( '/usr/local/users/chess/chess_db' ).
?- chess_db_connect( dir('/tmp/') ).
ERROR: Unhandled exception: chess_db_dir_does_not_exist_and_asked_not_to_create_it_by('/usr/local/users/nicos/sware/nicos/git/github/stoics.infra/here',false)

?- chess_db_connect( true ).
HERE:
false.
author
- nicos angelopoulos
version
- 0.1 2018/3/15
See also
- chess_db_openning/3
 chess_db_current(-CdbHs)
 chess_db_current(-CdbHs, +Opts)
If there are open databases the handles structure of each is returned.
Else, chess_db_connect(Opts) is called to create the connections.<br>

Opts

close(Close=_98194)
if the databases were opened by this call, then Close will be instantiated to true
dir(Dir=_98534)
directory of chess database (multiple are allowed, see chess_db_connect/1)
?- debug( chess_db(original) ).
?- chess_db( pack('chess_db/data/4ncl_short.pgn'), [dir('/tmp/fourNCL'),create(true)] ).
.....
?- chess_db_connect( [dir('/tmp/fourNCL'),profile(false)] ).
true.
?- chess_db_current( CdbHs ).
CdbHs = chdbs(<#40e8de28067f0000>, <#40e8de28067f0000>, <#40e8de28067f0000>).
?- chess_db_current( CdbHs ), chess_db_max_id( CdbHs, Max ).
Max = 31.
author
- nicos angelopoulos
version
- 0.1 2018/3/15
See also
- chess_db_connect/1
 chess_db_openning(+Moves, -Gid)
 chess_db_openning(+Moves, -Gid, +Opts)
Gid is an identifier for a game starting with sequence of Moves.
Moves is a list of atoms in standard chess notation.

GidStr is of the form GdbHs:Gid.

Games are taken from data based identified by chess_db_current/2.

Opts are passed to chess_db_current/2.

?- chess_db_openning( [e4,e6], Gid ). % find a French defense game.
author
- nicos angelopoulos
version
- 0.1 2018/3/15
 chess_db_disconnect(?Db)
Disconnect from a Db or all Dbs (-Db).

Db can be

?- debug( chess_db(original) ).
?- chess_db( pack('chess_db/examples/4ncl_short.pgn'), [dir('/tmp/fourNCL'),create(true)] ).
...
?- chess_db_connect( [dir('/tmp/fourNCL'),profile(false)] ).
true.
?- chess_db_current( CdbHs .
CdbHs = chdbs(<#40e867375c7f0000>, <#40e867375c7f0000>, <#40e867375c7f0000>).
?- chess_db_disconnect( CdbHs ).
author
- nicos angelopoulos
version
- 0.1 2018/3/18
 chess_db_openning_pgn(Moves, PgnF)
Dump all the originial PGN fragments that correspond to Moves openning, to
the output file PgnF.
?- chess_db( pack('chess_db/examples/4ncl_short.pgn'), [dir(short),create(true)] ).
?- chess_db_connect( [dir(short),profile(false)] ).
?- PgnF = 'short/french.pgn', chess_db_openning_pgn( [e4,e6], PgnF ).
author
- nicos angelopoulos
version
- 0.1 2018/3/17
See also
- pack('examples/short.pl')
 chess_db_version(-Version, -Date)
The current version. Version is a Mj:Mn:Fx term, and date is a date(Y,M,D) term.
?- chess_db_version( 0:2:0, date(2018,3,20) ).
true.