Check out Atomic Chess, our featured variant for November, 2024.


[ Help | Earliest Comments | Latest Comments ]
[ List All Subjects of Discussion | Create New Subject of Discussion ]
[ List Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Single Comment

Capablanca Random Chess. Randomized setup for Capablanca chess. (10x8, Cells: 80) [All Comments] [Add Comment or Rating]
💡📝Reinhard Scharnagl wrote on Sun, Feb 27, 2005 11:57 PM UTC:
//=====================================
// CRC / Chess960 Position Generator
//=====================================
// reference implementation (C) 2005 by
// Reinhard Scharnagl, Munich, Germany
//=====================================

#include < string.h>
#include < stdio.h>

#define TXT_LIM 160

static char FenZone[TXT_LIM];

// insert a symbol into FEN-String 
// -------------------------------
// color could be:
// col <  0 => not specified
// col == 0 => bright square
// col == 1 => dark square
void PlaceIntoFEN
  (int cntFree, char symbol, int fieldColor)
{
  for (int pos = 0, free = 0; ; ++pos) {
    if (fieldColor < 0 || ((fieldColor ^ pos) & 1)) {
      if (!FenZone[pos] && cntFree == free++) {
        FenZone[pos] = symbol;
        break;
      }
    }
  }
}

// generating of FEN strings
// -------------------------
// nr could be
// nr >= 0 creating Chess960 position (1 ... 960)
// nr <  0 creating CRC position    (1 ... 48000)
const char *GetFen(int nr)
{
  // knight distributions over 5 free squares
  static const int knight_pos[10] = {
     3, // xx--- (binary encoded)
     5, // x-x--
     9, // x--x-
    17, // x---x
     6, // -xx--
    10, // -x-x-
    18, // -x--x
    12, // --xx-
    20, // --x-x
    24  // ---xx
  };

  // clear the working area
  int bit, pos = TXT_LIM;
  while (--pos >= 0) { FenZone[pos] = '\0'; }

  // test whether CRC is requested
  bool istCRC = (nr <= 0);

  if (istCRC) {
    nr = -nr;
    bool q_first = ((nr % 2) != 0);
    nr /= 2;
    PlaceIntoFEN(nr % 5, q_first ? 'q' : 'a', 0);
    nr /= 5;
    PlaceIntoFEN(nr % 5, q_first ? 'a' : 'q', 1);
    nr /= 5;
  }

  PlaceIntoFEN(nr % 4, 'b', 0);
  nr /= 4;
  PlaceIntoFEN(nr % 4, 'b', 1);
  nr /= 4;
  PlaceIntoFEN(nr % 6, istCRC ? 'c' : 'q', -1);
  nr /= 6;
  pos = knight_pos[nr % 10];
  for (bit = 5; --bit >= 0; ) {
    if ((pos & (1 << bit)) != 0)
      PlaceIntoFEN(bit, 'n', -1);
  }

  PlaceIntoFEN(2, 'r', -1);
  PlaceIntoFEN(1, 'k', -1);
  PlaceIntoFEN(0, 'r', -1);

  int width = istCRC ? 10 : 8;
  char *pC = &FenZone[width];
  *pC++ = '/';
  for (pos = width; --pos >= 0; ) {
    *pC++ = 'p';
  }
  for (pos = 4; --pos >= 0; ) {
    *pC++ = '/';
    *pC++ = (char)('0' + width % 10);
  }
  *pC++ = '/';
  for (pos = width; --pos >= 0; ) {
    *pC++ = 'P'; 
  }
  *pC++ = '/';
  for (pos = 0; pos < width; ++pos) {
    *pC++ = FenZone[pos] ^ ('a'^'A');
  }
  strcpy(pC, ' w KQkq - 0 1');

  return FenZone;
}

// test output
int main(void) {
  puts('first Chess960 positions');
  for (int nrFRC = 0; ++nrFRC <= 5; ) {
    puts(GetFen(nrFRC));
  }

  puts('first CRC positions');
  for (int nrCRC = 0; ++nrCRC <= 5; ) {
    puts(GetFen(-nrCRC));
  }

  return 0;
}