960pos.c: program to generate or lookup chess960 starting position - randomcrap - random crap programs of varying quality
(HTM) git clone git://git.codemadness.org/randomcrap
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit ccfd3b75fd9368ff84c604a337e094038fdcd4d3
(DIR) parent 7710dbd1b1784adeffe118b15282fd05cb1b31d1
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue, 23 Jan 2024 20:22:52 +0100
960pos.c: program to generate or lookup chess960 starting position
Diffstat:
A 960pos.c | 186 +++++++++++++++++++++++++++++++
1 file changed, 186 insertions(+), 0 deletions(-)
---
(DIR) diff --git a/960pos.c b/960pos.c
@@ -0,0 +1,186 @@
+/* generate chess960 position by number or list all the positions.
+ see: https://en.wikipedia.org/wiki/Fischer_random_chess_numbering_scheme */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+ranktofen(char *buf, size_t bufsiz, const char *rank)
+{
+ int i;
+
+ snprintf(buf, bufsiz, "%s/pppppppp/8/8/8/8/PPPPPPPP/%s w KQkq - 0 1", rank, rank);
+
+ for (i = 0; i < 8; i++)
+ buf[i] = ((buf[i] - 'A') + 'a'); /* lower-case */
+}
+
+/* simpler method, using 2 tables */
+void
+postab(int n, char *rank)
+{
+ /* Scharnagl's NQ-skeleton Table */
+ char *ktab[] = {
+ "QNNRKR", "NQNRKR", "NNQRKR", "NNRQKR", "NNRKQR", "NNRKRQ",
+ "QNRNKR", "NQRNKR", "NRQNKR", "NRNQKR", "NRNKQR", "NRNKRQ",
+ "QNRKNR", "NQRKNR", "NRQKNR", "NRKQNR", "NRKNQR", "NRKNRQ",
+ "QNRKRN", "NQRKRN", "NRQKRN", "NRKQRN", "NRKRQN", "NRKRNQ",
+ "QRNNKR", "RQNNKR", "RNQNKR", "RNNQKR", "RNNKQR", "RNNKRQ",
+ "QRNKNR", "RQNKNR", "RNQKNR", "RNKQNR", "RNKNQR", "RNKNRQ",
+ "QRNKRN", "RQNKRN", "RNQKRN", "RNKQRN", "RNKRQN", "RNKRNQ",
+ "QRKNNR", "RQKNNR", "RKQNNR", "RKNQNR", "RKNNQR", "RKNNRQ",
+ "QRKNRN", "RQKNRN", "RKQNRN", "RKNQRN", "RKNRQN", "RKNRNQ",
+ "QRKRNN", "RQKRNN", "RKQRNN", "RKRQNN", "RKRNQN", "RKRNNQ"
+ };
+
+ /* Bishop's table */
+ unsigned char btab[] = {
+ 0, 0, 0, 2, 0, 4, 0, 6, 1, 0, 2, 0, 2, 2, 2, 4,
+ 1, 2, 3, 0, 4, 0, 4, 2, 1, 4, 3, 2, 5, 0, 6, 0
+ };
+
+ char *s;
+ int i, t1, t2;
+
+ t2 = n % 16;
+ t1 = (n - t2) / 16;
+
+ for (i = 0; i < 8; i++)
+ rank[i] = 0;
+
+ /* bishops */
+ rank[btab[t2 * 2]] = 'B';
+ rank[btab[t2 * 2] + btab[t2 * 2 + 1] + 1] = 'B';
+
+ s = ktab[t1];
+ for (i = 0; i < 8 && *s; i++) {
+ if (rank[i])
+ continue;
+ rank[i] = *s;
+ s++;
+ }
+
+ rank[8] = '\0'; /* NUL */
+}
+
+/* more computation way to generate the position */
+void
+poscomp(int n, char *rank)
+{
+ int n1, n2, n3, n4, b1, b2, q, i;
+ int ntab[] = { 0, 0, 0, 1, 0, 2, 0, 3, 1, 0, 1, 1, 1, 2, 2, 0, 2, 1, 3, 0 };
+
+ for (q = 0; q < 8; q++)
+ rank[q] = 0;
+
+ /* bishop (white square) */
+ b1 = n % 4;
+ n2 = (n - b1) / 4;
+
+ /* b, d, f, h */
+ rank[b1 * 2 + 1] = 'B'; /* b */
+
+ /* bishop (dark square) */
+ b2 = n2 % 4;
+ n3 = (n2 - b2) / 4;
+ /* a, c, e, g */
+ rank[b2 * 2] = 'B';
+
+ /* queen */
+ q = n3 % 6;
+ n4 = (n3 - q) / 6;
+ for (i = 0; i < 8; i++) {
+ if (rank[i])
+ continue;
+ if (q == 0) {
+ rank[i] = 'Q';
+ break;
+ }
+ q--;
+ }
+
+ /* knights */
+ n1 = ntab[n4 * 2]; /* skip for first knight */
+ n2 = ntab[n4 * 2 + 1]; /* skip for second knight */
+
+ for (i = 0; i < 8; i++) {
+ if (rank[i])
+ continue;
+ if (n1) {
+ n1--;
+ continue;
+ }
+ rank[i] = 'N';
+ break;
+ }
+
+ for (; ; i++) {
+ if (i >= 8)
+ i = 0; /* wrap around */
+ if (rank[i])
+ continue;
+ if (n2) {
+ n2--;
+ continue;
+ }
+ rank[i] = 'N';
+ break;
+ }
+
+ /* there are three blank squares remaining; place a rook in each of the
+ outer two and the king in the middle one. */
+ for (i = 0; i < 8; i++) {
+ if (rank[i])
+ continue;
+ rank[i] = 'R';
+ break;
+ }
+
+ for (i = 7; i >= 0; i--) {
+ if (rank[i])
+ continue;
+ rank[i] = 'R';
+ break;
+ }
+
+ for (i = 0; i < 8; i++) {
+ if (rank[i])
+ continue;
+ rank[i] = 'K';
+ break;
+ }
+
+ rank[8] = '\0'; /* NUL */
+}
+
+int
+main(int argc, char *argv[])
+{
+ char fen[92], rank[9];
+ long l;
+ int i;
+
+ if (argc > 2) {
+usage:
+ fprintf(stderr, "usage: %s <0-959>\n", argv[0]);
+ return 1;
+ }
+
+ if (argc == 2) {
+ l = strtol(argv[1], NULL, 10);
+ if (l < 0 || l > 959)
+ goto usage;
+ postab(l, rank);
+ ranktofen(fen, sizeof(fen), rank);
+ printf("%s\n", fen);
+ } else {
+ /* 518 is classical */
+ for (i = 0; i < 960; i++) {
+ postab(i, rank);
+ ranktofen(fen, sizeof(fen), rank);
+ printf("%d\t%s\n", i, fen);
+ }
+ }
+
+ return 0;
+}