Playing chess with strings to build datasets for text generation.<p>I want to share this quick win.<p>The other day I was asking myself some theoretical chess questions, and wanted to answer them programmatically and needed to build some custom chess datasets for that.<p>I needed the chess basic routines, like getting the next legal moves, displaying the board, and some rudimentary position scores. I contemplated writing from scratch. I contemplated using some library. But instead I settled for a higher level choice : interfacing with Stockfish game engine over a text interface.<p>There is something called UCI, which stands for Universal Chess Interface, ( <a href="https://official-stockfish.github.io/docs/stockfish-wiki/UCI-&-Commands.html" rel="nofollow">https://official-stockfish.github.io/docs/stockfish-wiki/UCI...</a> ), to use it you start a new stockfish process and write and read from the standard inputs.<p>So instead of writing bug prone routines to check the validity of board positions, it turn the basic routines into a simple wrapper of parsing task to read and write UCI protocol to use a battle tested engine.<p>A chess position state is simply defined as a vector<string> representing the sequence of moves. Moves are string in long algebraic notation.<p>This architectural decision allows for very quick (LLM-powered development) prototyping.<p>namespace bp = boost::process;
bp::ipstream is;
bp::opstream os;<p>bp::child c("../Stockfish/src/stockfish", bp::std_in < os, bp::std_out > is);<p>void displayBoard( const vector<string> & moveSeq, bp::ipstream& is, bp::opstream& os );<p>void getLegalMoves( const vector<string> & moveSeq, vector<string>& legalMoves, bp::ipstream& is, bp::opstream& os );<p>void getTopKMoveAndScoreAtDepthFromPosition(const vector<string> & moveSeq,int K, int D, vector<pair<string,int> >& topkmoves, bp::ipstream& is, bp::opstream& os , bool debug = false);<p>void displayBoard( const vector<string> & moveSeq, bp::ipstream& is, bp::opstream& os )
{<p>os << "position startpos moves";<p>for( int i = 0 ; i < moveSeq.size() ; i++)<p>{<p><pre><code> os << " " << moveSeq[i];
</code></pre>
}<p>os << endl;<p>os << "d" << endl;<p>os << "isready" << endl;<p>string line;<p>while (getline(is, line))
{
if (!line.compare(0, 7, "readyok")) break;
cout << line << endl;
}<p>}<p>You get the gist...