@@ -96,7 +96,7 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
9696 fprintf (stderr, " ERROR: Cannot open input PGN file '%s'\n " , inPgnFileName);
9797 return 1 ;
9898 }
99-
99+
100100 FILE *outfile = fopen (outFileName, " wt" );
101101 if (outfile)
102102 {
@@ -106,12 +106,12 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
106106 ChessBoard board;
107107 Move move;
108108 UnmoveInfo unmove;
109-
109+
110110 rc = 0 ;
111111 fprintf (outfile, " var %s = [\n " , varname);
112-
112+
113113 bool first = true ;
114-
114+
115115 for (;;)
116116 {
117117 while (GetNextPgnMove (infile, movestr, state, info))
@@ -124,9 +124,9 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
124124 else
125125 {
126126 fprintf (outfile, " , { " );
127- }
128-
129- if (state == PGN_FILE_STATE_NEWGAME)
127+ }
128+
129+ if (state == PGN_FILE_STATE_NEWGAME)
130130 {
131131 fprintf (outfile, " \" reset\" : true\n " );
132132 board.Init ();
@@ -135,27 +135,27 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
135135 {
136136 fprintf (outfile, " \" reset\" : false\n " );
137137 }
138-
138+
139139 MoveList legal;
140140 board.GenMoves (legal);
141-
141+
142142 if (!ParseFancyMove (movestr, board, move))
143143 {
144144 fprintf (stderr, " ERROR: illegal move '%s'\n " , movestr);
145145 rc = 1 ;
146146 goto failure_exit;
147147 }
148-
148+
149149 char notation[LONGMOVE_MAX_CHARS];
150150 if (!FormatLongMove (board.WhiteToMove (), move, notation))
151151 {
152152 fprintf (stderr, " ERROR: cannot format move\n " );
153153 rc = 1 ;
154154 goto failure_exit;
155155 }
156-
156+
157157 fprintf (outfile, " , \" move\" : \" %s\"\n " , notation);
158-
158+
159159 fprintf (outfile, " , \" legal\" : [" );
160160 for (int i=0 ; i < legal.num ; ++i)
161161 {
@@ -165,42 +165,42 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
165165 rc = 1 ;
166166 goto failure_exit;
167167 }
168- if (i > 0 )
168+ if (i > 0 )
169169 {
170170 fprintf (outfile, " , " );
171171 }
172172 fprintf (outfile, " \" %s\" " , notation);
173173 }
174174 fprintf (outfile, " ]\n " );
175-
175+
176176 board.MakeMove (move, unmove);
177-
177+
178178 char fen[200 ];
179179 if (!board.GetForsythEdwardsNotation (fen, sizeof (fen)))
180180 {
181181 fprintf (stderr, " ERROR: cannot calculate FEN\n " );
182182 rc = 1 ;
183183 goto failure_exit;
184184 }
185-
185+
186186 bool check = board.CurrentPlayerInCheck ();
187187 bool mobile = board.CurrentPlayerCanMove ();
188188 int reps = 0 ;
189189 int draw = (!mobile && !check) || board.IsDefiniteDraw (&reps);
190-
190+
191191 fprintf (outfile, " , \" fen\" : \" %s\"\n " , fen);
192192 fprintf (outfile, " , \" check\" : %s\n " , check ? " true" : " false" );
193193 fprintf (outfile, " , \" mobile\" : %s\n " , mobile ? " true" : " false" );
194194 fprintf (outfile, " , \" draw\" : %s }\n\n " , draw ? " true" : " false" );
195195 }
196-
196+
197197 if (state != PGN_FILE_STATE_FINISHED)
198198 {
199199 break ; // nothing left in this PGN file, or we encountered a syntax error
200200 }
201- }
202-
203- failure_exit:
201+ }
202+
203+ failure_exit:
204204 fprintf (outfile, " ];\n " );
205205 fclose (outfile);
206206 if (rc != 0 )
@@ -214,11 +214,137 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
214214 }
215215
216216 fclose (infile);
217-
217+
218+ return rc;
219+ }
220+
221+
222+ int MakeGearboxUnitTest (const char *inPgnFileName, const char *outFileName)
223+ {
224+ int rc = 1 ;
225+ remove (outFileName); // delete file if already exists
226+ FILE *infile = fopen (inPgnFileName, " rt" );
227+ if (infile == NULL )
228+ {
229+ fprintf (stderr, " ERROR: Cannot open input PGN file '%s'\n " , inPgnFileName);
230+ return 1 ;
231+ }
232+
233+ FILE *outfile = fopen (outFileName, " wt" );
234+ if (outfile)
235+ {
236+ PgnExtraInfo info;
237+ PGN_FILE_STATE state;
238+ char movestr [1 + MAX_MOVE_STRLEN];
239+ ChessBoard board;
240+ Move move;
241+ UnmoveInfo unmove;
242+ int ply = 0 ;
243+ bool skipThisGame = false ;
244+
245+ int totalGameCount = 0 ;
246+ int keptGameCount = 0 ;
247+
248+ const int MIN_ELO = 2600 ;
249+ const int GAME_LIMIT = 1000 ;
250+
251+ rc = 0 ;
252+
253+ for (;;)
254+ {
255+ while (GetNextPgnMove (infile, movestr, state, info))
256+ {
257+ if (state == PGN_FILE_STATE_NEWGAME)
258+ {
259+ ++totalGameCount;
260+ skipThisGame = (info.whiteElo < MIN_ELO || info.blackElo < MIN_ELO);
261+ if (!skipThisGame)
262+ {
263+ if (keptGameCount == GAME_LIMIT)
264+ break ;
265+ ++keptGameCount;
266+ ply = 0 ; // signals reader that we are starting a new game
267+ board.Init ();
268+ }
269+ }
270+
271+ if (skipThisGame)
272+ continue ;
273+
274+ MoveList legal;
275+ board.GenMoves (legal);
276+
277+ if (!ParseFancyMove (movestr, board, move))
278+ {
279+ fprintf (stderr, " ERROR: illegal move '%s'\n " , movestr);
280+ rc = 1 ;
281+ goto failure_exit;
282+ }
283+
284+ char notation[LONGMOVE_MAX_CHARS];
285+ if (!FormatLongMove (board.WhiteToMove (), move, notation))
286+ {
287+ fprintf (stderr, " ERROR: cannot format move\n " );
288+ rc = 1 ;
289+ goto failure_exit;
290+ }
291+
292+ fprintf (outfile, " %d %s\n " , ply, notation);
293+ for (int i=0 ; i < legal.num ; ++i)
294+ {
295+ if (!FormatLongMove (board.WhiteToMove (), legal.m [i], notation))
296+ {
297+ fprintf (stderr, " ERROR: cannot format legal move %d\n " , i);
298+ rc = 1 ;
299+ goto failure_exit;
300+ }
301+
302+ if (i > 0 )
303+ fprintf (outfile, " " );
304+ fprintf (outfile, " %s" , notation);
305+ }
306+ fprintf (outfile, " \n " );
307+
308+ board.MakeMove (move, unmove);
309+ ++ply;
310+
311+ char fen[200 ];
312+ if (!board.GetForsythEdwardsNotation (fen, sizeof (fen)))
313+ {
314+ fprintf (stderr, " ERROR: cannot calculate FEN\n " );
315+ rc = 1 ;
316+ goto failure_exit;
317+ }
318+ fprintf (outfile, " %s\n " , fen);
319+
320+ bool check = board.CurrentPlayerInCheck ();
321+ bool mobile = board.CurrentPlayerCanMove ();
322+ fprintf (outfile, " check=%d mobile=%d\n " , (int )check, (int )mobile);
323+ fprintf (outfile, " \n " );
324+ }
325+
326+ if (state != PGN_FILE_STATE_FINISHED)
327+ break ; // nothing left in this PGN file, or we encountered a syntax error
328+ }
329+
330+ failure_exit:
331+ fclose (outfile);
332+ if (rc == 0 )
333+ printf (" Kept %d of %d games.\n " , keptGameCount, totalGameCount);
334+ else
335+ remove (outFileName);
336+ }
337+ else
338+ {
339+ fprintf (stderr, " ERROR: cannot open file '%s' for write\n " , outFileName);
340+ }
341+
342+ fclose (infile);
218343 return rc;
219344}
220345
221346
347+
222348int main ( int argc, const char *argv[] )
223349{
224350 char line [256 ];
@@ -521,6 +647,17 @@ int main ( int argc, const char *argv[] )
521647 const char *varname = argv[4 ];
522648 return MakeFlywheelUnitTest (inPgnFileName, outFileName, varname);
523649 }
650+ else if (strcmp (argv[1 ], " --gearbox" ) == 0 )
651+ {
652+ if (argc != 4 )
653+ {
654+ fprintf (stderr, " Use: %s --gearbox infile.pgn outfile.txt\n " , argv[0 ]);
655+ return 1 ;
656+ }
657+ const char *inPgnFileName = argv[2 ];
658+ const char *outFileName = argv[3 ];
659+ return MakeGearboxUnitTest (inPgnFileName, outFileName);
660+ }
524661 else
525662 {
526663 fprintf ( stderr,
0 commit comments