[![](https://git.sr.ht/~alip/jja/blob/main/misc/jja-logo.png)](https://git.sr.ht/~alip/jja)
Swiss army knife for chess file formats
=======================================
[![Jin, Jîyan, Azadî](https://img.shields.io/badge/Jin,%20J%C3%AEyan,%20Azad%C3%AE!-8A2BE2)](https://en.wikipedia.org/wiki/Woman,_Life,_Freedom)
[![crates.io](https://img.shields.io/crates/v/jja.svg)](https://crates.io/crates/jja)
[![repology](https://repology.org/badge/latest-versions/jja.svg)](https://repology.org/project/jja/versions)
[![msrv](https://img.shields.io/badge/rustc-1.70%2B-green?style=plastic)](https://blog.rust-lang.org/2022/09/22/Rust-1.70.0.html)
[![documentation](https://docs.rs/jja/badge.svg)](https://docs.rs/jja)
[![build status](https://builds.sr.ht/~alip/jja.svg)](https://builds.sr.ht/~alip/jja?)
[![downloads](https://img.shields.io/crates/d/jja.svg)](https://crates.io/crates/jja)
[![Crowdin](https://badges.crowdin.net/jja/localized.svg)](https://crowdin.com/project/jja)
[![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta)
[![license](https://img.shields.io/crates/l/jja.svg)](https://git.sr.ht/~alip/jja/tree/main/item/COPYING)
[![dependency status](https://deps.rs/repo/sourcehut/~alip/jja/status.svg)](https://deps.rs/repo/sourcehut/~alip/jja)
[![maintenance-status](https://img.shields.io/badge/maintenance-actively--developed-brightgreen.svg)](https://git.sr.ht/~alip/jja)
This is ___jja___, a command line utility to interact with various chess file
formats. It is still in its early stages of development. The initial intention
of the author was to convert their opening books which were saved with ChessBase's
proprietary [CTG](https://www.chessprogramming.org/CTG) format to the free and open
[PolyGlot](http://hgm.nubati.net/book_format.html) format. Overtime they intend to
add support for other chess file formats (
[cbh](https://www.chessprogramming.org/ChessBase_%28Database%29%23Formats),
[si4](https://www.chessprogramming.org/SCID#Database_Format),
[si5](https://www.chessprogramming.org/SCID#Database_Format)
and so on).
# Demo
# Jin, Jîyan, Azadî
I've started hacking this on International Women's Day 2023, a day to honor the
achievements of women and advocate for their rights worldwide. As a person of
Kurdish heritage, I am particularly moved by the slogan "Woman, Life, Freedom",
which has become a symbol of resistance against oppression and a call for
equality. In the spirit of free software and free speech, I strive to
contribute to the creation of a more just and inclusive society, where every
human being is granted the freedom to express themselves and pursue their
dreams. I also honor the memory of Mahsa Amini, whose tragic death reminds us
of the urgent need to fight for women's freedom and safety.
More on Wikipedia,
[WikiPedia::Woman, Life, Freedom](https://en.wikipedia.org/wiki/Woman,_Life,_Freedom)
# Formats
As of version 0.7.0, ___jja___ supports reading/querying:
- [PolyGlot](http://hgm.nubati.net/book_format.html), aka `bin`
- [Arena](https://www.chessprogramming.org/ABK), aka `abk`
- [ChessBase](https://www.chessprogramming.org/CTG), aka `ctg`
- [ChessMaster](https://www.chessprogramming.org/Chessmaster), aka `obk`
(version 1 and 2, w\o,with text notes)
- [BrainLearn](https://github.com/amchess/BrainLearn), aka `exp`
opening book files, whereas it supports writing/converting to:
- [PolyGlot](http://hgm.nubati.net/book_format.html), aka `bin`
- [Arena](https://www.chessprogramming.org/ABK), aka `abk`
- [BrainLearn](https://github.com/amchess/BrainLearn), aka `exp`
opening book files.
As of version 0.5.0, ___jja___ supports exporting all the supported opening book
formats to [PGN](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm). To
use this functionality, specify an output file with `pgn` extension as an argument
to `jja edit`.
As of version 0.8.0, ___jja___ supports exporting all positions in a
[PGN](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm) file into an
output [EPD](https://www.chessprogramming.org/Extended_Position_Description) file.
To use this functionality, specify an input file with `pgn` extension (or a
compressed pgn: `pgn.bz2`, `pgn.gz`, `pgn.lz4`, `pgn.xz` or `pgn.zst`) and an output
file with `epd` extension as arguments to `jja edit`.
During opening book conversion, ___jja___ uses the information provided in various
input opening book formats to come up with a **move weight** which accompanies the
move in the [PolyGlot](http://hgm.nubati.net/book_format.html) opening file.
___jja___ also writes some custom numbers in the **learn** field, such as
[NAGs](https://en.wikipedia.org/wiki/Numeric_Annotation_Glyphs) during `ctg`
conversion or **priority** during `abk` conversion. You may disable this custom
usage using `--no-learn` as it may confuse other software making use of this field.
Note, [Arena](https://www.chessprogramming.org/ABK), aka `abk`, opening book file
writing support is only supported from
[ChessBase](https://www.chessprogramming.org/CTG), aka `ctg` books. Use the command
line flags `--author`, `--comment`, `--probability-priority`, `--probability-games`,
`--probability-win-percent` to configure [ABK](https://www.chessprogramming.org/ABK)
header metadata. Game statistics (minimum number of games/wins, win percentages for
both sides) are managed automatically by ___jja___.
In-place editing for [Arena](https://www.chessprogramming.org/ABK) opening books is
also possible using `-i, --in-place=SUFFIX` command line option. Conversion from
[PolyGlot](http://hgm.nubati.net/book_format.html), aka `bin`, and
[ChessMaster](https://www.chessprogramming.org/Chessmaster), aka `obk` opening books
to [Arena](https://www.chessprogramming.org/ABK), aka `abk` opening book files is
planned for a future release.
# Usage
- Use `jja info` to get brief information about the chess file.
- Use `jja find` to search for a position in a chess file.
- Use `jja edit` to edit opening book files and convert to
[PolyGlot](http://hgm.nubati.net/book_format.html) files or
[Arena](https://www.chessprogramming.org/ABK) files.
- Use `jja make` to compile
[PGN](https://en.wikipedia.org/wiki/Portable_Game_Notation) files into
[PolyGlot](http://hgm.nubati.net/book_format.html) opening books.
- Use `jja dump` to dump a [PolyGlot](http://hgm.nubati.net/book_format.html)
or [BrainLearn](https://github.com/amchess/BrainLearn) file as a stream of
[JSON](https://en.wikipedia.org/wiki/JSON) arrays.
- Use `jja restore` to restore a [PolyGlot](http://hgm.nubati.net/book_format.html)
or [BrainLearn](https://github.com/amchess/BrainLearn) file from a stream of
[JSON](https://en.wikipedia.org/wiki/JSON) arrays.
- Use `jja merge` to merge two [PolyGlot](http://hgm.nubati.net/book_format.html)
opening books.
- Use `jja match` to arrange book matches using random playouts.
- Use `jja play` to make random playouts, optionally using books.
- Use `jja digest` to calculate Zobrist hash of a given chess position.
- Use `jja perft` to calculate node count from a given position up to a given depth.
- Use `jja open` to browse [ECO](https://www.chessprogramming.org/ECO)
classification.
- Use `jja quote` to print a chess quote.
___jja___ determines the type of the file using its file extension. Files with the
extension `.bin` are considered [PolyGlot](http://hgm.nubati.net/book_format.html)
books. Files with the extension `.ctg` are considered
[ChessBase](https://www.chessprogramming.org/CTG) books. Files with the extension
`.abk` are considered [Arena](https://www.chessprogramming.org/ABK) books. Files
with extension `.obk` are considered
[ChessMaster](https://www.chessprogramming.org/Chessmaster) books. Files with
extension `.exp` are considered [BrainLearn](https://github.com/amchess/BrainLearn)
experience files.
By default if the standard output is a
[TTY](https://en.wikipedia.org/wiki/Computer_terminal), ___jja___ will display
information using fancy tables. Use `--porcelain` command line option to get the
output in [CSV](https://en.wikipedia.org/wiki/Comma-separated_values)
(comma-separated values) format instead.
# Install
To compile from source, use `cargo install jja`. This requires the [Rust
Toolchain](https://rustup.rs/) to be installed. In addition you are going to need
[OpenSSL](https://www.openssl.org/) libraries on
[UNIX](https://en.wikipedia.org/wiki/Unix) systems. Moreover you need
[liburing](https://github.com/axboe/liburing) on [Linux](https://kernel.org). If
you're on a [Linux](https://kernel.org) system older than
[5.1](https://en.wikipedia.org/wiki/Io_uring#History) or you are unable to install
[liburing](https://github.com/axboe/liburing) for another reason, you may disable
the feature by building ___jja___ with `cargo install jja --no-default-features`.
As an alternative, release builds of ___jja___ are hosted on
[chesswob.org](https://chesswob.org/jja) for
[64-bit](https://en.wikipedia.org/wiki/64-bit_computing)
[Linux](https://en.wikipedia.org/wiki/Linux) and
[Windows](https://en.wikipedia.org/wiki/Microsoft_Windows). These versions are
signed by [GnuPG](https://gnupg.org/), using key
[D076A377FB27DE70](https://keybase.io/alip/pgp_keys.asc). To install, acquire the
latest version from [chesswob.org](https://chesswob.org/jja), verify the
[checksum](https://en.wikipedia.org/wiki/Checksum) and the
[GnuPG](https://gnupg.org/)
[signature](https://en.wikipedia.org/wiki/Digital_signature):
```
$> export JJA_VERSION=0.7.1
$> export JJA_FLAVOUR=glibc
$> curl https://keybase.io/alip/pgp_keys.asc | gpg --import
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13292 100 13292 0 0 13535 0 --:--:-- --:--:-- --:--:-- 26584
gpg: key D076A377FB27DE70: public key "Ali Polatel (Caissa AI) " imported
gpg: Total number processed: 1
gpg: imported: 1
$> for f in jja-${JJA_VERSION}-${JJA_FLAVOUR}.bin{,.sha512sum,.sha512sum.asc}; do wget -q https://chesswob.org/jja/${f}; done
$> gpg --verify jja-${JJA_VERSION}.bin.sha512sum.asc jja-${JJA_VERSION}.bin.sha512sum
gpg: Signature made Sun Mar 19 20:52:41 2023 CET
gpg: using RSA key 5DF763560390A149AC6C14C7D076A377FB27DE70
gpg: Good signature from "Ali Polatel (Caissa AI) ...
$> sha512sum -c jja-${JJA_VERSION}.bin.sha512sum
jja: OK
$> sudo install -m755 jja-${JJA_VERSION}-${JJA_FLAVOUR}.bin /usr/local/bin
```
Finally you may download the builds of the latest git version via the
[SourceHut build server](https://builds.sr.ht/~alip/jja?). There're three flavours,
`windows`, `linux-glibc`, and `linux-musl`. Simply browse to the latest build and
download the artifact listed on the left. Note: these artifacts are kept for 90
days.
# Packaging Status
[![Packaging status](https://repology.org/badge/vertical-allrepos/jja.svg)](https://repology.org/project/jja/versions)
# License
__jja__ is free software: you can redistribute it and/or modify it under the
terms of the __GNU General Public License__ as published by the Free Software
Foundation, either __version 3__ of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but __WITHOUT
ANY WARRANTY__; without even the implied warranty of __MERCHANTABILITY__ or
__FITNESS FOR A PARTICULAR PURPOSE__. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see .
# Bugs
```
Hey you, out there beyond the wall,
Breaking bottles in the hall,
Can you help me?
```
Report bugs to ___jja___'s bug tracker at :
1. Always **be polite**, respectful, and kind:
2. Keep your final change as **small and neat** as possible:
3. Attaching poems with the bug report encourages consideration tremendously.
# PGN Book Making
Since version 0.4.0, ___jja___ can make
[PolyGlot](http://hgm.nubati.net/book_format.html) books out of
[PGN](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm)
files. This feature is similar to `polyglot make-book` with the following
differences:
1. ___jja___ may directly read compressed
[PGN](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm) files
.pgn.{bz2,gz,lz4,xz,zst}
2. ___jja___ can process
[PGN](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm) files bigger
than your system's available memory, by persisting statistics in a temporary
[RocksDB](https://rocksdb.org/) database.
3. ___jja___ scales move weights by default to prevent potential overflows with huge
[PGN](http://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm) files bigger
files, use `--no-scale` to disable.
4. ___jja___ can filter moves using *Filter Expressions*, allowing the user to
filter-out unwanted games and create specialised opening books.
## Filter Expressions
The filter expression string should contain filter conditions, which consist of a
tag name, a comparison operator, and a value. The following operators are supported:
- `>` (greater than)
- `>=` (greater than or equal to)
- `<` (less than)
- `<=` (less than or equal to)
- `=` (equal to)
- `!=` (not equal to)
- `=~` (regex match, case insensitive)
- `!~` (negated regex match, case insensitive)
Filter conditions can be combined using the following logical operators:
- `AND` (logical AND)
- `OR` (logical OR)
Example:
`--filter="Event =~ World AND White =~ Carlsen AND ( Result = 1-0 OR ECO = B33 )"`
Supported tags are Event, Site, Date, UTCDate, Round, Black, White, Result,
BlackElo, WhiteElo, BlackRatingDiff, WhiteRatingDiff, BlackTitle, WhiteTitle, ECO,
Opening, TimeControl, Termination, TotalPlyCount, and ScidFlags.
In addition to these are four special variables, namely, Player, Elo, Title, and
RatingDiff. These variables may be used to match the relevant header from either
one of the sides. E.g the filter:
`--filter="Player =~ Carlsen"`
is functionally equivalent to
`--filter="( White =~ Carlsen OR Black =~ Carlsen )"`
Note: The filtering is designed to be simple and fast. The tokens, including
parantheses are split by whitespace. Quoting values is not allowed. For more
sophisticated filtering needs, use pgn-extract.
### Scid Flags
Scid uses one character flags, `DWBMENPTKQ!?U123456`, for each field where:
- `D` - Deleted
- `W` - White opening
- `B` - Black opening
- `M` - Middlegame
- `E` - Endgame
- `N` - Novelty
- `P` - Pawn structure
- `T` - Tactics
- `K` - Kingside play
- `Q` - Queenside play
- `!` - Brilliancy
- `?` - Blunder
- `U` - User-defined
- `1..6` - Custom flags
It is ill-advised to rely on the order of the characters flags.
Use a regex match if/when you can.
## Tips and Tricks about PGN Book Making
0. The defaults run best on my laptop and in my personal benchmarks on the
[SourceHut build
server](https://builds.sr.ht/~alip/jja/commits/main/benchmark.yml),
they're not universal truth.
1. ___jja___ processes input PGN files in parallel. You can use this to your
advantage by giving many split PGNs as input to increase parallelism and
performance.
2. Increasing batch size is good as long as you have constant memory usage. When
threads can't keep up, you'll get increased memory usage so that's the point you
really know your limit.
3. Try increasing max open files to the point you don't get too many open files
error from your operating system. You may specify `--max-open-files=-1` to keep
files always open.
4. Try different compression algorithms for the temporary
[RocksDB](https://rocksdb.org/) database, or try disabling compression completely
if you have enough space. ___jja___ writes the temporary
[RocksDB](https://rocksdb.org/) database in the same directory as the first
pgn file argument. The default compression algorithm,
[Lz4](https://lz4.github.io/lz4/), and the default compression level, `4`, are
aimed at speedy conversion with relatively moderate space usage. If you run out
of space during conversion, try to use an algorithm like
[Zstd](https://github.com/facebook/zstd) with an "ultra" level, ie. a level
greater or equal to `20`.
5. Use filters which are processed during PGN traversal when possible. Due to the
fact that these filters are matched before writing the game data to the temporary
database, when use wisely, they may have a vast on impact space and memory costs
and therefore improve overall performance. These filters are `--filter=`,
`--max-ply=`, `--min-pieces=`, `--only-white`, and
`--only-black`.
# Acknowledgements
Thanks to ___Steinar H. Gunderson___, for publishing the [CTG
Specification](https://web.archive.org/web/20210129162445/https://rybkaforum.net/cgi-bin/rybkaforum/topic_show.pl?tid=2319),
and authoring the [remoteglot](http://git.sesse.net/?p=remoteglot;a=summary) tool:
The [CTG](https://www.chessprogramming.org/CTG) probing code in ___jja___ is very
directly ported from their
[C](https://en.wikipedia.org%2Fwiki%2FC_%28programming_language%29%) probing code,
and the specification has been an enormous help in clearing up various rough edges.
Thanks to ___Fabien Letouzey___, the author of the original
[PolyGlot](http://hgm.nubati.net/book_format.html) software: The
[PolyGlot](http://hgm.nubati.net/book_format.html) probing, book making and merging
code in ___jja___ is mostly ported from their respective
[C](https://en.wikipedia.org%2Fwiki%2FC_%28programming_language%29%) code. Thanks to
___Michel Van den Bergh___, the author of pg\_utils, a collection of tools to
interact with [PolyGlot](http://hgm.nubati.net/book_format.html) opening books: The
[PolyGlot](http://hgm.nubati.net/book_format.html) book editing code of ___jja___
uses many ideas and code excerpts from pg\_utils. Thanks to ___Peter Österlund___,
the author of [DroidFish](https://www.chessprogramming.org/DroidFish): The
[ABK](https://www.chessprogramming.org/ABK) opening book interface code in ___jja___
makes use of ideas and code excerpts from
[DroidFish](https://www.chessprogramming.org/DroidFish). Thanks to ___Jens
Nissen___, the author of [ChessX](https://chessx.sourceforge.io/): The
[CTG](https://www.chessprogramming.org/CTG) and
[ABK](https://www.chessprogramming.org/ABK) probing codes in ___jja___ use ideas and
code excerpts from [ChessX](https://chessx.sourceforge.io/). Thanks to
[LiChess](https://lichess.org), the best chess website on the planet. The `quote`
command of ___jja___ has a selection of quotes imported from the
[LiChess](https://lichess.org) codebase. Thanks to ___Shane Hudson___, the author of
[Scid vs. PC](https://scidvspc.sourceforge.net/): The `jja eco` command uses the
[ECO](https://www.chessprogramming.org/ECO) classification which has been done by
the [Scid](https://scidvspc.sourceforge.net/) project. In addition, the
[PolyGlot](http://hgm.nubati.net/book_format.html) editing code of ___jja___ uses
ideas and code from [Scid](https://scidvspc.sourceforge.net/). Thanks to ___Marcus
Bufett___, the author of
[chess-tactics-cli](https://github.com/marcusbuffett/chess-tactics-cli): The
chessboard displaying code in [PolyGlot](http://hgm.nubati.net/book_format.html) and
[ABK](https://www.chessprogramming.org/ABK) edit screens is borrowed from
[chess-tactics-cli](https://github.com/marcusbuffett/chess-tactics-cli).
# ChangeLog
## 0.9.1
- upgrade `nix` crate from `0.27` to `0.28`.
- upgrade `tempfile` crate from `3.8` to `3.10`.
- upgrade `rust-embed` crate from `8.1` to `8.4`.
- upgrade `rusqlite` crate from `0.30` to `0.31`.
- upgrade `rayon` crate from `1.8` to `1.10`.
- upgrade `hostname` crate from `0.3` to `0.4`.
- Add support for restoring BrainLearn experience files from Lichess
evaluations export JSON.
- `TotalPlyCount` PGN tag is now supported in make filters.
- fix `--win,draw,loss-factor` calculation for make
- Add 50-moves detection and 3-position repetition detection to the play
subcommand.
- upgrade `once_cell` crate from `1.18` to `1.19`.
- upgrade `rayon` crate from `1.7` to `1.8`.
- upgrade `zstd` crate from `0.12` to `0.13`.
- upgrade `rusqlite` crate from `0.29` to `0.30`.
- upgrade `dialoguer` crate from `0.10` to `0.11`.
- upgrade `i18n-embed` crate from `0.13` to `0.14`.
- upgrade `rust-embed` crate from `6.8` to `8.0`.
- upgrade `built` crate from `0.6` to `0.7`.
- fix quote matching at word boundaries when no wildcard characters are given.
- merge learned `-O, --outlier-threshold=` to specify an outlier threshold
where moves with weights higher than the given threshold are filtered out from the
merged output book. This stands from the fact that if the weight differences of
the same move in two different books have a high difference, calculating any
average may not yield meaningful results. The default is 0, which disables this
feature.
- merge learned `--strategy dynmid` which stands for
`jja::merge::MergeStrategy::DynamicMidpoint`.
- merge learned `--strategy wdist` which stands for
`jja::merge::MergeStrategy::WeightedDistance`.
- upgrade `nix` crate from `0.26` to `0.27` and add the `signal` feature.
- merge learned `--strategy wmedian` which stands for
`jja::merge::MergeStrategy::WeightedMedian`.
- merge learned `--strategy entropy` which stands for
`jja::merge::MergeStrategy::Entropy`.
- merge learned `--strategy quadratic` which stands for
`jja::merge::MergeStrategy::QuadraticMean`. This strategy merges using the Quadratic
Mean (Root Mean Square) approach. The Quadratic Mean (also known as the Root Mean
Square) is a statistical measure of the magnitude of a set of numbers. It offers a
more balanced view, especially when dealing with numbers of varying magnitudes.
- merge learned `--strategy lavg` which stands for
`jja::merge::MergeStrategy::LogarithmicAverage`. This strategy merges using a
logarithmic averaging approach. Given that logarithmic functions compress large
values and expand small values, we can use them to get a merge strategy that's
sensitive to differences in smaller weights while being more resistant to
disparities in larger weights.
## 0.9.0
- merge cutoff specified using `-c, --cutoff` is now applied after the merge
strategy assigns new weights. This way, cutoff may also be used to filter out
unwanted entries after the merge.
- the default value of `edit --color-weight-blue` has been changed from `32768` to
`65280` for consistency with `--nag-weight-good`.
- merge learned new merge strategy `jja::merge::MergeStrategy::Sort` to calculate
weight based on the relative position of the move entry in sorted move entries.
- merge learned new merge strategy `jja::merge::MergeStrategy::GeometricScaling` to
calculate the weight using geometric scaling: The geometric scale focuses on
multiplying numbers together rather than adding, which can help in equalizing
disparities.
- merge learned new merge strategy `jja::merge::MergeStrategy::HarmonicMean` to
calculate the harmonic mean weight of the identical move entries in both books.
This approach tends to favor more balanced weights and is less influenced by
extreme values.
- merge learned new merge strategy `jja::merge::MergeStrategy::Sigmoid` to remap the
weights in a non-linear fashion using the sigmoid function. The idea here is to
diminish the influence of extreme values, which might be causing the
dissatisfaction in previous strategies.
- edit now properly prioritizes CTG move entries with higher combined color, NAG,
performance score such that the ordering is more close to the original.
- edit learned new commandline flags `-C, --no-colors`, and `-N, --no-nags` to avoid
using CTG move colours and NAGs to assign PolyGlot move weights or Arena move
priorities.
- merge and make commands now outputs `info` on the output book after successful run.
- merge strategy defaults to the new `pavg` strategy rather than `sum` now.
- merge learned `--strategy pavg` which stands for
`jja::merge::MergeStrategy::PercentageAverage`. This strategy merges by computing
the weighted average of percentage weights, taking into account the total number
of entries in each book. This approach gives higher importance to moves from
larger books versus smaller ones, ensuring that the resultant weights reflect the
relative contributions of each book based on its size.
- merge learned `--rescale` to rescale weights of merged book entries globally to
fit into 16 bits. This is similar to `edit --rescale` but works on the final
merged book rather than the input books.
- make now uses `estimate-num-keys` property of the temporary RocksDB database to
determine the _approximate_ unique position count rather than bulk scanning the
database twice which improves performance.
- make now uses read ahead during the bulk scan of the temporary RocksDB database.
This increases performance significantly especially on spinning disks.
The read ahead size may be configured using the `--read-ahead=` commandline
option. This defaults to `4 MB` and may be disabled by passing `0` as size.
- make now uses asynchronous I/O during the bulk scan of the temporary RocksDB
database. This increases performance significantly especially with the `io_uring`
feature enabled. This may be disabled using the new `--sync` commandline argument
or using the environment variable `JJA_SYNC`.
- drop `smallvec` crate usage, and remove dependency.
- replace `humansize` with `bytefmt` crate.
- `jja::abk::traverse_tree` function now returns a `BTreeMap` rather than a `BTreeMap` which is a
**breaking change**. Moreover this function now sorts the value vectors using
binary search which makes `abk->bin` both more memory efficient and faster.
- `jja::ctg::ByteBoard::from_position` has been replaced with the function
`from_board` which is a **breaking change**.
- `jja::ctgbook::CtgBook::process_move` function now utilizes binary search for move
table lookup improving efficiency. `jja::ctg::MOVETABLE`'s `encoding` element has
changed its type from `char` to `u8` which is a **breaking change**.
- edit converts CTG books to BIN books with 20% less memory usage using the new compact
`jja::polyglot::CompactBookEntry` data structure.
- `jja::abk::PackedSBookMoveEntry` has been renamed to `CompactSBookMoveEntry` which
is a **breaking change**.
- drop the unused functions `jja::ctgbook::CtgBook::extract_all{,2}` and the unused
type `jja::ctgbook::CtgTree` both of which are **breaking changes**.
- rename `jja::ctgbook::CtgBook::extract_map{,2}` to `extract_abk{,2}` for
consistency which is a **breaking change**.
- use `extract_bin` in `CTG->BIN` to improve efficiency
- implement new functions `jja::ctgbook::CtgBook::extract_bin{,2}`
- use `human-panic` crate for user friendly panic messages.
## 0.8.1
- upgrade `tempfile` crate from `3.7` to `3.8`.
- upgrade `clap` crate from `4.3` to `4.4`.
- info learned to print the sha256 checksum of the chess file.
- fix a memory leak in builds with the `i18n` feature disabled.
- edit now converts CTG books to ABK books around 5% times faster using 30% less
memory thanks to the new public functions `jja::ctgbook::CtgBook::extract_map{,2}`
which directly returns a `BTreeMap>` rather than processing a
`CtgTree` into a `SBookMoveEntryHashMap` as an additional step.
- info now prints information about the size of a single entry.
- info now prints information about ABK number of entries.
- New public function `jja::abkbook::AbkBook::total_entries()` to calculate the
number of entries in an Arena opening book file.
- Various memory efficiency improvements for `CTG->ABK` conversion.
- edit now reads from standard input rather than spawning the default editor if the
standard input does not refer to a terminal, ie is not a TTY. This is useful for
programmatic editing of opening books. find output may be piped to edit which
makes it practical to write entries from an opening book to another opening book
of the same type. Finally this also gives users who are unable to use the editor
functionality a chance to edit their opening books by submitting a custom CSV
file via standard input.
- replace the final `lazy_static!` usages with `once_cell` and drop the dependency
on `lazy_static` crate. Our usage of `once_cell` is currently in Rust nightly and
is hopefully soon going to land in stable Rust.
## 0.8.0
- new `perft` subcommand to count legal move paths of a given length
- upgrade `pgn-reader` crate from `0.24` to `0.25`
- upgrade `shakmaty` crate from `0.25` to `0.26`
- upgrade `tempfile` create from `3.6` to `3.7`
- **important fix** in PGN generation to avoid skip some lines due to the incorrect
usage of the repetition tracker. This effects PGN generation from all supported
opening book formats (`abk`, `bin`, `ctg`, `exp`, `obk`) so users are highly
recommended to re-export their previously exported PGNs using `jja edit
book.{abk,bin,ctg,exp,obk} -o book.pgn`.
- bump MSRV (minimal supported Rust version) from `1.64` to `1.70`.
- quote now matches at word boundaries unless the given quote pattern includes the
wildcard characters `.`, `?`, or `*`.
- jja now ignores invalid castling rights and en passant squares in PGN games' FEN
header rather than skipping the game.
- edit learned to dump all positions in a PGN file to an output EPD file. Compressed
PGN files are supported, hence the usage is
`jja edit source.pgn{,.bzip2,gz,lz4,xz,zst} -o output.epd`.
- dump learned `-e`, `--elements` to specify a list of elements to dump which
defaults to `id, position`. This option works only for PGN dumps.
- new subcommand `probe` which can be used to probe Syzygy tablebases up to 7
pieces. This is almost functionally identical to the awesome Fathom tool, but also
offers some alternative modes such as `--test --fast` to skip walking the DTZ line
at the cost of misevaluating `MaybeWin` and `MaybeLoss` positions.
- edit learned two new command line options `--max-ply=`, and
`--look-ahead=`. The former limits PGN generation to a certain number of
plies, and defaults to `1024`. The latter is used to specify the number of plies
to look ahead on PolyGlot book lookup misses during PGN generation which is useful
to generate PGNs of book generated by `--only-black|white`. Currently
`--look-ahead` only supports `0`, and `1` as argument, of which `0` being the
default value, other values will generate an `unimplemented` panic which directs
the user to report a bug. This change comes along with a change in the public
function signature of `jja::polyglotbook::PolyGlotBook::write_pgn` which is a
**breaking change**.
- The function `jja::polyglot::from_move` now takes argument a *reference* to a
`shakmarty::Move` rather than a `shakmaty::Move` which is a **breaking change**.
- The default values of some weight conversion arguments to `jja edit` have been
changed to be more intuitive, in that default value of `--color-weight-green` has
been changed from `10000` to `65520`, `--color-weight-blue` from `1000` to
`32768`, `--nag-weight-good` from `9000` to `65280`, `--nag-weight-hard` from
`10000` to `65520`, `--nag-weight-interesting` from `7500` to `61440`,
`--nag-weight--forced` from `10000` to `65520`, and `--nag-weight-only` from
`10000` to `65520`. The new defaults are empirical, and advanced users are
recommended to use `--color-weight-*`, and `--nag-weight-*` arguments with `jja
edit` for fine-tuning during `CTG->BIN` or `CTG->ABK` conversions.
- **Important fix** in `jja::ctgbook::CtgBook::read_page` function to prevent panics
due to out-of-bounds access. This fixes search & conversion with some huge CTG
books.
- The function `jja::abkbook::AbkBook::traverse_book_and_merge` function now returns
nothing rather than `Result<(), Box>` which is a **breaking
change**.
- The function `jja::chess::lines_from_tree` now returns a `Table` rather than a
`Result
>` which is a **breaking change**.
- Use `anyhow` crate for error handling. This is mainly used in the main code, and
not the library code but there are points where the library code is changed, and
there are **breaking changes**: `jja::pgnbook::create_opening_book` now returns an
`anyhow::Result`, rather than
`Result>`. Similarly the function
`jja::pgn::pgn_dump` now returns `anyhow::Result<()>` rather than
`Result<(), Box>`.
- The functions `jja::system::get_progress_{bar,spinner}` now return a `ProgressBar`
rather than a `Result>`. These functions
now panic when there is an error in the template, which shouldn't happen normally.
This change is a **breaking change**.
- The function `jja::system::edit_tempfile` now returns `EditTempfileError` on error
rather than `Box`. Moreover the `EditTempfileError` enum
has a new member `EditTempfileError::InputOutputError(std::io::Error)`. These
changes are in the public API and hence are **breaking changes**.
- restore learned experimental EPD output support. This may be used in a pipeline
with dump, e.g: `jja dump -fcsv file.pgn | jja restore file.epd` to create an
Extended Position Description file of all the positions in the given Portable Game
Notation file. The EPD entries include the Zobrist hash of the positions in the `id`
field.
- fix deserializing of Chess960 castling rights in `jja::chess::deserialize_chess`.
- `jja::chess::deserialize_chess` function now panics on invalid piece indexes
rather than silently continuing.
- `hash` subcommand has been renamed to `digest`. The former will work as an alias
until the next major version bump.
## 0.7.1
- fix build with `i18n` feature disabled.
- enable the lint `#![deny(clippy::cast_lossless)]` for jja library and fix
offending code.
## 0.7.0
- enable the lint `#![deny(clippy::cast_precision_loss)]` for jja library and fix
offending code.
- edit learned to use buffered I/O, rather than direct I/O during PGN conversion to
improve efficiency, especially with huge opening books.
- edit learned to display a progress bar during PGN conversion.
- CTG interface has seen many **breaking change**s to make the interface leaner,
with regards to the recent mmap changes. As a result, the function
`jja::ctg::find_piece` returns an `Option` rather than a `Result`, the functions `jja::ctgbook::CtgBook::extract_all{,2}` return a
`CtgTree` rather than a `Result`, and the function
`jja::ctgbook::CtgBook::lookup_moves` returns an `Option>` rather
than a `Result