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"