URI:
       add example for picking random puzzle by some theme + blind practise - chess-puzzles - chess puzzle book generator
  HTML git clone git://git.codemadness.org/chess-puzzles
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit ba83e5c98028bd2bc0e46840cb7004a8c9549b79
   DIR parent 16797922fca63b7c4ebea1f378ee40197930c026
  HTML Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Wed,  4 Mar 2026 19:42:37 +0100
       
       add example for picking random puzzle by some theme + blind practise
       
       Diffstat:
         A blindpig/count.c                    |      82 +++++++++++++++++++++++++++++++
         A blindpig/pickrandom.sh              |      24 ++++++++++++++++++++++++
       
       2 files changed, 106 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/blindpig/count.c b/blindpig/count.c
       @@ -0,0 +1,82 @@
       +/*
       + * Find simple puzzles intended for blind / visualization practise.
       + *
       + * Compile:
       + *         cc -O2 -o count count.c
       + *
       + * Example 1:
       + *
       + *   # Generate list once adding a score field, sort from easier to harder:
       + *   ./count mateIn1 oneMove blindSwineMate < lichess_db_puzzle.csv | sort -t ',' -k11,11 > vis.csv
       + *
       + *   # Pick a random one using awk to filter by score.
       + *   LC_ALL=C awk -F ',' 'int($11) <= 30' vis.csv | sort -R | sed 1q
       + *
       + * Example 2:
       + *
       + *   # Make scores for all:
       + *   ./count < lichess_db_puzzle.csv | sort -t ',' -k11,11 > vis.csv
       + *
       + *   # Pick a random one using awk to filter by score and theme.
       + *   LC_ALL=C awk -F ',' '$8 ~ /mateIn1/ && int($11) <= 30' vis.csv | sort -R | sed 1q
       + *
       + */
       +
       +#include <stdio.h>
       +#include <string.h>
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        int i, ismatch, score;
       +        char *line = NULL, *p;
       +        size_t linesiz = 0;
       +        ssize_t n;
       +
       +        while ((n = getline(&line, &linesiz, stdin)) > 0) {
       +                if (n && line[n - 1] == '\n')
       +                        line[--n] = '\0';
       +
       +                ismatch = 0;
       +                /* filter on line / theme, multiple args possible: "mateIn1", "oneMove", "blindSwineMate" */
       +                for (i = 1; i < argc; i++) {
       +                        if (!strstr(line, argv[i])) {
       +                                ismatch = 1;
       +                                break;
       +                        }
       +                }
       +                if (ismatch)
       +                        continue;
       +
       +                /* skip until 2nd field which contains FEN */
       +                score = 0;
       +                for (p = line; *p; p++) {
       +                        if (*p == ',') {
       +                                p++;
       +                                break;
       +                        }
       +                }
       +
       +                /* Simple difficulty score / weight from FEN.
       +                   The idea is, the more pieces there are its harder to visualize.
       +                   (Many pawns) are harder to visualize than distinctive pieces(?). */
       +                for (; *p && *p != ' ' && *p != ','; p++) {
       +                        switch (*p) {
       +                        case 'Q': case 'q': score += 5; break;
       +                        case 'R': case 'r': score += 5; break;
       +                        case 'B': case 'b': score += 5; break;
       +                        case 'N': case 'n': score += 5; break;
       +                        case 'P': case 'p': score += 10; break;
       +                        }
       +                }
       +                /* append difficulty score / weight */
       +                printf("%s,%d\n", line, score);
       +        }
       +
       +        if (ferror(stdin) || fflush(stdout) || ferror(stdout)) {
       +                perror(NULL);
       +                return 1;
       +        }
       +
       +        return 0;
       +}
   DIR diff --git a/blindpig/pickrandom.sh b/blindpig/pickrandom.sh
       @@ -0,0 +1,24 @@
       +#!/bin/sh
       +FEN="../fen"
       +
       +line=$(LC_ALL=C awk -F ',' 'int($11) <= 30' vis.csv | sort -R | sed 1q)
       +
       +fen=$(printf '%s\n' "$line" | cut -f 2 -d ',')
       +moves=$(printf '%s\n' "$line" | cut -f 3 -d ',')
       +firstmove=$(printf '%s\n' "$moves" | cut -f 1 -d ' ')
       +sidetomove=$(printf '%s\n' "$fen" | cut -f 2 -d ' ')
       +
       +# DEBUG
       +#id=$(printf '%s\n' "$line" | cut -f 1 -d ',')
       +#echo "DEBUG: https://lichess.org/training/${id}"
       +#"$FEN" -H -o tty "$fen" "$firstmove"
       +#echo "---"
       +
       +# side to move is before first move played, so inversed.
       +if test "$sidetomove" = "b"; then
       +        echo "White to move"
       +else
       +        echo "Black to move"
       +fi
       +echo ""
       +"$FEN" -H -o describe "$fen" "$firstmove"