@@ -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,117 @@ int MakeFlywheelUnitTest(const char *inPgnFileName, const char *outFileName, con
214214 }
215215
216216 fclose (infile);
217-
217+
218218 return rc;
219219}
220220
221221
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+ int totalGameCount = 0 ;
244+
245+ rc = 0 ;
246+
247+ for (;;)
248+ {
249+ while (GetNextPgnMove (infile, movestr, state, info))
250+ {
251+ if (state == PGN_FILE_STATE_NEWGAME)
252+ {
253+ ++totalGameCount;
254+ ply = 0 ; // signals reader that we are starting a new game
255+ board.Init ();
256+ }
257+
258+ MoveList legal;
259+ board.GenMoves (legal);
260+
261+ if (!ParseFancyMove (movestr, board, move))
262+ {
263+ fprintf (stderr, " ERROR: illegal move '%s'\n " , movestr);
264+ rc = 1 ;
265+ goto failure_exit;
266+ }
267+
268+ char notation[LONGMOVE_MAX_CHARS];
269+ if (!FormatLongMove (board.WhiteToMove (), move, notation))
270+ {
271+ fprintf (stderr, " ERROR: cannot format move\n " );
272+ rc = 1 ;
273+ goto failure_exit;
274+ }
275+ fprintf (outfile, " %d %s\n " , ply, notation);
276+
277+ // Print all legal moves in SAN/PGN format.
278+ char san[MAX_MOVE_STRLEN + 1 ];
279+ for (int i=0 ; i < legal.num ; ++i)
280+ {
281+ FormatChessMove (board, legal, legal.m [i], san);
282+ if (i > 0 )
283+ fprintf (outfile, " " );
284+ fprintf (outfile, " %s" , san);
285+ }
286+ fprintf (outfile, " \n " );
287+
288+ board.MakeMove (move, unmove);
289+ ++ply;
290+
291+ char fen[200 ];
292+ if (!board.GetForsythEdwardsNotation (fen, sizeof (fen)))
293+ {
294+ fprintf (stderr, " ERROR: cannot calculate FEN\n " );
295+ rc = 1 ;
296+ goto failure_exit;
297+ }
298+ fprintf (outfile, " %s\n " , fen);
299+
300+ bool check = board.CurrentPlayerInCheck ();
301+ bool mobile = board.CurrentPlayerCanMove ();
302+ fprintf (outfile, " check=%d mobile=%d\n " , (int )check, (int )mobile);
303+ fprintf (outfile, " \n " );
304+ }
305+
306+ if (state != PGN_FILE_STATE_FINISHED)
307+ break ; // nothing left in this PGN file, or we encountered a syntax error
308+ }
309+
310+ failure_exit:
311+ fclose (outfile);
312+ if (rc == 0 )
313+ printf (" Processed %d games.\n " , totalGameCount);
314+ else
315+ remove (outFileName);
316+ }
317+ else
318+ {
319+ fprintf (stderr, " ERROR: cannot open file '%s' for write\n " , outFileName);
320+ }
321+
322+ fclose (infile);
323+ return rc;
324+ }
325+
326+
327+
222328int main ( int argc, const char *argv[] )
223329{
224330 char line [256 ];
@@ -521,6 +627,17 @@ int main ( int argc, const char *argv[] )
521627 const char *varname = argv[4 ];
522628 return MakeFlywheelUnitTest (inPgnFileName, outFileName, varname);
523629 }
630+ else if (strcmp (argv[1 ], " --gearbox" ) == 0 )
631+ {
632+ if (argc != 4 )
633+ {
634+ fprintf (stderr, " Use: %s --gearbox infile.pgn outfile.txt\n " , argv[0 ]);
635+ return 1 ;
636+ }
637+ const char *inPgnFileName = argv[2 ];
638+ const char *outFileName = argv[3 ];
639+ return MakeGearboxUnitTest (inPgnFileName, outFileName);
640+ }
524641 else
525642 {
526643 fprintf ( stderr,
0 commit comments