home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume20 / notation / part04 / notation.c
Encoding:
C/C++ Source or Header  |  1991-06-18  |  39.8 KB  |  1,795 lines

  1. /*
  2.   Notation program
  3.   @(#)notation.c    3.1 (C) Henry Thomas\tVersion 3.1\tDated 6/16/91
  4.  */
  5. /* Programme d'analyse de notation echiquienne
  6.    Copyright (C) 1990 Henry Thomas
  7.    Nom: notation
  8.    Auteur: Henry Thomas
  9.    Date: 27/11/90
  10. /*
  11. This file is part of NOTATION program.
  12.  
  13. NOTATION is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 1, or (at your option)
  16. any later version.
  17.  
  18. NOTATION is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with NOTATION; see the file COPYING.  If not, write to
  25. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  26.  
  27. /* --------------------- data part ---------------------- */
  28.  
  29. /* les tableaux suivants sont les tables de transcription de notation
  30.    selon les langages
  31.    */
  32. #ifdef __STDC__
  33. #include <stdlib.h>
  34. #endif
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38.  
  39. #include "chesstype.h"
  40. #include "notation.h"
  41. #include "drivers.h"
  42. #include "lexer.h"
  43.  
  44. extern void close_files();
  45.  
  46. char * version_string =
  47.   "@(#)notation.c    3.1 (C) Henry Thomas\tVersion 3.1\tDated 6/16/91";
  48.  
  49. static char * keywords[]= {
  50.   "@startplay" , "@clearboard" , "@showboard" ,
  51.   "@whitesmove", "@blacksmove", "@configwhite", "@configblack" ,
  52.   "@default" , 
  53.   /* these are keywords with arguments */
  54.   "@title", "@subtitle", "@score", "@language",
  55.   /* "special" keyword */
  56.   "@special", 
  57.   /* null and final keyword */
  58.   "@null"
  59.   };
  60.  
  61. int configuring = FALSE ;
  62. int configside = 0 ;
  63.  
  64.  
  65. static char * t_language[] = {
  66.   "french", "english", "italian", "spanish", "german", "dutch",
  67.   "czech",  "hungarian","polish", "romanian", "FIDE"
  68. };
  69.  
  70. static int in_language = DEFAULT_INPUT_LANGUAGE ;
  71. static int out_language = DEFAULT_OUTPUT_LANGUAGE ;
  72.  
  73. static char c_language[NBLANGUAGES][7] = {
  74. /* french    */  { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' },
  75. /* english   */  { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' },
  76. /* italian   */  { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' },
  77. /* spanish   */  { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' },
  78. /* german    */  { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' },
  79. /* dutch     */  { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' },
  80. /* czech     */  { '@' ,'K' , 'D' , 'V' , 'S' , 'J' , 'P' },
  81. /* hungarian */  { '@' ,'K' , 'V' , 'B' , 'F' , 'H' , 'G' },
  82. /* polish    */  { '@' ,'K' , 'H' , 'W' , 'G' , 'S' , 'P' },
  83. /* romanian  */  { '@' ,'R' , 'D' , 'T' , 'N' , 'C' , 'P' },
  84. /* FIDE      */  { '@' ,'K' , 'D' , 'T' , 'S' , 'N' , 'P' }
  85. /* UNIMPLEMENTED ... */
  86. /* user_def  *//*{ '@' ,'X' , 'X' , 'X' , 'X' , 'X' , 'X' }*/
  87. /* russian not implemented : ASCII russian is an oxymoron */
  88. /* russian   *//*{ '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' }*/
  89.            };
  90.  
  91. /* input translation table */
  92. char *in_table;
  93.  
  94.  
  95. char *  c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" };
  96.  
  97. /* various notations for en passant */
  98. #define N_EP 2
  99. char * c_en_passant[] = { "ep" , "e.p." } ;
  100.  
  101.  
  102. /* notation for catch */
  103. char c_prise ='x';
  104.  
  105. /* various comments */
  106. char * c_comments[] = { "+" , "++" , 
  107.               "?" , "??", "!", "!!", "!?", "?!",
  108.               "mate", "draw" };
  109.  
  110. /* movement tables */
  111. /* move only */
  112. /* white pawn, move */
  113. #define NB_M_PAWN_MOVE_WD 2
  114. static int m_pawn_move_wd [][2] = {
  115.   { 1, 0}, {2, 0}
  116. };
  117.  
  118. /* black pawn, move */
  119. #define NB_M_PAWN_MOVE_BD 2
  120. static int m_pawn_move_bd [][2] = {
  121.   {-1, 0}, {-2, 0}
  122. };
  123.  
  124. /* TRICK = we have added the catching move at the end of
  125.    the non catching ones; so in check_depl, we try first 
  126.    the non catching one and then the catching one.
  127.    So, even if catching (x) is non indicated in the input, 
  128.    we succeed in guessing the move
  129.    */
  130. /* white pawn, move */
  131. /*#define NB_M_PAWN_WD 2*/
  132. #define NB_M_PAWN_WD 4
  133. static int m_pawn_wd [][2] = {
  134.   { 1, 0}, {2, 0},
  135. /* catch... */
  136.   { 1, 1}, { 1,-1}
  137. };
  138.  
  139. /* white pawn, catch */
  140. #define NB_M_PAWN_WX 2
  141. static int m_pawn_wx [][2] = {
  142.   { 1, 1}, { 1,-1}
  143. };
  144.  
  145. /* black pawn, move */
  146. /*#define NB_M_PAWN_BD 2*/
  147. #define NB_M_PAWN_BD 4
  148. static int m_pawn_bd [][2] = {
  149.   {-1, 0}, {-2, 0},
  150. /* catch... */
  151.   {-1, 1}, {-1,-1} 
  152. };
  153.  
  154. /* black pawn, catch */
  155. #define NB_M_PAWN_BX 2
  156. static int m_pawn_bx [][2] = {
  157.   {-1, 1}, {-1,-1} 
  158. };
  159.  
  160.  
  161. #define NB_M_KNIGHT  8
  162. static int m_knight[][2] = { 
  163.   { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1},
  164.   { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2}
  165. };
  166.  
  167. #define NB_M_BISHOP 28
  168. static int m_bishop[][2] = {
  169.   { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  170.   { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  171.   {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  172.   {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}
  173. };
  174.  
  175. #define NB_M_ROOK 28
  176. static int m_rook[][2] = {
  177.   { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  178.   {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  179.   { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  180.   { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  181. };
  182.  
  183. #define NB_M_QUEEN 56
  184. static int m_queen[][2] = {
  185.   { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  186.   { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  187.   {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  188.   {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1},
  189.   { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  190.   {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  191.   { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  192.   { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  193. };
  194.  
  195. #define NB_M_KING 8
  196. static int m_king[][2] = {
  197.   { 1, 1}, { 1, 0}, { 1,-1},
  198.   {-1, 1}, {-1, 0}, {-1,-1},
  199.   { 0, 1}, { 0, -1}
  200. };
  201.  
  202.  
  203. /* I/O */
  204. FILE * infile ;
  205. FILE * fhelp;
  206.  
  207. static char * t_output[] = 
  208. { "ascii", "postscript", "tex", "roff", "xchess", "gnu" };
  209.  
  210. /* stack -- used for variation */
  211.  
  212. /* stack element */
  213. typedef struct {
  214.   depl * d;
  215.   game * b;
  216.   
  217.   /* we don't stack drivers, but only to variables */
  218.   int d1,d2; /* iswhiteturn and interrupt */
  219. } stack_elt ;
  220.  
  221. /* size of the stack
  222.    0 = ordinary play
  223.    1 = level 1 variation
  224.    2 = level 2 variation
  225.    3 = level 3 variation
  226. */
  227. #define VARIATION_MAX 3
  228.  
  229. /* the stack itself */
  230. static stack_elt stack[VARIATION_MAX];
  231.  
  232. /* top of the stack */
  233. /* --> explicit in dr->variation */
  234.  
  235.  
  236. /* ---------- automata definitions --------- */
  237. /* table for syntaxic analysis of move */
  238.  
  239. #define FINAL    10
  240. #define TML     FINAL   /* terminal state */
  241. #define NBETAT     11
  242. #define NBCLAS     8
  243.  
  244. /* successor of state */
  245. static int transit[NBETAT][NBCLAS] = { 
  246. /*   P a-h 1-8   -   x   =  \0   ? */ 
  247. /*(  0   1   2   3   4   5   6   7)*/
  248.   {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  249.   { -1,  2, -1, -1,  4, -1, -1, -1 }, /* etat  1 */
  250.   { -1,  6,  3,  4,  4,  8,TML,TML }, /* etat  2 */
  251.   { -1,  6, -1,  4,  4,  8,TML,TML }, /* etat  3 */
  252.   {  5,  6, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  253.   { -1,  6, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  254.   { -1, -1,  7, -1, -1, -1, -1, -1 }, /* etat  6 */
  255.   { -1, -1, -1, -1, -1,  8,TML,TML }, /* etat  7 */
  256.   {  9, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  257.   { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat  9 */
  258.   { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 == terminal */
  259. };
  260.  
  261. /* actions to do */
  262. static int action[NBETAT][NBCLAS] = {
  263. /*   P a-h 1-8   -   x   =  \0   ? */ 
  264.   {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  265.   { -1,  2, -1, -1, 10, -1, -1, -1 }, /* etat  1 */
  266.   { -1, 13,  3,  4,  5, 14,  6,  7 }, /* etat  2 */
  267.   { -1, 13, -1,  4,  5, 14,  6,  7 }, /* etat  3 */
  268.   {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  269.   { -1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  270.   { -1, -1,  3, -1, -1, -1, -1, -1 }, /* etat  6 */
  271.   { -1, -1, -1, -1, -1, 14,  8,  9 }, /* etat  7 */
  272.   { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  273.   { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat  9 */
  274.   { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 */
  275. };
  276.  
  277.  
  278. /* the complete play */
  279. play * theplay ;
  280.  
  281. /* current game
  282.    the name "tos" means "top of stack"
  283.    */
  284. static game * tos = GULL ;
  285.  
  286. /* variable holding current move */
  287. static depl * m = MULL ;
  288.  
  289. /* the output driver */
  290. static format * dr;
  291.  
  292. static int driver; /* driver type, ie gnu, ascii ... */
  293.  
  294. static int movecount;
  295.  
  296. /* current move, used by the parser */
  297. static int curpiece,  curcol,  curlig ;
  298. static int curdigit, curmove;
  299.  
  300. /* booleen d'erreur */
  301. int error_flag = FALSE;
  302.  
  303. /* move to display board */
  304. static int count = 0 ;
  305.  
  306. static int move_to_display[NB_MOVE_TO_DISP] ;
  307. static int nb_move_to_dsp = 0;
  308. static int stop_at_display = FALSE;
  309.  
  310. /* short and long form comment table */
  311. char * com_short[] = {
  312. #define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) SASC,
  313. #include "chesssymb.def"
  314.  ""
  315.  };
  316. #undef CHESSSYMB
  317.  
  318. char * com_long[] = {
  319. #define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) LASC,
  320. #include "chesssymb.def"
  321.  ""
  322.  };
  323. #undef CHESSSYMB
  324.  
  325.  
  326.  
  327. #define setboard(A,I,J,P,C)  { (A)->board[(I)][(J)] = (P) ; \
  328.                  (A)->color[(I)][(J)] = (C); }
  329. #define clsboard(A,I,J)   { (A)->board[(I)][(J)] = VOID ; \
  330.                 (A)->color[(I)][(J)] = VOID ;}
  331.  
  332. /* --------------------------- code part --------------------- */
  333.  
  334.  
  335. #ifdef __STDC__
  336. static int ispiece(char c)
  337. #else
  338. static int ispiece(c)
  339.      char c;
  340. #endif
  341. {
  342.   register int i;
  343.   
  344.   for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  345.   /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
  346.   return(i<NUMPIECES);
  347. }
  348.  
  349.  
  350. #ifdef __STDC__
  351. static int piece(char c)
  352. #else
  353. static int piece(c)
  354.      char c ;
  355. #endif
  356. {
  357.   register int i;
  358.   
  359.   for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  360.   if ( i== NUMPIECES)
  361.     i = PAWN ;
  362.   return(i);
  363. }
  364.  
  365. /* this function return yhe # entry of a keyword in a given table.
  366.    if key is not present, it returns the default value
  367.    */
  368. #ifdef __STDC__
  369. static int find_keyword(char *tab[], int nbentry,int defaut,
  370.             char *key,int warning)
  371. #else
  372. static int find_keyword(tab, nbentry,defaut,key,warning)
  373.      char * tab[]; /* the table to look in */
  374.      int nbentry;  /* number of entries */
  375.      int defaut;  /* the default value to return if search failed */
  376.      char *key;    /* the key to find */
  377.      int warning;  /* do we display a warning ? */
  378. #endif
  379. {
  380.   int i ;
  381.  
  382.   for(i=0; (i< nbentry) ;i++)
  383.     if (strcmp(tab[i],key)==0)
  384.       return(i);
  385.  
  386.   /* we failed to find the keyword */
  387.   if (warning)
  388.     (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
  389.   return(defaut);
  390. }
  391.  
  392. /* ---------- board management function ------------- */
  393.  
  394. #ifdef __STDC__
  395. void clear_board(game *g)
  396. #else
  397. void clear_board(g)
  398.      game *g;
  399. #endif
  400. {
  401.   register int i,j;
  402.  
  403.   for (i=0; i < 10; i++ )
  404.     for (j=0 ; j< 10 ; j++) {
  405.       g->board[i][j] = VOID;
  406.       g->color[i][j] = VOID;
  407.     }
  408. }
  409.  
  410. #ifdef __STDC__
  411. game * new_board(void)
  412. #else
  413. game * new_board()
  414. #endif
  415. {
  416.   game * tmp;
  417.   int i; 
  418.  
  419.   tmp = (game *) malloc (sizeof(game));
  420.   ALLOCP(tmp);
  421.   for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  422.     ((int *) tmp)[i] = 0;
  423.   return(tmp);
  424. }
  425.  
  426. #ifdef __STDC__
  427. game * copy_board(game *from, game *to)
  428. #else
  429. game * copy_board(from, to)
  430.      game * from;
  431.      game * to;
  432. #endif
  433. {
  434.   int i; 
  435.  
  436.   for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  437.     ((int *) to)[i] =  ((int *) from)[i] ;
  438.   return(to);
  439. }
  440.  
  441. #ifdef __STDC__
  442. void init_board(game *tgm)
  443. #else
  444. void init_board(tgm)
  445.   game * tgm;
  446. #endif
  447. {
  448.   register int i,j;
  449.  
  450.   clear_board(tgm);
  451.  
  452.   for (i=1; i< 9 ; i=i+7) {
  453.     tgm->board[i][1]= tgm->board[i][8] = ROOK ;
  454.     tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
  455.     tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
  456.     tgm->board[i][4]= QUEEN;
  457.     tgm->board[i][5]= KING;
  458.   }
  459.   for (i=2; i< 8 ; i=i+5) 
  460.     for (j=1; j <=8 ; j++)
  461.       tgm->board[i][j] = PAWN;
  462.  
  463.   for (i=1; i <=2; i++)
  464.     for (j=1; j <=8 ; j++) {
  465.       tgm->color[i][j] = WHITE;
  466.       tgm->color[i+6][j] = BLACK ;
  467.     }
  468. }
  469.  
  470. #ifdef __STDC__
  471. depl * new_move(void)
  472. #else
  473. depl * new_move()
  474. #endif
  475. {
  476.   depl * tmp;
  477.   int i; 
  478.   static int counter = 0;
  479.  
  480.   tmp = (depl *) malloc (sizeof(depl));
  481.   ALLOCP(tmp);
  482.   for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  483.     ((int *) tmp)[i] = 0;
  484.   tmp->uid = ++counter;
  485.   tmp->whiteturn = FALSE;
  486.   tmp->move = 0;
  487.   return(tmp);
  488. }
  489.  
  490.  
  491. #ifdef __STDC__
  492. void init_move(depl *m)
  493. #else
  494. void init_move(m)
  495.      depl *m;
  496. #endif
  497. {
  498.   m->move= 1 ;
  499.   m->whiteturn = TRUE ;
  500. }
  501.  
  502. #ifdef __STDC__
  503. depl * copy_move(depl *from,depl *to)
  504. #else
  505. depl * copy_move(from,to)
  506.      depl * from;
  507.      depl * to ;
  508. #endif
  509. {
  510.   int i; 
  511.  
  512.   for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  513.     ((int *) to)[i] = ((int *) from)[i];
  514.  
  515.   return(to);
  516. }
  517.  
  518. /* add a new move as successor to the move m */
  519. #ifdef __STDC__
  520. depl * add_trailing_move(depl *mo)
  521. #else
  522. depl * add_trailing_move(mo)
  523.      depl * mo;
  524. #endif
  525. {
  526.   mo->next = new_move();
  527.  
  528.   mo->next->prev = mo;
  529.   mo->next->next = (depl *) NULL;
  530.   mo->next->sub  = (depl *) NULL;
  531.  
  532.   mo->next->whiteturn = !( m->whiteturn ) ;
  533.   mo->next->move = mo->move;
  534.   if ( mo->next->whiteturn) {
  535.     mo->next->move++;
  536.   }
  537.  
  538.   return(mo->next);
  539. }
  540.  
  541. #ifdef __STDC__
  542. static depl * add_variation(depl *mo)
  543. #else
  544. static depl * add_variation(mo)
  545.      depl * mo;
  546. #endif
  547. {
  548.   depl *ip ; /* insertion point */
  549.  
  550.   ip = mo ;
  551.   while (ip->sub != (depl *) NULL )
  552.     ip = ip->sub ;
  553.   
  554.   ip->sub = new_move();
  555.  
  556.   ip->sub->prev = mo;
  557.   ip->sub->next = (depl *) NULL;
  558.   ip->sub->sub  = (depl *) NULL;
  559.   
  560.   /* as we have a fictif element heading our list, 
  561.      ( generated by add_trailing_move() )
  562.      we have to go back in the numbering */
  563.   ip->sub->whiteturn =  mo->prev->whiteturn  ;
  564.   ip->sub->move = mo->prev->move ;
  565.  
  566.   return(ip->sub);
  567. }
  568.  
  569.  
  570. #ifdef __STDC__
  571. static void free_move_list(depl *d)
  572. #else
  573. static void free_move_list(d)
  574.      depl * d;
  575. #endif
  576. {  
  577.  
  578.   if (d->next != (depl *) NULL) {
  579.     free_move_list(d->next);
  580.     free(d->next);
  581.     d->next = (depl *) NULL;
  582.   }
  583.   if (d->sub != (depl *) NULL) {
  584.     free_move_list(d->sub);
  585.     free(d->sub);
  586.     d->sub = (depl *) NULL;
  587.   }
  588. }
  589.   
  590. /* this procedure undo the effect of move m on the board g */
  591. #ifdef __STDC__
  592. static void undo_move(game *g,depl *m)
  593. #else
  594. static void undo_move(g,m)
  595.      game *g;
  596.      depl *m;
  597. #endif
  598. {
  599.   int lig;
  600.   if (m->whiteturn)
  601.     lig = 1;
  602.   else 
  603.     lig = 8;
  604.   switch (m->type) {
  605.   case MOVE:
  606.     clsboard(g,m->tolig,m->tocol) ;
  607.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  608.     break;
  609.   case PRISE:
  610.     setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
  611.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  612.     break;
  613.   case GRANDROQUE:
  614.     clsboard(g,lig,3) ;
  615.     clsboard(g,lig,3) ;
  616.     setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
  617.     setboard(g,m->fromlig,5,ROOK,CURCOLOR(m)) ;
  618.     break;
  619.   case PETITROQUE:
  620.     clsboard(g,lig,6) ;
  621.     clsboard(g,lig,7) ;
  622.     setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
  623.     setboard(g,m->fromlig,8,ROOK,CURCOLOR(m)) ;
  624.     break;
  625.   case EN_PASSANT:
  626.     clsboard(g,m->tolig,m->tocol) ;
  627.     setboard(g,m->tolig,m->fromcol,PAWN,OPPCOLOR(m)) ;
  628.  
  629.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  630.     break;
  631.   case PROMOTION:
  632.     clsboard(g,m->tolig,m->tocol);
  633.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  634.     break;
  635.   case PROM_ET_PRISE:
  636.     setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
  637.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  638.     break;
  639.   default:
  640.     fprintf(stderr,"unable to undo move: unknown move type\n");
  641.     break;
  642.   }
  643. }
  644.  
  645. /* variation procedures == stack manipulation */
  646.  
  647. #ifdef __STDC__
  648. void enter_variation(void)
  649. #else
  650. void enter_variation()
  651. #endif
  652. {
  653.   int l;
  654.  
  655.   l = dr->variation ;
  656.   
  657.   if (l >= VARIATION_MAX) {
  658.     error((stderr,"Maximum imbricated variation is %d",VARIATION_MAX));
  659.   } else {
  660.     /* save current line/variation */
  661.     stack[l].d = m;
  662.     stack[l].b = tos;
  663.     stack[l].d1 = dr->iswhiteturn;
  664.     stack[l].d2 = dr->interrupt = TRUE ;    
  665.     /* create new */
  666.     tos = new_board();
  667.     (void) copy_board(stack[l].b, tos);
  668.  
  669.     /* A variation FOLLOWS the main line 
  670.        so we need to backtrack one move
  671.        */
  672.     m = add_variation(stack[l].d);
  673.     undo_move(tos,stack[l].d);
  674.  
  675.     /* set variables */
  676.     l++;
  677.     dr->variation = l;
  678.  
  679.     output_variation(dr,VARIATION_IN);
  680.   }
  681. }
  682.  
  683. #ifdef __STDC__
  684. void exit_variation(void)
  685. #else
  686. void exit_variation()
  687. #endif
  688. {
  689.   int l ;
  690.  
  691.   l = dr->variation ;
  692.   
  693.   if (l == 0) {
  694.     error((stderr,"You cannot exit from the main line (variation error?)"));
  695.   } else {
  696.     output_variation(dr,VARIATION_OUT);
  697.  
  698.     l--;
  699.     free(tos);
  700.     free(m);
  701.     m = stack[l].d ;
  702.     tos = stack[l].b ;
  703.  
  704.     dr->iswhiteturn = stack[l].d1 ;
  705.     dr->interrupt = stack[l].d2 ;
  706.     dr->variation = l;
  707.   }
  708. }
  709.  
  710. /* ----------- semantic evaluation of move ----------- */
  711. /* check if  position lies within the board
  712.    */
  713. #ifdef __STDC__
  714. int in_board(int l,int c)
  715. #else
  716. int in_board(l,c)
  717.      int l,c;
  718. #endif
  719. {
  720.   return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
  721. }
  722.  
  723. /* check that the path from pos1 to pos2 is free
  724.    */
  725. #ifdef __STDC__
  726. int path_free(int l1,int c1,int l2,int c2)
  727. #else
  728. int path_free(l1, c1, l2, c2)
  729. int l1,c1, l2, c2;
  730. #endif
  731. {
  732.   int li = 1 ;
  733.   int ci = 1 ;
  734.   int lig, col;
  735.  
  736.  
  737.   li = SIGN(l2-l1);
  738.   ci = SIGN(c2-c1);
  739.  
  740.  
  741.   if ( c1 == c2 ) {    
  742.     col = c1;
  743.     for (lig = l1 +li; lig != l2 ; lig +=li)
  744.       if (tos->board[lig][col] != VOID)
  745.     return (FALSE);
  746.     return(TRUE);
  747.   }
  748.  
  749.   if ( l1 == l2) {
  750.     lig = l1 ;
  751.     for (col = c1 + ci; col != c2 ; col +=ci)
  752.       if (tos->board[lig][col] != VOID)
  753.     return (FALSE);
  754.     return(TRUE);
  755.   }
  756.  
  757.   for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
  758.     if (tos->board[lig][col] != VOID) {
  759.       return (FALSE);
  760.     }
  761.   return(TRUE);
  762. }
  763.  
  764. /* check roque is possible */
  765. #ifdef __STDC__
  766. int check_roque(void)
  767. #else
  768. int check_roque()
  769. #endif
  770. {
  771.   int lig, col ;
  772.  
  773.   if (m->whiteturn)
  774.     lig = 1 ;
  775.   else
  776.     lig =8;
  777.   if (m->type == GRANDROQUE)
  778.     for (col = 2; col < 5 ; col++)
  779.       if (tos->board[lig][col] != VOID)
  780.     return(FALSE);
  781.   if (m->type == PETITROQUE)
  782.     for (col = 6; col < 7 ; col++)
  783.       if (tos->board[lig][col] != VOID)
  784.     return(FALSE);
  785.   return(TRUE);
  786. }
  787.   
  788. /* check -- or guess -- where a given piece come */
  789. #ifdef __STDC__
  790. int guess_piece(void) 
  791. #else
  792. int guess_piece() 
  793. #endif
  794. {
  795.   return(tos->board[m->fromlig][m->fromcol]); 
  796. }
  797.  
  798. /* try to guess the move -- low-level function */
  799. #ifdef __STDC__
  800. int guess_depl(int nb, int tab[][2],
  801.            int * pl1, int * pc1, int l2, int c2, int path)
  802. #else
  803. int guess_depl(nb, tab, pl1, pc1, l2,c2,path)
  804.      int nb;
  805.      int tab[][2];
  806.      int *pl1, *pc1;
  807.      int l2,c2;
  808.      int path;
  809. #endif
  810. {
  811.   int i;
  812.   int c,l;
  813.  
  814.   for (i=0; i< nb; i++ ) {
  815.     l = l2 - tab[i][0];
  816.     c = c2 - tab[i][1];
  817.     if (in_board(l,c))
  818.       if ((tos->board[l][c] == m->piece) &&
  819.       (tos->color[l][c] == CURCOLOR(m)) &&
  820.       ( !path || (path && path_free(l,c, l2, c2))) &&
  821.       ( ((*pl1) == 0) || ((*pl1) == l) ) &&
  822.       ( ((*pc1) == 0) || ((*pc1) == c) ) )
  823.       {
  824.     *pl1 = l;
  825.     *pc1 = c;
  826.     return(TRUE);
  827.       }
  828.   }
  829.   return(FALSE);
  830. }
  831.  
  832. /* check for ambiguitey in a move
  833.    used in ouptut function: the piece had beenm already moved and
  834.    if we guess another move, there is an ambiguity
  835.    */
  836. #ifdef __STDC__
  837. int ambiguity(int frompiece, int l2, int c2)
  838. #else
  839. int ambiguity(frompiece, l2, c2)
  840.      int frompiece, l2, c2 ;
  841. #endif
  842. {
  843.   int l1 = 0 ;
  844.   int c1 = 0 ;
  845.  
  846.   switch(frompiece) {
  847.   case PAWN:
  848.     if (m->type == PRISE) {
  849.       if (m->whiteturn)
  850.     return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE));
  851.       else
  852.     return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE));
  853.    } else {
  854.       if (m->whiteturn)
  855.     return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd, 
  856.               &l1,&c1, l2,c2, FALSE));
  857.       else
  858.     return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd, 
  859.               &l1,&c1, l2,c2, FALSE));
  860.     }
  861.     /* break; */
  862.   case KNIGHT:
  863.     return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  864.     /* break; */
  865.   case BISHOP:
  866.     return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  867.     /* break; */
  868.   case ROOK:
  869.     return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  870.     /* break; */
  871.   case QUEEN:
  872.     return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  873.     /* break; */
  874.   case KING:
  875.     return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  876.     /* break; */
  877.   default:
  878.     break;
  879.   }
  880.   return(TRUE);
  881. }
  882.  
  883. #ifdef __STDC__
  884. int check_move(depl *m)
  885. #else
  886. int check_move(m)
  887.      depl * m;
  888. #endif
  889. {
  890.   int l1,c1,l2,c2;
  891.   int tmp; /* tmp boolean */
  892.  
  893.   l1 = m->fromlig;
  894.   c1 = m->fromcol;
  895.   l2 = m->tolig;
  896.   c2 = m->tocol;
  897.  
  898.   if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  899.     return(check_roque());
  900.  
  901.   if ((tos->board[l1][c1] != m->piece)||
  902.       (tos->color[l1][c1] != CURCOLOR(m))){
  903.     fprintf(stderr,"hum... piece should be %d \n",tos->board[l1][c1]);
  904.     error ((stderr,": from position and piece not coherent at move (%d,%d)\n",
  905.         m->move,m->whiteturn));
  906.     return(FALSE);
  907.   }
  908.  
  909.   /* if prise === FALSE, we must not take a piece */
  910.   if (tos->board[l2][c2] != VOID 
  911.       && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
  912.     (void) fprintf(stderr,"catching not indicated at move %d\n",m->move);
  913.     return(FALSE);
  914.   }
  915.  
  916.   /* prendre une de ses propres pieces */
  917.   if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
  918.     (void) fprintf(stderr,"attempt to catch same color piece at move %d\n",
  919.            m->move);
  920.     return(FALSE);
  921.   }
  922.  
  923.   /* we check if the move is a possible one for the piece
  924.      */
  925.  
  926.   switch(m->piece) {
  927.   case PAWN:
  928.     if (m->prise) {
  929.       if (m->whiteturn)
  930.     tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  931.       else
  932.     tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  933.    } else {
  934.       if (m->whiteturn)
  935.     tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
  936.       else
  937.     tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
  938.     }
  939.     /* is it a "prise en passant " */
  940.     if ((c1 != c2) && (tos->board[l2][c2] == VOID)
  941.     && (tos->board[l1][c2] == PAWN)) {
  942.       m->type = EN_PASSANT ;
  943.       /* we must perform here the "en passant" test */
  944.       tos->board[l1][c2] = VOID ;
  945.       tos->color[l1][c2] = VOID ;
  946.       tmp = TRUE;
  947.     }
  948.     return(tmp);
  949.     /* break; */
  950.   case KNIGHT:
  951.     return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  952.     /* break; */
  953.   case BISHOP:
  954.     return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  955.     /* break; */
  956.   case ROOK:
  957.     return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  958.     /* break; */
  959.   case QUEEN:
  960.     return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  961.     /* break; */
  962.   case KING:
  963.     return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  964.     /* break; */
  965.   default:
  966.     break;
  967.   }
  968.  
  969.   return(TRUE);
  970. }
  971.  
  972. /* try to guess the move -- used for shortened notation
  973.    */
  974. #ifdef __STDC__
  975. int guess_move(void)
  976. #else
  977. int guess_move()
  978. #endif
  979. {
  980.   int l1,c1,l2,c2;
  981.  
  982.   if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  983.     return(TRUE);
  984.  
  985.   l1 = m->fromlig ;
  986.   c1 = m->fromcol ;
  987.   l2 = m->tolig;
  988.   c2 = m->tocol;
  989.  
  990.   switch(m->piece) {
  991.   case PAWN:
  992.     if (m->prise) {
  993.       if (m->whiteturn)
  994.     (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  995.       else
  996.     (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  997.     } else {
  998.       if (m->whiteturn)
  999.     (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); 
  1000.       else
  1001.     (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); 
  1002.     }
  1003.     break;
  1004.   case KNIGHT:
  1005.     (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
  1006.     break;
  1007.   case BISHOP:
  1008.     (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
  1009.     break;
  1010.   case ROOK:
  1011.     (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
  1012.     break;
  1013.   case QUEEN:
  1014.     (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
  1015.     break;
  1016.   case KING:
  1017.     (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
  1018.     break;
  1019.   default:
  1020.     break;
  1021.   }
  1022.  
  1023.   if ((l1 == 0) || (c1 == 0)) {
  1024.     if (m->whiteturn)
  1025.       error((stderr,"unable to guess move %d white, with piece %d\n",
  1026.          m->move,m->piece));
  1027.     else
  1028.       error((stderr,"unable to guess move %d black, with piece %d\n",
  1029.          m->move,m->piece));
  1030.     return(FALSE);
  1031.   } else {
  1032.     m->fromcol = c1;
  1033.     m->fromlig = l1;
  1034.     return(TRUE);
  1035.   }
  1036. }
  1037.  
  1038. /* --------------- execution of move ----------------- */
  1039.  
  1040. /* clear a position */
  1041. #ifdef __STDC__
  1042. int clear_pos(int lig, int col)
  1043. #else
  1044. int clear_pos(lig,col)
  1045.      int lig;
  1046.      int col;
  1047. #endif
  1048. {
  1049.   tos->board[lig][col] = VOID ;
  1050.   tos->color[lig][col] = VOID ;
  1051.   return(TRUE);
  1052. }
  1053.  
  1054. /* configure the board */
  1055. #ifdef __STDC__
  1056. int configure(void)
  1057. #else
  1058. int configure()
  1059. #endif
  1060. {
  1061.   if (configuring) {
  1062.     if (m->piece == VOID)
  1063.       m->piece = PAWN ;
  1064.     tos->board[m->tolig][m->tocol] = m->piece ;
  1065.     tos->color[m->tolig][m->tocol] = configside ;
  1066.   }
  1067.   return(TRUE);
  1068. }
  1069.  
  1070. /* execute a move, no checking */
  1071. #ifdef __STDC__
  1072. int execute_move(void)
  1073. #else
  1074. int execute_move()
  1075. #endif
  1076. {
  1077.   register int i;
  1078.  
  1079.   if (m->piece == VOID )
  1080.     m->piece = PAWN;
  1081.  
  1082.   if ((m->fromlig == 0) || (m->fromcol == 0))
  1083.     (void) guess_move();
  1084.   
  1085.   /* supply to the -- maybe -- deficiency of input notation
  1086.      */
  1087.   if ((m->fromlig !=0) || (m->fromcol != 0))
  1088.     m->piece = tos->board[m->fromlig][m->fromcol];
  1089.  
  1090.   if (tos->board[m->tolig][m->tocol] != VOID) {
  1091.     m->type = PRISE;
  1092.     m->prise = tos->board[m->tolig][m->tocol] ;
  1093.   }
  1094.  
  1095.   if (!check_move(m)) {
  1096.     if (m->whiteturn)
  1097.       error((stderr,"white move %d illegal\n",m->move));
  1098.     else
  1099.       error((stderr,"black move %d illegal\n",m->move));
  1100.   }
  1101.  
  1102.   if (m->type == PETITROQUE) {
  1103.     if (m->whiteturn)
  1104.       curlig = 1 ;
  1105.     else
  1106.       curlig = 8 ;
  1107.     tos->board[curlig][7] = KING;
  1108.     tos->board[curlig][6] = ROOK;
  1109.     tos->color[curlig][7] = tos->color[curlig][5] ;
  1110.     tos->color[curlig][6] = tos->color[curlig][5] ;
  1111.     (void) clear_pos(curlig, 5);
  1112.     (void) clear_pos(curlig, 8);
  1113.   }
  1114.   if (m->type == GRANDROQUE) {
  1115.     if (m->whiteturn)
  1116.       curlig = 1 ;
  1117.     else
  1118.       curlig = 8 ;
  1119.     tos->board[curlig][3] = KING;
  1120.     tos->board[curlig][4] = ROOK;
  1121.     tos->color[curlig][3] = tos->color[curlig][5] ;
  1122.     tos->color[curlig][4] = tos->color[curlig][5] ;
  1123.     (void) clear_pos(curlig, 5);
  1124.     (void) clear_pos(curlig, 1);
  1125.   }
  1126.  
  1127.         
  1128.   if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) {
  1129.     if (m->piece == VOID)
  1130.       m->piece = tos->board[m->fromlig][m->fromcol];
  1131.     /*if (m->topiece == VOID)
  1132.       m->topiece = tos->board[m->fromlig][m->fromcol];*/
  1133.     tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol];
  1134.     tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol];
  1135.     (void) clear_pos(m->fromlig,m->fromcol);
  1136.   }
  1137.   
  1138.   if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE))
  1139.     tos->board[m->tolig][m->tocol] = m->promotion ;
  1140.      
  1141.   output_move(dr,m);
  1142.  
  1143.   if (error_flag) {
  1144.     (void) fprintf(dr->outfile, "\nlast position encountered:\n");
  1145.     output_board(dr,tos);
  1146.     close_files();
  1147.     exit(0);
  1148.   }
  1149.  
  1150.   /* do we need to display the move ? */
  1151.   if (nb_move_to_dsp > 0) {
  1152.     for (i=0; i < nb_move_to_dsp; i++)
  1153.       if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
  1154.     output_board(dr,tos);
  1155.     if (stop_at_display) {
  1156.       output_end(dr);
  1157.       close_files();
  1158.       exit(0);
  1159.     }
  1160.       }
  1161.   }
  1162.  
  1163.   return(TRUE);
  1164. }
  1165.  
  1166. /* ------------------ automata ----------------------- */
  1167.  
  1168. /* categorise the input for the automata */
  1169. #ifdef __STDC__
  1170. int typechar(char c)
  1171. #else
  1172. int typechar(c)
  1173.      char c;
  1174. #endif
  1175. {
  1176.   if (ispiece(c))
  1177.     return(0);
  1178.   if ((c >=  'a') && ( c <= 'h'))
  1179.     return(1);
  1180.   if ((c >=  '1') && ( c <= '8'))
  1181.     return(2);
  1182.   if ( c== '-' )
  1183.     return(3);
  1184.   if ((c == 'x') || (c == 'X' ))
  1185.     return(4);
  1186.   if (c == '=' )
  1187.     return(5);
  1188.   if (c == '\0' )
  1189.     return(6);
  1190.   return(7);
  1191. }
  1192.  
  1193.  
  1194. /* execute the actions decided by the automata */
  1195. #ifdef __STDC__
  1196. int execute(int num,char c)
  1197. #else
  1198. int execute(num,c)
  1199.      int num;
  1200.      char c;
  1201. #endif
  1202. {
  1203.   switch (num) {
  1204.   case 1: /* set cur piece */
  1205.     curpiece = piece(c);
  1206.     break;
  1207.   case 2: /* set cur col */
  1208.     curcol = lettertocol(c);
  1209.     break;
  1210.   case 3: /* set cur lig */
  1211.     curlig = lettertolig(c);
  1212.     break;
  1213.   case 4: /* from = cur ; prise = false */
  1214.     m->piece = curpiece ;
  1215.     m->fromcol = curcol ;
  1216.     m->fromlig = curlig;
  1217.     /*m->topiece = curpiece;*/
  1218.     break;
  1219.   case 5: /* from = cur ; prise = true */
  1220.     m->piece = curpiece ;
  1221.     m->fromcol = curcol ;
  1222.     m->fromlig = curlig;
  1223.     m->type = PRISE ;
  1224.     m->prise = curpiece;
  1225.     break;
  1226.   case 6: /* to = cur ; guess from */
  1227.   case 7: /* to = cur ; guess from ; parse remaining token */
  1228.     m->piece = curpiece ;
  1229.     m->tocol = curcol;
  1230.     m->tolig = curlig ;
  1231.  
  1232.     /*m->topiece = curpiece ; /* ? */
  1233.  
  1234.     if (configuring)
  1235.       (void) configure();
  1236.     else {
  1237.       (void) execute_move();
  1238.     }
  1239.     break;
  1240.   case 8: /* to = cur */
  1241.   case 9: /* to = cur */
  1242.     m->tocol = curcol;
  1243.     m->tolig = curlig ;
  1244.  
  1245.     if (configuring)
  1246.       (void) configure();
  1247.     else {
  1248.       (void) execute_move();
  1249.     }
  1250.     break;
  1251.   case 10: /* piece = cur piece ; prise = true */
  1252.     /* later : guess from position */
  1253.     m->piece = curpiece ;
  1254.     m->type = PRISE ;
  1255.     break;
  1256.   case 11: /* grand roque */
  1257.   case 12: /* petit roque */
  1258.     (void) execute_move();
  1259.     break;
  1260.   case 13: /* case of simpliest algebraic notation ;
  1261.           only e2e4 : this is the transition from e2 to e4
  1262.           also the case of move such as Nge2
  1263.           from =cur; prise = FALSE;
  1264.           also:
  1265.           curcol = ...
  1266.           */
  1267.     m->piece = curpiece ;
  1268.     m->fromcol = curcol ;
  1269.     m->fromlig = curlig;
  1270.  
  1271.     m->type = MOVE;
  1272.     curcol = lettertocol(c);
  1273.   case 14: /* promotion, the "=" */
  1274.     break;
  1275.   case 15: /* promotion, the piece name */
  1276.     /* to = cur ; guess from */
  1277.   case 16: 
  1278.     /* to = cur */
  1279.  
  1280.     m->tocol = curcol;
  1281.     m->tolig = curlig ;
  1282.     /*m->topiece = curpiece ;*/
  1283.  
  1284.     if (m->type == PRISE )
  1285.       m->type = PROM_ET_PRISE ;
  1286.     else
  1287.       m->type = PROMOTION ;
  1288.     m->promotion = curpiece = piece(c) ;
  1289.  
  1290.     break;
  1291.   case 17: /* execute move for promotion */
  1292.     (void) execute_move();
  1293.     break;
  1294.   case -1:
  1295.     break;
  1296.   default:
  1297.     break;
  1298.   }
  1299.   return(TRUE);
  1300. }
  1301.  
  1302. #ifdef __STDC__
  1303. int parse_number(char *token)
  1304. #else
  1305. int parse_number(token)
  1306.      char *token;
  1307. #endif
  1308. {
  1309.   int curmove = 0 ;
  1310.   int i;
  1311.  
  1312.   /* check coherency with internal numbering */
  1313.   i = 0;
  1314.   while (isdigit(token[i])) {
  1315.    curmove = curmove * 10 +  ((int) token[i++] - (int) '0' );
  1316.   }
  1317.   movecount = curmove ;
  1318.   return(TRUE);
  1319. }
  1320.  
  1321. #ifdef __STDC__
  1322. int parse_text(char *text)
  1323. #else
  1324. int parse_text(text)
  1325.      char *text;
  1326. #endif
  1327. {
  1328.   output_text(dr,T_TEXT, text, 0);
  1329.   return(TRUE);
  1330. }
  1331.  
  1332. #ifdef __STDC__
  1333. int parse_comment(char *com)
  1334. #else
  1335. int parse_comment(com)
  1336.      char *com;
  1337. #endif
  1338. {
  1339.   int t;
  1340.  
  1341.   if (com[0] == '$')
  1342.     /* we look in the long ascii table */
  1343.     t = find_keyword(com_long, NUM_COM_CODE, NUM_COM_CODE, com, TRUE);
  1344.   else {
  1345.     /* we look for the comment in the short ascii table */
  1346.     t = find_keyword(com_short, NUM_COM_CODE, NUM_COM_CODE, com,FALSE);
  1347.     if (t == NUM_COM_CODE)
  1348.       fprintf (stderr,"\nWhat is \"%s\" ?\n",com);   
  1349.   }
  1350.   if (t != NUM_COM_CODE)
  1351.     output_text(dr,T_COMMENT, com, t);
  1352.   return(TRUE);
  1353. }
  1354.  
  1355. #ifdef __STDC__
  1356. int parse_keyword(char *token, char *text)
  1357. #else
  1358. int parse_keyword(token,text)
  1359.      char *token;
  1360.      char *text;
  1361. #endif
  1362. {
  1363.   char c;
  1364.  
  1365.   switch (find_keyword(keywords, NBKEYWORD, KNULL, token, TRUE)) {
  1366.   case START:
  1367.     /* don't forget we are configuring the previous move */
  1368.     /* -> move 0, black */
  1369.     configuring = FALSE;
  1370.     m->move = 0;
  1371.     m->whiteturn = FALSE;
  1372.     break;
  1373.   case CLEAR:
  1374.     clear_board(tos);
  1375.     m= theplay->chain;
  1376.     free_move_list(m);
  1377.     break;
  1378.   case SHOWBOARD:
  1379.     output_board(dr,tos);
  1380.     break;
  1381.   case TOWHITE:
  1382.     /* don't forget we are configuring the previous move */
  1383.     /* reset to 0,black --> 1,white */
  1384.     m->move = 0;
  1385.     m->whiteturn = FALSE;
  1386.     break;
  1387.   case TOBLACK:
  1388.     /* reset to 1,white -> 1 black */
  1389.     m->move = 1;
  1390.     m->whiteturn = TRUE;
  1391.     break;
  1392.   case CONFIGWH:
  1393.     configuring = TRUE ;
  1394.     configside = WHITE;
  1395.     m= theplay->chain;
  1396.     free_move_list(m);
  1397.     break;
  1398.   case CONFIGBL:
  1399.     configuring = TRUE ;
  1400.     configside = BLACK;
  1401.     m= theplay->chain;
  1402.     free_move_list(m);
  1403.     break;
  1404.   case DEFAULTP:
  1405.     init_board(tos);
  1406.     m= theplay->chain;
  1407.     free_move_list(m);
  1408.     break;
  1409.   case TITLE:
  1410.     output_text(dr, T_TITLE, text, NULL);
  1411.     break;
  1412.   case SUBTITLE:
  1413.     output_text(dr, T_SUBTITLE, text, NULL);
  1414.     break;
  1415.   case SCORE:
  1416.     output_text(dr, T_SCORE, text, NULL);
  1417.     break;
  1418.   case LANGUE:
  1419.     in_language = find_keyword (t_language, NBLANGUAGES, in_language,
  1420.                    text,TRUE);
  1421.     associe_traduction( &in_table, in_language);           
  1422.     break;
  1423.   case SPECIAL: /* all input, up to \n is copied to output */
  1424.     while ((( c = getc(infile)) != EOF) && (c != '\n'))
  1425.       (void) putc (c,dr->outfile);
  1426.     putc ('\n', dr->outfile);
  1427.     break;
  1428.   case KNULL:
  1429.   default:
  1430.     fprintf(stderr,"unknown keyword %s\n",token);
  1431.     break;
  1432.   }
  1433.   return(TRUE);
  1434. }
  1435.  
  1436. #ifdef __STDC__
  1437. int parse_roque(char *token)
  1438. #else
  1439. int parse_roque(token)
  1440.      char * token;
  1441. #endif
  1442.   int i;
  1443.  
  1444.   for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
  1445.   if ( i < NBROQUE ) {
  1446.     
  1447.     m = add_trailing_move(m);
  1448.     init_parse(m);
  1449.  
  1450.     if (strlen(token) == 3) {
  1451.       m->type = PETITROQUE ;
  1452.       (void) execute(12,DUMMYCHAR);
  1453.     } else {
  1454.       m->type = GRANDROQUE ;
  1455.       (void) execute(11,DUMMYCHAR);
  1456.     }
  1457.     /*(void) fprintf(stderr,"ROQUE\n");*/
  1458.     return(TRUE);
  1459.   }
  1460.  
  1461.   return(FALSE);
  1462. }
  1463.  
  1464. #ifdef __STDC__
  1465. int  parse_move(char *token)
  1466. #else
  1467. int  parse_move(token)
  1468.      char *token;
  1469. #endif
  1470. {
  1471.   register int i;
  1472.   int correcte = FALSE ;
  1473.   int erreursyntaxe = FALSE ;
  1474.   int etat =0;
  1475.   int code;
  1476.   
  1477.   m = add_trailing_move(m);
  1478.   init_parse(m);
  1479.   m->type = MOVE;
  1480.  
  1481.   i=0;
  1482.   while ( !correcte && !erreursyntaxe ) {
  1483.     code = typechar(token[i]);
  1484.     (void) execute(action[etat][code],token[i]);
  1485.     etat = transit[etat][code] ;
  1486.     if (etat == -1) 
  1487.       erreursyntaxe = TRUE;
  1488.     if (etat == FINAL)
  1489.       correcte = TRUE ;
  1490.     i++;
  1491.   }
  1492.   if (erreursyntaxe) {
  1493.     (void) fprintf(stderr, "no comprende, senor: %s\n",token);
  1494.     return(FALSE);
  1495.   }
  1496.   if (correcte) {
  1497.     /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
  1498.   }
  1499.   /*init_parse(m);*/
  1500.   return(TRUE);
  1501. }
  1502.  
  1503. #ifdef __STDC__
  1504. void init_parse(depl *m)
  1505. #else
  1506. void init_parse(m)
  1507.      depl * m ;
  1508. #endif
  1509. {
  1510.  
  1511.   /* global position and piece variable initialised to 0
  1512.      */
  1513.   /* move and whiteturn unchanged */ 
  1514.  
  1515.   m->type = MOVE ;
  1516.  
  1517.   curpiece = m->piece = VOID ;
  1518.   curcol = m->tocol = m->fromcol = 0;
  1519.   curlig = m->tolig = m->fromlig = 0;
  1520.  
  1521.   m->promotion = VOID;
  1522.   m->prise = VOID;
  1523.   m->is_check = FALSE ;
  1524.  
  1525.   curdigit = curmove = 0;
  1526.  
  1527.   /*if (movecount != m->move)
  1528.     (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
  1529.            m->move, movecount);*/
  1530.  
  1531. }
  1532.  
  1533. /* ------------------- top routines -------------------- */
  1534.  
  1535. /* cette fonction analyse les arguments de la ligne de commande
  1536.    */
  1537. #ifdef __STDC__
  1538. int parse_options(int argc,char *argv[])
  1539. #else
  1540. int parse_options(argc,argv)
  1541.      int argc;
  1542.      char * argv[];
  1543. #endif
  1544. {
  1545.   int narg =1 ;
  1546.   int i;
  1547.   register int c;
  1548.   char cp[132];
  1549.   char chaine[MAXTOKLEN];
  1550.  
  1551.   infile = stdin;
  1552.   dr->outfile = stdout;
  1553.   nb_move_to_dsp = 0;
  1554.  
  1555.   while (narg < argc ) {
  1556.     (void) strcpy (cp,argv[narg]);
  1557.     switch (cp[0]) {
  1558.     case '-' :
  1559.       switch (cp[1]) {
  1560.       case 'f' : /* from langage */
  1561.     if  ((narg+1) >= argc )
  1562.       fatal((stderr,"missing argument to %s option",cp));
  1563.     narg++ ;
  1564.     in_language = find_keyword (t_language, NBLANGUAGES,
  1565.                     DEFAULT_INPUT_LANGUAGE,
  1566.                     argv[narg],TRUE);
  1567.     break;
  1568.       case 't' : /* to langage */
  1569.     if  ((narg+1) >= argc )
  1570.       fatal((stderr,"missing argument to %s option",cp));
  1571.     narg++ ;
  1572.     out_language = find_keyword (t_language, NBLANGUAGES,
  1573.                      DEFAULT_OUTPUT_LANGUAGE,
  1574.                      argv[narg],TRUE);
  1575.     break;
  1576.       case 'o' : /* next arg is output file */
  1577.     narg++ ;
  1578.     if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
  1579.       (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
  1580.       (void) fprintf (stderr,"assume stdout for output\n");
  1581.     }
  1582.     break;
  1583.       case 'e':
  1584.     if  ((narg+1) >= argc )
  1585.       fatal((stderr,"missing argument to %s option",cp));
  1586.     narg++ ;
  1587.  
  1588.     i=0;
  1589.     nb_move_to_dsp = 0;
  1590.     move_to_display[nb_move_to_dsp] = 0;
  1591.     while (isdigit(argv[narg][i])) {
  1592.       move_to_display[nb_move_to_dsp] =
  1593.         ((int) argv[narg][i] - (int) '0')
  1594.           + move_to_display[nb_move_to_dsp] * 10;
  1595.       i++;
  1596.     }
  1597.     nb_move_to_dsp++;
  1598.     stop_at_display = TRUE;
  1599.     break;
  1600.       case 'c':
  1601.     if  ((narg+1) >= argc )
  1602.       fatal((stderr,"missing argument to %s option",cp));
  1603.     narg++ ;
  1604.  
  1605.     i=0;
  1606.     while (isdigit(argv[narg][i])) {
  1607.       move_to_display[nb_move_to_dsp] = 0;
  1608.       while (isdigit(argv[narg][i])) {
  1609.         move_to_display[nb_move_to_dsp] =
  1610.           ((int) argv[narg][i] - (int) '0')
  1611.           + move_to_display[nb_move_to_dsp] * 10;
  1612.         i++;
  1613.       }
  1614.       nb_move_to_dsp++;
  1615.  
  1616.       if (nb_move_to_dsp > NB_MOVE_TO_DISP)
  1617.         fatal((stderr,"max. number of move to display exceeded"));
  1618.  
  1619.       /* process next number */
  1620.       if (argv[narg][i] == ',')
  1621.         i++;
  1622.     }
  1623.     break;
  1624.       case 'a': /* algebraic output */
  1625.     dr->output_move_format = ALGEBRAIC;
  1626.     break;
  1627.       case 's':  /* shortened output */
  1628.     dr->output_move_format = SHORTENED;
  1629.     break;
  1630.       case 'b': /* display only the board, no move */
  1631.     dr->only_board = TRUE;
  1632.     break;
  1633.       case 'd': /* output driver */
  1634.     if  ((narg+1) >= argc )
  1635.       fatal((stderr,"missing argument to %s option",cp));
  1636.     narg++ ;
  1637.     driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
  1638.                   argv[narg],TRUE);
  1639.     break;
  1640.       case 'i': /* no headers */
  1641.     dr->print_headers = FALSE;
  1642.     break;
  1643.       case 'v': /* print version */
  1644.     /* this already done, so exit() */
  1645.     exit(0);
  1646.     break;
  1647.       case 'h': /* help file */
  1648.     (void) strcpy(chaine,LIB_DIR);
  1649.         if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
  1650.           fatal((stderr,"Can't find help file.\n"));
  1651.         else {
  1652.           while ((c = getc(fhelp)) != EOF)
  1653.             (void) fputc(c,stderr);
  1654.           (void) fclose(fhelp);
  1655.       exit(0);
  1656.         }
  1657.          break;
  1658.       default:
  1659.     error((stderr,"unknown command line options %s\n",cp));
  1660.     break;
  1661.       }
  1662.       break;
  1663.     default: /* assume this is the input file */
  1664.       if ((infile = fopen (cp,"r")) == NULL)
  1665.     fatal((stderr,"can't open %s input file\n",cp));
  1666.     }
  1667.     narg++;
  1668.   } /* process next arg */
  1669.   return(argc);
  1670. }
  1671.  
  1672. #ifdef __STDC__
  1673. void close_files(void)
  1674. #else
  1675. void close_files()
  1676. #endif
  1677. {
  1678.   if (!((infile == stdin)||(infile == NULL)))
  1679.     (void) fclose(infile);
  1680.   if (dr->outfile != stdout )
  1681.     (void) fclose(dr->outfile);
  1682. }
  1683.  
  1684. #ifdef __STDC__
  1685. int associe_traduction (char **table, int language)
  1686. #else
  1687. int associe_traduction (table, language)
  1688. char ** table;
  1689. int language ;
  1690. #endif
  1691. {
  1692.   if (language < 0 || (language >= NBLANGUAGES))
  1693.     error((stderr,"unknown language\n"));
  1694.   else
  1695.     *table = c_language[language];
  1696.   return(language);
  1697. }
  1698.  
  1699. #ifdef __STDC__
  1700. static void print_all_play(play *p)
  1701. #else
  1702. static void print_all_play(p)
  1703. play *p;
  1704. #endif
  1705.   depl *d;
  1706.   d = p->chain;
  1707.   while (d->next != NULL){
  1708.     d = d->next;
  1709.     output_move(dr,d);
  1710.   }
  1711. }
  1712.  
  1713. /* ------------- main --------------------- */
  1714.  
  1715. #ifdef __STDC__
  1716. void main(int argc,char *argv[])
  1717. #else
  1718. int main(argc,argv)
  1719.      int argc;
  1720.      char * argv[];
  1721. #endif
  1722. {
  1723.   (void) fprintf(stderr,"%s\n",version_string);
  1724.   
  1725.   /* allocation of driver descriptor */
  1726.   dr = new_driver();
  1727.  
  1728.   /* default configuration */
  1729.   init_driver(dr,DEFAULT_DRIVER);
  1730.   (void) associe_traduction(&in_table,  DEFAULT_INPUT_LANGUAGE );
  1731.   (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
  1732.  
  1733.   (void) parse_options(argc,argv);
  1734.  
  1735.   (void) associe_traduction (&in_table, in_language);
  1736.   (void) associe_traduction (&(dr->out_table), out_language);
  1737.  
  1738.   /* assoc driver */
  1739.   init_driver(dr,driver);
  1740.  
  1741.   configuring = FALSE;
  1742.   configside = VOID;
  1743.  
  1744.   /* initialise output file */
  1745.   output_init(dr);
  1746.  
  1747.   if (error_flag)
  1748.     fatal((stderr,"too many errors"));
  1749.  
  1750.   /* allocation of board descriptor */
  1751.   tos = new_board();
  1752.   init_board(tos);
  1753.  
  1754.   /* allocation of move descriptor */
  1755.   m = new_move();
  1756.   m->type = VOID ;
  1757.   /*init_move(m);*/
  1758.   
  1759.   /* allocation of the play descriptor */
  1760.   theplay = (play *) malloc (sizeof(play)) ;
  1761.   theplay->initial = tos ;
  1762.   theplay->chain   = m ;
  1763.   movecount = 1;
  1764.  
  1765.   /* main analysis routine */
  1766.   yyin = infile ;
  1767.   yyout = stderr ;
  1768.  
  1769.   /*init_parse(m); */
  1770.   yylex();
  1771.  
  1772.   if ((count == 0) && !error_flag)
  1773.     output_board(dr,tos);
  1774.  
  1775.   if (error_flag) {
  1776.     error((stderr,"last valid position:\n"));
  1777.     output_board(dr,tos);
  1778.     fatal((stderr,"too many errors"));
  1779.   }
  1780.       
  1781.   /* terminates output files */
  1782.   output_end(dr);
  1783.  
  1784.   /* close files */
  1785.   close_files();
  1786.  
  1787.   /* exit properly */
  1788. #ifdef __STDC__
  1789. #else
  1790.   exit(0);
  1791. #endif
  1792. }
  1793.