C++: Generate Chess960 Starting Position

Bjarne-stroustrup
 

Chess960 is a variant of chess created by world champion Bobby Fisher. Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:

  • as in the standard chess game, all eight white pawns must be placed on the second rank.
  • White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:
    • the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)
    • the King must be between two rooks (with any number of other pieces between them all)
  • Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game. (That is, their positions are not independently randomized.)

With those constraints there are 960 possible starting positions, thus the name of the variant.

Task

The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed with Chess symbols in Unicode: ♔♕♖♗♘ or with the letters King Queen Rook Bishop kNight.

#include <iostream>
#include <string>
#include <time.h>
using namespace std;
class chess960
{
public:
	void generate( int c )
	{
		for( int x = 0; x < c; x++ )
		cout << startPos() << "\n";
	}

private:
	string startPos()
	{
		char p[8]; memset( p, 0, 8 );
		int b1, b2; bool q;

		// bishops
		while( 1 )
		{
			b1 = rand() % 8; b2 = rand() % 8;
			if( !( b1 & 1 ) && b2 & 1 ) break;
		}
		p[b1] = 'B'; p[b2] = 'B';

		// queen, knight, knight
		q = false;
		for( int x = 0; x < 3; x++ )
		{
			do
			{ b1 = rand() % 8; }
			while( p[b1] );
			if( !q )
			{ p[b1] = 'Q'; q = true; }
			else p[b1] = 'N';
		}

		// rook king rook
		q = false;
		for( int x = 0; x < 3; x++ )
		{
			int a = 0;
			for( ; a < 8; a++ )
			if( !p[a] ) break;

			if( !q )
			{ p[a] = 'R'; q = true; }
			else
			{ p[a] = 'K'; q = false; }
		}

		string s;
		for( int x = 0; x < 8; x++ )
		s.append( 1, p[x] );

		return s;
	}
};

int main( int argc, char* argv[] )
{
	srand( time( NULL ) );
	chess960 c;
	c.generate( 10 );
	cout << "\n\n";
	return system( "pause" );
}
Output:
BNNBRKRQ
NRBQKBNR
RNQKNBBR
RKRBBQNN
RNBKQNRB
RKQNRNBB
QRBKRNNB
RBNKNRBQ
RBKNBNRQ
NQNRKBBR

SOURCE

Content is available under GNU Free Documentation License 1.2.