home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / notation / part01 / notation.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  41.7 KB  |  1,870 lines

  1. /*
  2.   Notation program
  3.   @(#)notation.c    3.9 (C) Henry Thomas   Release 3     Dated 12/10/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.9 (C) Henry Thomas.   Release 3     Dated 12/10/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,TML, -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, 17, -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.  
  290. int alternate_moves[10][2]; /* table of alternate moves, guessed by
  291.                    the "move generator": guess depl
  292.                    */
  293.  
  294.  
  295. /* the output driver */
  296. static format * dr;
  297.  
  298. static int driver; /* driver type, ie gnu, ascii ... */
  299.  
  300. static int movecount;
  301.  
  302. /* current move, used by the parser */
  303. static int curpiece,  curcol,  curlig ;
  304. static int curdigit, curmove;
  305.  
  306. /* booleen d'erreur */
  307. int error_flag = FALSE;
  308.  
  309. /* move to display board */
  310. static int count = 0 ;
  311.  
  312. static int move_to_display[NB_MOVE_TO_DISP] ;
  313. static int nb_move_to_dsp = 0;
  314. static int stop_at_display = FALSE;
  315.  
  316. /* short and long form comment table */
  317. char * com_short[] = {
  318. #define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) SASC,
  319. #include "chesssymb.def"
  320.  ""
  321.  };
  322. #undef CHESSSYMB
  323.  
  324. char * com_long[] = {
  325. #define CHESSSYMB(LET,LASC,SASC,TEX,PS,ENG,FRA) LASC,
  326. #include "chesssymb.def"
  327.  ""
  328.  };
  329. #undef CHESSSYMB
  330.  
  331.  
  332.  
  333. #define setboard(A,I,J,P,C)  { (A)->board[(I)][(J)] = (P) ; \
  334.                  (A)->color[(I)][(J)] = (C); }
  335. #define clsboard(A,I,J)   { (A)->board[(I)][(J)] = VOID ; \
  336.                 (A)->color[(I)][(J)] = VOID ;}
  337.  
  338. /* --------------------------- code part --------------------- */
  339.  
  340.  
  341. #ifdef __STDC__
  342. static int ispiece(char c)
  343. #else
  344. static int ispiece(c)
  345.      char c;
  346. #endif
  347. {
  348.   register int i;
  349.   
  350.   for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  351.   /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
  352.   return(i<NUMPIECES);
  353. }
  354.  
  355.  
  356. #ifdef __STDC__
  357. static int piece(char c)
  358. #else
  359. static int piece(c)
  360.      char c ;
  361. #endif
  362. {
  363.   register int i;
  364.   
  365.   for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  366.   if ( i== NUMPIECES)
  367.     i = PAWN ;
  368.   return(i);
  369. }
  370.  
  371. /* this function returns the rank of a keyword in a given table.
  372.    if key is not present, it returns the default value
  373.    */
  374. #ifdef __STDC__
  375. static int find_keyword(char *tab[], int nbentry,int defaut,
  376.             char *key,int warning)
  377. #else
  378. static int find_keyword(tab, nbentry,defaut,key,warning)
  379.      char * tab[]; /* the table to look in */
  380.      int nbentry;  /* number of entries */
  381.      int defaut;  /* the default value to return if search failed */
  382.      char *key;    /* the key to find */
  383.      int warning;  /* do we display a warning ? */
  384. #endif
  385. {
  386.   int i ;
  387.  
  388.   for(i=0; (i< nbentry) ;i++)
  389.     if (strcmp(tab[i],key)==0)
  390.       return(i);
  391.  
  392.   /* we failed to find the keyword */
  393.   if (warning)
  394.     (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
  395.   return(defaut);
  396. }
  397.  
  398. /* ---------- board management function ------------- */
  399.  
  400. #ifdef __STDC__
  401. void clear_board(game *g)
  402. #else
  403. void clear_board(g)
  404.      game *g;
  405. #endif
  406. {
  407.   register int i,j;
  408.  
  409.   for (i=0; i < 10; i++ )
  410.     for (j=0 ; j< 10 ; j++) {
  411.       g->board[i][j] = VOID;
  412.       g->color[i][j] = VOID;
  413.     }
  414. }
  415.  
  416. #ifdef __STDC__
  417. game * new_board(void)
  418. #else
  419. game * new_board()
  420. #endif
  421. {
  422.   game * tmp;
  423.   int i; 
  424.  
  425.   tmp = (game *) malloc (sizeof(game));
  426.   ALLOCP(tmp);
  427.   for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  428.     ((int *) tmp)[i] = 0;
  429.   return(tmp);
  430. }
  431.  
  432. #ifdef __STDC__
  433. game * copy_board(game *from, game *to)
  434. #else
  435. game * copy_board(from, to)
  436.      game * from;
  437.      game * to;
  438. #endif
  439. {
  440.   int i; 
  441.  
  442.   for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  443.     ((int *) to)[i] =  ((int *) from)[i] ;
  444.   return(to);
  445. }
  446.  
  447. #ifdef __STDC__
  448. void init_board(game *tgm)
  449. #else
  450. void init_board(tgm)
  451.   game * tgm;
  452. #endif
  453. {
  454.   register int i,j;
  455.  
  456.   clear_board(tgm);
  457.  
  458.   for (i=1; i< 9 ; i=i+7) {
  459.     tgm->board[i][1]= tgm->board[i][8] = ROOK ;
  460.     tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
  461.     tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
  462.     tgm->board[i][4]= QUEEN;
  463.     tgm->board[i][5]= KING;
  464.   }
  465.   for (i=2; i< 8 ; i=i+5) 
  466.     for (j=1; j <=8 ; j++)
  467.       tgm->board[i][j] = PAWN;
  468.  
  469.   for (i=1; i <=2; i++)
  470.     for (j=1; j <=8 ; j++) {
  471.       tgm->color[i][j] = WHITE;
  472.       tgm->color[i+6][j] = BLACK ;
  473.     }
  474. }
  475.  
  476. #ifdef __STDC__
  477. depl * new_move(void)
  478. #else
  479. depl * new_move()
  480. #endif
  481. {
  482.   depl * tmp;
  483.   int i; 
  484.   static int counter = 0;
  485.  
  486.   tmp = (depl *) malloc (sizeof(depl));
  487.   ALLOCP(tmp);
  488.   for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  489.     ((int *) tmp)[i] = 0;
  490.   tmp->uid = ++counter;
  491.   tmp->whiteturn = FALSE;
  492.   tmp->move = 0;
  493.   return(tmp);
  494. }
  495.  
  496.  
  497. #ifdef __STDC__
  498. void init_move(depl *m)
  499. #else
  500. void init_move(m)
  501.      depl *m;
  502. #endif
  503. {
  504.   m->move= 1 ;
  505.   m->whiteturn = TRUE ;
  506. }
  507.  
  508. #ifdef __STDC__
  509. depl * copy_move(depl *from,depl *to)
  510. #else
  511. depl * copy_move(from,to)
  512.      depl * from;
  513.      depl * to ;
  514. #endif
  515. {
  516.   int i; 
  517.  
  518.   for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  519.     ((int *) to)[i] = ((int *) from)[i];
  520.  
  521.   return(to);
  522. }
  523.  
  524. /* add a new move as successor to the move m */
  525. #ifdef __STDC__
  526. depl * add_trailing_move(depl *mo)
  527. #else
  528. depl * add_trailing_move(mo)
  529.      depl * mo;
  530. #endif
  531. {
  532.   mo->next = new_move();
  533.  
  534.   mo->next->prev = mo;
  535.   mo->next->next = (depl *) NULL;
  536.   mo->next->sub  = (depl *) NULL;
  537.  
  538.   mo->next->whiteturn = !( m->whiteturn ) ;
  539.   mo->next->move = mo->move;
  540.   if ( mo->next->whiteturn) {
  541.     mo->next->move++;
  542.   }
  543.  
  544.   return(mo->next);
  545. }
  546.  
  547. #ifdef __STDC__
  548. static depl * add_variation(depl *mo)
  549. #else
  550. static depl * add_variation(mo)
  551.      depl * mo;
  552. #endif
  553. {
  554.   depl *ip ; /* insertion point */
  555.  
  556.   ip = mo ;
  557.   while (ip->sub != (depl *) NULL )
  558.     ip = ip->sub ;
  559.   
  560.   ip->sub = new_move();
  561.  
  562.   ip->sub->prev = mo;
  563.   ip->sub->next = (depl *) NULL;
  564.   ip->sub->sub  = (depl *) NULL;
  565.   
  566.   /* as we have a fictif element heading our list, 
  567.      ( generated by add_trailing_move() )
  568.      we have to go back in the numbering */
  569.   ip->sub->whiteturn =  mo->prev->whiteturn  ;
  570.   ip->sub->move = mo->prev->move ;
  571.  
  572.   return(ip->sub);
  573. }
  574.  
  575.  
  576. #ifdef __STDC__
  577. static void free_move_list(depl *d)
  578. #else
  579. static void free_move_list(d)
  580.      depl * d;
  581. #endif
  582. {  
  583.  
  584.   if (d->next != (depl *) NULL) {
  585.     free_move_list(d->next);
  586.     free(d->next);
  587.     d->next = (depl *) NULL;
  588.   }
  589.   if (d->sub != (depl *) NULL) {
  590.     free_move_list(d->sub);
  591.     free(d->sub);
  592.     d->sub = (depl *) NULL;
  593.   }
  594. }
  595.   
  596. /* procedure upadate borad g with move m */
  597. #ifdef __STDC__
  598. void do_move(game *g,depl *m)
  599. #else
  600. void do_move(g,m)
  601.      game *g;
  602.      depl *m;
  603. #endif
  604. {
  605.   switch (m->type) {
  606.   case MOVE:
  607.     setboard(g,m->tolig,m->tocol,m->piece,CURCOLOR(m)) ;
  608.     clsboard(g,m->fromlig,m->fromcol) ;
  609.     break;
  610.   case PRISE:
  611.     setboard(g,m->tolig,m->tocol,m->piece,CURCOLOR(m)) ;
  612.     clsboard(g,m->fromlig,m->fromcol);
  613.     break;
  614.   case GRANDROQUE:
  615.     if (m->whiteturn)
  616.       m->fromlig = 1;
  617.     else 
  618.       m->fromlig = 8;
  619.     setboard(g,m->fromlig,3,KING,CURCOLOR(m)) ;
  620.     setboard(g,m->fromlig,4,ROOK,CURCOLOR(m)) ;
  621.     clsboard(g,m->fromlig,1) ;
  622.     clsboard(g,m->fromlig,5) ;
  623.     break;
  624.   case PETITROQUE:
  625.     if (m->whiteturn)
  626.       m->fromlig = 1;
  627.     else 
  628.       m->fromlig = 8;
  629.     setboard(g,m->fromlig,7,KING,CURCOLOR(m)) ;
  630.     setboard(g,m->fromlig,6,ROOK,CURCOLOR(m)) ;
  631.     clsboard(g,m->fromlig,5) ;
  632.     clsboard(g,m->fromlig,8) ;
  633.     break;
  634.   case EN_PASSANT:
  635.     setboard(g,m->tolig,m->tocol,m->piece,CURCOLOR(m)) ;
  636.     clsboard(g,m->tolig,m->fromcol) ;
  637.     clsboard(g,m->fromlig,m->fromcol) ;
  638.     break;
  639.   case PROMOTION:
  640.     setboard(g,m->tolig,m->tocol,m->piece,CURCOLOR(m)) ;
  641.     clsboard(g,m->fromlig,m->fromcol);
  642.     break;
  643.   case PROM_ET_PRISE:
  644.     setboard(g,m->tolig,m->tocol,m->piece,CURCOLOR(m)) ;
  645.     clsboard(g,m->fromlig,m->fromcol);
  646.     break;
  647.   default:
  648.     fprintf(stderr,"\nUnable to do move: unknown move type\n");
  649.     break;
  650.   }
  651. }
  652.  
  653.  
  654.  
  655. /* this procedure undo the effect of move m on the board g */
  656. #ifdef __STDC__
  657. void undo_move(game *g,depl *m)
  658. #else
  659. void undo_move(g,m)
  660.      game *g;
  661.      depl *m;
  662. #endif
  663. {
  664.   switch (m->type) {
  665.   case MOVE:
  666.     clsboard(g,m->tolig,m->tocol) ;
  667.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  668.     break;
  669.   case PRISE:
  670.     setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
  671.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  672.     break;
  673.   case GRANDROQUE:
  674.     if (m->whiteturn)
  675.       m->fromlig = 1;
  676.     else 
  677.       m->fromlig = 8;
  678.     clsboard(g,m->fromlig,3) ;
  679.     clsboard(g,m->fromlig,4) ;
  680.     setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
  681.     setboard(g,m->fromlig,1,ROOK,CURCOLOR(m)) ;
  682.     break;
  683.   case PETITROQUE:
  684.     if (m->whiteturn)
  685.       m->fromlig = 1;
  686.     else 
  687.       m->fromlig = 8;
  688.     clsboard(g,m->fromlig,6) ;
  689.     clsboard(g,m->fromlig,7) ;
  690.     setboard(g,m->fromlig,5,KING,CURCOLOR(m)) ;
  691.     setboard(g,m->fromlig,8,ROOK,CURCOLOR(m)) ;
  692.     break;
  693.   case EN_PASSANT:
  694.     clsboard(g,m->tolig,m->tocol) ;
  695.     setboard(g,m->tolig,m->fromcol,PAWN,OPPCOLOR(m)) ;
  696.     setboard(g,m->fromlig,m->fromcol,m->piece,CURCOLOR(m)) ;
  697.     break;
  698.   case PROMOTION:
  699.     clsboard(g,m->tolig,m->tocol);
  700.     setboard(g,m->fromlig,m->fromcol,PAWN,CURCOLOR(m)) ;
  701.     break;
  702.   case PROM_ET_PRISE:
  703.     setboard(g,m->tolig,m->tocol,m->prise,OPPCOLOR(m)) ;
  704.     setboard(g,m->fromlig,m->fromcol,PAWN,CURCOLOR(m)) ;
  705.     break;
  706.   default:
  707.     fprintf(stderr,"\nUnable to undo move: unknown move type\n");
  708.     break;
  709.   }
  710. }
  711.  
  712. /* variation procedures == stack manipulation */
  713.  
  714. #ifdef __STDC__
  715. void enter_variation(void)
  716. #else
  717. void enter_variation()
  718. #endif
  719. {
  720.   int l;
  721.  
  722.   l = dr->variation ;
  723.   
  724.   if (l >= VARIATION_MAX) {
  725.     error((stderr,"\nMaximum imbricated variation is %d\n",VARIATION_MAX));
  726.   } else {
  727.     /* save current line/variation */
  728.     stack[l].d = m;
  729.     stack[l].b = tos;
  730.     stack[l].d1 = dr->iswhiteturn;
  731.     stack[l].d2 = dr->interrupt = TRUE ;    
  732.     /* create new */
  733.     tos = new_board();
  734.     (void) copy_board(stack[l].b, tos);
  735.  
  736.     /* A variation FOLLOWS the main line 
  737.        so we need to backtrack one move
  738.        */
  739.     m = add_variation(stack[l].d);
  740.     undo_move(tos,stack[l].d);
  741.  
  742.     /* set variables */
  743.     l++;
  744.     dr->variation = l;
  745.  
  746.     output_variation(dr,VARIATION_IN);
  747.   }
  748. }
  749.  
  750. #ifdef __STDC__
  751. void exit_variation(void)
  752. #else
  753. void exit_variation()
  754. #endif
  755. {
  756.   int l ;
  757.  
  758.   l = dr->variation ;
  759.   
  760.   if (l == 0) {
  761.     error((stderr,"\nYou cannot exit from the main line (a variation level error?)\n"));
  762.   } else {
  763.     output_variation(dr,VARIATION_OUT);
  764.  
  765.     l--;
  766.     free(tos);
  767.     free(m);
  768.     m = stack[l].d ;
  769.     tos = stack[l].b ;
  770.  
  771.     dr->iswhiteturn = stack[l].d1 ;
  772.     dr->interrupt = stack[l].d2 ;
  773.     dr->variation = l;
  774.   }
  775. }
  776.  
  777. /* ----------- semantic evaluation of move ----------- */
  778. /* check if  position lies within the board
  779.    */
  780. #ifdef __STDC__
  781. int in_board(int l,int c)
  782. #else
  783. int in_board(l,c)
  784.      int l,c;
  785. #endif
  786. {
  787.   return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
  788. }
  789.  
  790. /* check that the path from pos1 to pos2 is free
  791.    */
  792. #ifdef __STDC__
  793. int path_free(int l1,int c1,int l2,int c2)
  794. #else
  795. int path_free(l1, c1, l2, c2)
  796. int l1,c1, l2, c2;
  797. #endif
  798. {
  799.   int li = 1 ;
  800.   int ci = 1 ;
  801.   int lig, col;
  802.  
  803.  
  804.   li = SIGN(l2-l1);
  805.   ci = SIGN(c2-c1);
  806.  
  807.  
  808.   if ( c1 == c2 ) {    
  809.     col = c1;
  810.     for (lig = l1 +li; lig != l2 ; lig +=li)
  811.       if (tos->board[lig][col] != VOID)
  812.     return (FALSE);
  813.     return(TRUE);
  814.   }
  815.  
  816.   if ( l1 == l2) {
  817.     lig = l1 ;
  818.     for (col = c1 + ci; col != c2 ; col +=ci)
  819.       if (tos->board[lig][col] != VOID)
  820.     return (FALSE);
  821.     return(TRUE);
  822.   }
  823.  
  824.   for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
  825.     if (tos->board[lig][col] != VOID) {
  826.       return (FALSE);
  827.     }
  828.   return(TRUE);
  829. }
  830.  
  831. /* check roque is possible */
  832. #ifdef __STDC__
  833. int check_roque(void)
  834. #else
  835. int check_roque()
  836. #endif
  837. {
  838.   int lig, col ;
  839.  
  840.   if (m->whiteturn)
  841.     lig = 1 ;
  842.   else
  843.     lig =8;
  844.   if (m->type == GRANDROQUE)
  845.     for (col = 2; col < 5 ; col++)
  846.       if (tos->board[lig][col] != VOID)
  847.     return(FALSE);
  848.   if (m->type == PETITROQUE)
  849.     for (col = 6; col < 7 ; col++)
  850.       if (tos->board[lig][col] != VOID)
  851.     return(FALSE);
  852.   return(TRUE);
  853. }
  854.   
  855. /* check -- or guess -- where a given piece come */
  856. #ifdef __STDC__
  857. int guess_piece(void) 
  858. #else
  859. int guess_piece() 
  860. #endif
  861. {
  862.   return(tos->board[m->fromlig][m->fromcol]); 
  863. }
  864.  
  865. /* try to guess the move -- low-level function 
  866.    it returns -- in the parms -- the coordinates of a possible move
  867.    it returns -- as value -- the number of possible move
  868.  */
  869. #ifdef __STDC__
  870. int guess_depl(int nb, int tab[][2],
  871.            int * pl1, int * pc1, int l2, int c2, int path)
  872. #else
  873. int guess_depl(nb, tab, pl1, pc1, l2,c2,path)
  874.      int nb;
  875.      int tab[10][2];
  876.      int *pl1, *pc1;
  877.      int l2,c2;
  878.      int path; /* tell if we have to check for a free path 
  879.           used for en passant */
  880. #endif
  881. {
  882.   int i, c, l;
  883.   int count = 0;
  884.  
  885.   for (i=0; i< nb; i++ ) {
  886.     l = l2 - tab[i][0];
  887.     c = c2 - tab[i][1];
  888.     if (in_board(l,c))
  889.       if ((tos->board[l][c] == m->piece) &&
  890.       (tos->color[l][c] == CURCOLOR(m)) &&
  891.       ( !path || (path && path_free(l,c, l2, c2))) &&
  892.       ( ((*pl1) == 0) || ((*pl1) == l) ) &&
  893.       ( ((*pc1) == 0) || ((*pc1) == c) ) )
  894.     {
  895.       alternate_moves[count][0] = l;
  896.       alternate_moves[count][1] = c;
  897.       count++;
  898.     }
  899.   }
  900.   alternate_moves[count][0] = alternate_moves[count][1] = 0;
  901.   if (count > 0) {
  902.     /* we return the first entry because the last entry, in the case of pawn,
  903.        movement, might be a catching move, even it a non-catching, more 
  904.        probable, is present
  905.        */
  906.     *pl1 = alternate_moves[0][0];
  907.     *pc1 = alternate_moves[0][1];
  908.   }
  909.   return(count);
  910. }
  911.  
  912. /* check for ambiguity in a move
  913.    used in output function: the piece had been already moved and
  914.    if we guess another move, there is an ambiguity
  915.    */
  916. #ifdef __STDC__
  917. int ambiguity(depl *d, int *amline, int *amcols)
  918. #else
  919. int ambiguity(d, amline, amcols )
  920.      depl *d ;
  921.      int * amline;
  922.      int *amcols;
  923. #endif
  924. {
  925.   int l1 = 0 ;
  926.   int c1 = 0 ;
  927.   int r = 0;
  928.   int frompiece = d->piece;
  929.   int l2 = d->tolig;
  930.   int c2 = d->tocol ;
  931.   int i;
  932.  
  933.   undo_move(tos,m);
  934.  
  935.  
  936.   switch(frompiece) {
  937.   case PAWN:
  938.     if (m->type == PRISE) {
  939.       if (m->whiteturn)
  940.     r = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  941.       else
  942.     r = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  943.     } else {
  944.       if (m->whiteturn)
  945.     r = guess_depl(NB_M_PAWN_MOVE_WD,m_pawn_move_wd,&l1,&c1, l2,c2, FALSE);
  946.       else
  947.     r = guess_depl(NB_M_PAWN_MOVE_BD,m_pawn_move_bd,&l1,&c1,l2,c2, FALSE);
  948.     }
  949.     break;
  950.   case KNIGHT:
  951.     r = guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
  952.     break;
  953.   case BISHOP:
  954.     r = guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
  955.     break;
  956.   case ROOK:
  957.     r = guess_depl(NB_M_ROOK,   m_rook,   &l1,&c1, l2,c2, TRUE);
  958.     break;
  959.   case QUEEN:
  960.     r = guess_depl(NB_M_QUEEN,  m_queen,  &l1,&c1, l2,c2, TRUE);
  961.     break;
  962.   case KING:
  963.     r = guess_depl(NB_M_KING,   m_king,   &l1,&c1, l2,c2, TRUE);
  964.     break;
  965.   default:
  966.     break;
  967.   }
  968.   do_move(tos,m);
  969.  
  970.   if (r > 1) {
  971.     /* we have an ambiguity, we use alternate_moves to resolve it:
  972.        we look through that table to find identical lines: if so, 
  973.        we signal that the column determines move; 
  974.        we then do the same with columns
  975.        */
  976.     *amline = TRUE ;
  977.     *amcols = TRUE ;
  978.     for (i= 1; i < r ; i++) {
  979.       if (alternate_moves[i][0] != alternate_moves[0][0])
  980.     *amline = FALSE;
  981.       if (alternate_moves[i][1] != alternate_moves[0][1])
  982.     *amcols = FALSE;
  983.     }
  984.   }
  985.   return( (r > 1) );
  986. }
  987.  
  988. #ifdef __STDC__
  989. int check_move(depl *m)
  990. #else
  991. int check_move(m)
  992.      depl * m;
  993. #endif
  994. {
  995.   int l1,c1,l2,c2;
  996.   int tmp; /* tmp boolean */
  997.  
  998.   l1 = m->fromlig;
  999.   c1 = m->fromcol;
  1000.   l2 = m->tolig;
  1001.   c2 = m->tocol;
  1002.  
  1003.   if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  1004.     return(check_roque());
  1005.  
  1006.   if ((tos->board[l1][c1] != m->piece)||
  1007.       (tos->color[l1][c1] != CURCOLOR(m))){
  1008.     fprintf(stderr,"Problem: piece should be %c\n",in_table[tos->board[l1][c1]]);
  1009.     if (m->whiteturn)
  1010.       error ((stderr,"\nOriginating position and piece not coherent for White move %d\n",m->move));
  1011.     else
  1012.       error ((stderr,"\nOriginating position and piece not coherent for Black move %d\n",m->move));
  1013.     return(FALSE);
  1014.   }
  1015.  
  1016.   /* if prise === FALSE, we must not take a piece */
  1017.   if (tos->board[l2][c2] != VOID 
  1018.       && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
  1019.     (void) fprintf(stderr,"catching not indicated at move %d.\n",m->move);
  1020.     return(FALSE);
  1021.   }
  1022.  
  1023.   /* prendre une de ses propres pieces */
  1024.   if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
  1025.     (void) fprintf(stderr,"attempt to catch same color piece at move %d.\n",
  1026.            m->move);
  1027.     return(FALSE);
  1028.   }
  1029.  
  1030.   /* we check if the move is a possible one for the piece
  1031.      */
  1032.  
  1033.   switch(m->piece) {
  1034.   case PAWN:
  1035.     if (m->prise) {
  1036.       if (m->whiteturn)
  1037.     tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  1038.       else
  1039.     tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  1040.     } else {
  1041.       if (m->whiteturn)
  1042.     tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
  1043.       else
  1044.     tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
  1045.     }
  1046.     /* is it a "prise en passant " */
  1047.     if ((c1 != c2) && (tos->board[l2][c2] == VOID)
  1048.     && (tos->board[l1][c2] == PAWN)) {
  1049.       m->type = EN_PASSANT ;
  1050.       /* we must perform here the "en passant" test */
  1051.       tos->board[l1][c2] = VOID ;
  1052.       tos->color[l1][c2] = VOID ;
  1053.       tmp = TRUE;
  1054.     }
  1055.     return(tmp);
  1056.     break;
  1057.   case KNIGHT:
  1058.     return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  1059.     break;
  1060.   case BISHOP:
  1061.     return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  1062.     break;
  1063.   case ROOK:
  1064.     return(guess_depl(NB_M_ROOK,   m_rook,   &l1,&c1, l2,c2, TRUE));
  1065.     break;
  1066.   case QUEEN:
  1067.     return(guess_depl(NB_M_QUEEN,  m_queen,  &l1,&c1, l2,c2, TRUE));
  1068.     break;
  1069.   case KING:
  1070.     return(guess_depl(NB_M_KING,   m_king,   &l1,&c1, l2,c2, TRUE));
  1071.     break;
  1072.   default:
  1073.     break;
  1074.   }
  1075.  
  1076.   return(TRUE);
  1077. }
  1078.  
  1079. /* try to guess the move -- used for shortened notation
  1080.    */
  1081. #ifdef __STDC__
  1082. int guess_move(void)
  1083. #else
  1084. int guess_move()
  1085. #endif
  1086. {
  1087.   int l1,c1,l2,c2;
  1088.  
  1089.   if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  1090.     return(TRUE);
  1091.  
  1092.   l1 = m->fromlig ;
  1093.   c1 = m->fromcol ;
  1094.   l2 = m->tolig;
  1095.   c2 = m->tocol;
  1096.  
  1097.   switch(m->piece) {
  1098.   case PAWN:
  1099.     if (m->prise) {
  1100.       if (m->whiteturn)
  1101.     (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  1102.       else
  1103.     (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  1104.     } else {
  1105.       if (m->whiteturn)
  1106.     (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); 
  1107.       else
  1108.     (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); 
  1109.     }
  1110.     break;
  1111.   case KNIGHT:
  1112.     (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
  1113.     break;
  1114.   case BISHOP:
  1115.     (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
  1116.     break;
  1117.   case ROOK:
  1118.     (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
  1119.     break;
  1120.   case QUEEN:
  1121.     (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
  1122.     break;
  1123.   case KING:
  1124.     (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
  1125.     break;
  1126.   default:
  1127.     break;
  1128.   }
  1129.  
  1130.   if ((l1 == 0) || (c1 == 0)) {
  1131.     if (m->whiteturn)
  1132.       error((stderr,"\nUnable to guess white move %d, with piece %c\n",
  1133.          m->move,in_table[m->piece]));
  1134.     else
  1135.       error((stderr,"\nUnable to guess black move %d, with piece %c\n",
  1136.          m->move,in_table[m->piece]));
  1137.     return(FALSE);
  1138.   } else {
  1139.     m->fromcol = c1;
  1140.     m->fromlig = l1;
  1141.     return(TRUE);
  1142.   }
  1143. }
  1144.  
  1145. /* --------------- execution of move ----------------- */
  1146.  
  1147. /* clear a position */
  1148. #ifdef __STDC__
  1149. int clear_pos(int lig, int col)
  1150. #else
  1151. int clear_pos(lig,col)
  1152.      int lig;
  1153.      int col;
  1154. #endif
  1155. {
  1156.   tos->board[lig][col] = VOID ;
  1157.   tos->color[lig][col] = VOID ;
  1158.   return(TRUE);
  1159. }
  1160.  
  1161. /* configure the board */
  1162. #ifdef __STDC__
  1163. int configure(void)
  1164. #else
  1165. int configure()
  1166. #endif
  1167. {
  1168.   if (configuring) {
  1169.     if (m->piece == VOID)
  1170.       m->piece = PAWN ;
  1171.     tos->board[m->tolig][m->tocol] = m->piece ;
  1172.     tos->color[m->tolig][m->tocol] = configside ;
  1173.   }
  1174.   return(TRUE);
  1175. }
  1176.  
  1177. /* execute a move, no checking */
  1178. #ifdef __STDC__
  1179. int execute_move(void)
  1180. #else
  1181. int execute_move()
  1182. #endif
  1183. {
  1184.   register int i;
  1185.  
  1186.   if (m->piece == VOID )
  1187.     m->piece = PAWN;
  1188.  
  1189.   if ((m->fromlig == 0) || (m->fromcol == 0))
  1190.     (void) guess_move();
  1191.   
  1192.   /* supply to the -- maybe -- deficiency of input notation
  1193.      */
  1194.   if ((m->fromlig !=0) || (m->fromcol != 0))
  1195.     m->piece = tos->board[m->fromlig][m->fromcol];
  1196.  
  1197.   if (tos->board[m->tolig][m->tocol] != VOID) {
  1198.     m->type = PRISE;
  1199.     m->prise = tos->board[m->tolig][m->tocol] ;
  1200.   }
  1201.  
  1202.   if (!check_move(m)) {
  1203.     if (m->whiteturn)
  1204.       error((stderr,"\nWhite move %d illegal\n",m->move));
  1205.     else
  1206.       error((stderr,"\nBlack move %d illegal\n",m->move));
  1207.   }
  1208.  
  1209.   do_move(tos, m);
  1210.  
  1211.   output_move(dr,m);
  1212.  
  1213.   if (error_flag) {
  1214.     (void) fprintf(dr->outfile, "\nLast position encountered:\n");
  1215.     output_board(dr,tos);
  1216.     close_files();
  1217.     exit(0);
  1218.   }
  1219.  
  1220.   /* do we need to display the move ? */
  1221.   if (nb_move_to_dsp > 0) {
  1222.     for (i=0; i < nb_move_to_dsp; i++)
  1223.       if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
  1224.     output_board(dr,tos);
  1225.     if (stop_at_display) {
  1226.       output_end(dr);
  1227.       close_files();
  1228.       exit(0);
  1229.     }
  1230.       }
  1231.   }
  1232.  
  1233.   return(TRUE);
  1234. }
  1235.  
  1236. /* ------------------ automata ----------------------- */
  1237.  
  1238. /* categorise the input for the automata */
  1239. #ifdef __STDC__
  1240. int typechar(char c)
  1241. #else
  1242. int typechar(c)
  1243.      char c;
  1244. #endif
  1245. {
  1246.   if (ispiece(c))
  1247.     return(0);
  1248.   if ((c >=  'a') && ( c <= 'h'))
  1249.     return(1);
  1250.   if ((c >=  '1') && ( c <= '8'))
  1251.     return(2);
  1252.   if ( c== '-' )
  1253.     return(3);
  1254.   if ((c == 'x') || (c == 'X' ))
  1255.     return(4);
  1256.   if (c == '=' )
  1257.     return(5);
  1258.   if (c == '\0' )
  1259.     return(6);
  1260.   return(7);
  1261. }
  1262.  
  1263.  
  1264. /* execute the actions decided by the automata */
  1265. #ifdef __STDC__
  1266. int execute(int num,char c)
  1267. #else
  1268. int execute(num,c)
  1269.      int num;
  1270.      char c;
  1271. #endif
  1272. {
  1273.   switch (num) {
  1274.   case 1: /* set cur piece */
  1275.     curpiece = piece(c);
  1276.     break;
  1277.   case 2: /* set cur col */
  1278.     curcol = lettertocol(c);
  1279.     break;
  1280.   case 3: /* set cur lig */
  1281.     curlig = lettertolig(c);
  1282.     break;
  1283.   case 4: /* from = cur ; prise = false */
  1284.     m->piece = curpiece ;
  1285.     m->fromcol = curcol ;
  1286.     m->fromlig = curlig;
  1287.     /*m->topiece = curpiece;*/
  1288.     break;
  1289.   case 5: /* from = cur ; prise = true */
  1290.     m->piece = curpiece ;
  1291.     m->fromcol = curcol ;
  1292.     m->fromlig = curlig;
  1293.     m->type = PRISE ;
  1294.     m->prise = curpiece;
  1295.     break;
  1296.   case 6: /* to = cur ; guess from */
  1297.   case 7: /* to = cur ; guess from ; parse remaining token */
  1298.     m->piece = curpiece ;
  1299.     m->tocol = curcol;
  1300.     m->tolig = curlig ;
  1301.  
  1302.     /*m->topiece = curpiece ; /* ? */
  1303.  
  1304.     if (configuring)
  1305.       (void) configure();
  1306.     else {
  1307.       (void) execute_move();
  1308.     }
  1309.     break;
  1310.   case 8: /* to = cur */
  1311.   case 9: /* to = cur */
  1312.     m->tocol = curcol;
  1313.     m->tolig = curlig ;
  1314.  
  1315.     if (configuring)
  1316.       (void) configure();
  1317.     else {
  1318.       (void) execute_move();
  1319.     }
  1320.     break;
  1321.   case 10: /* piece = cur piece ; prise = true */
  1322.     /* later : guess from position */
  1323.     m->piece = curpiece ;
  1324.     m->type = PRISE ;
  1325.     break;
  1326.   case 11: /* grand roque */
  1327.   case 12: /* petit roque */
  1328.     (void) execute_move();
  1329.     break;
  1330.   case 13: /* case of simpliest algebraic notation ;
  1331.           only e2e4 : this is the transition from e2 to e4
  1332.           also the case of move such as Nge2
  1333.           from =cur; prise = FALSE;
  1334.           also:
  1335.           curcol = ...
  1336.           */
  1337.     m->piece = curpiece ;
  1338.     m->fromcol = curcol ;
  1339.     m->fromlig = curlig;
  1340.  
  1341.     m->type = MOVE;
  1342.     curcol = lettertocol(c);
  1343.     break;
  1344.   case 14: /* promotion, the "=" */
  1345.     /* NB: actions need some clean up here */
  1346.     /* to = cur */
  1347.  
  1348.     m->tocol = curcol;
  1349.     m->tolig = curlig ;
  1350.     /*m->topiece = curpiece ;*/
  1351.  
  1352.     if (m->type == PRISE )
  1353.       m->type = PROM_ET_PRISE ;
  1354.     else
  1355.       m->type = PROMOTION ;
  1356.     /* by default, we promote to queen 
  1357.        this can be overwritten by explicit naming
  1358.        */
  1359.     m->promotion = curpiece = QUEEN ;
  1360.     break;
  1361.   case 15: /* promotion, the piece name */
  1362.     m->promotion = curpiece = piece(c) ;
  1363.     break;
  1364.   case 16: /* not used */ 
  1365.     break;
  1366.   case 17: /* execute move for promotion */
  1367.     (void) execute_move();
  1368.     break;
  1369.   case -1:
  1370.     break;
  1371.   default:
  1372.     break;
  1373.   }
  1374.   return(TRUE);
  1375. }
  1376.  
  1377. #ifdef __STDC__
  1378. int parse_number(char *token)
  1379. #else
  1380. int parse_number(token)
  1381.      char *token;
  1382. #endif
  1383. {
  1384.   int curmove = 0 ;
  1385.   int i;
  1386.  
  1387.   /* check coherency with internal numbering */
  1388.   i = 0;
  1389.   while (isdigit(token[i])) {
  1390.    curmove = curmove * 10 +  ((int) token[i++] - (int) '0' );
  1391.   }
  1392.   movecount = curmove ;
  1393.   return(TRUE);
  1394. }
  1395.  
  1396. #ifdef __STDC__
  1397. int parse_text(char *text)
  1398. #else
  1399. int parse_text(text)
  1400.      char *text;
  1401. #endif
  1402. {
  1403.   output_text(dr,T_TEXT, text, 0);
  1404.   return(TRUE);
  1405. }
  1406.  
  1407. #ifdef __STDC__
  1408. int parse_comment(char *com)
  1409. #else
  1410. int parse_comment(com)
  1411.      char *com;
  1412. #endif
  1413. {
  1414.   int t;
  1415.  
  1416.   if (com[0] == '$')
  1417.     /* we look in the long ascii table */
  1418.     t = find_keyword(com_long, NUM_COM_CODE, NUM_COM_CODE, com, TRUE);
  1419.   else {
  1420.     /* we look for the comment in the short ascii table */
  1421.     t = find_keyword(com_short, NUM_COM_CODE, NUM_COM_CODE, com,FALSE);
  1422.     if (t == NUM_COM_CODE)
  1423.       fprintf (stderr,"\nWhat is \"%s\" ?\n",com);   
  1424.   }
  1425.   if (t != NUM_COM_CODE)
  1426.     output_text(dr,T_COMMENT, com, t);
  1427.   return(TRUE);
  1428. }
  1429.  
  1430. #ifdef __STDC__
  1431. int parse_keyword(char *token, char *text)
  1432. #else
  1433. int parse_keyword(token,text)
  1434.      char *token;
  1435.      char *text;
  1436. #endif
  1437. {
  1438.   char c;
  1439.  
  1440.   switch (find_keyword(keywords, NBKEYWORD, KNULL, token, TRUE)) {
  1441.   case START:
  1442.     /* don't forget we are configuring the previous move */
  1443.     /* -> move 0, black */
  1444.     configuring = FALSE;
  1445.     m->move = 0;
  1446.     m->whiteturn = FALSE;
  1447.     break;
  1448.   case CLEAR:
  1449.     clear_board(tos);
  1450.     m= theplay->chain;
  1451.     free_move_list(m);
  1452.     break;
  1453.   case SHOWBOARD:
  1454.     output_board(dr,tos);
  1455.     break;
  1456.   case TOWHITE:
  1457.     /* don't forget we are configuring the previous move */
  1458.     /* reset to 0,black --> 1,white */
  1459.     m->move = 0;
  1460.     m->whiteturn = FALSE;
  1461.     break;
  1462.   case TOBLACK:
  1463.     /* reset to 1,white -> 1 black */
  1464.     m->move = 1;
  1465.     m->whiteturn = TRUE;
  1466.     break;
  1467.   case CONFIGWH:
  1468.     configuring = TRUE ;
  1469.     configside = WHITE;
  1470.     m= theplay->chain;
  1471.     free_move_list(m);
  1472.     break;
  1473.   case CONFIGBL:
  1474.     configuring = TRUE ;
  1475.     configside = BLACK;
  1476.     m= theplay->chain;
  1477.     free_move_list(m);
  1478.     break;
  1479.   case DEFAULTP:
  1480.     init_board(tos);
  1481.     m= theplay->chain;
  1482.     free_move_list(m);
  1483.     break;
  1484.   case TITLE:
  1485.     output_text(dr, T_TITLE, text, NULL);
  1486.     break;
  1487.   case SUBTITLE:
  1488.     output_text(dr, T_SUBTITLE, text, NULL);
  1489.     break;
  1490.   case SCORE:
  1491.     output_text(dr, T_SCORE, text, NULL);
  1492.     break;
  1493.   case LANGUE:
  1494.     in_language = find_keyword (t_language, NBLANGUAGES, in_language,
  1495.                    text,TRUE);
  1496.     associe_traduction( &in_table, in_language);           
  1497.     break;
  1498.   case SPECIAL: /* all input, up to \n is copied to output */
  1499.     while ((( c = getc(infile)) != EOF) && (c != '\n'))
  1500.       (void) putc (c,dr->outfile);
  1501.     putc ('\n', dr->outfile);
  1502.     break;
  1503.   case KNULL:
  1504.   default:
  1505.     fprintf(stderr,"unknown keyword %s\n",token);
  1506.     break;
  1507.   }
  1508.   return(TRUE);
  1509. }
  1510.  
  1511. #ifdef __STDC__
  1512. int parse_roque(char *token)
  1513. #else
  1514. int parse_roque(token)
  1515.      char * token;
  1516. #endif
  1517.   int i;
  1518.  
  1519.   for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
  1520.   if ( i < NBROQUE ) {
  1521.     
  1522.     m = add_trailing_move(m);
  1523.     init_parse(m);
  1524.  
  1525.     if (strlen(token) == 3) {
  1526.       m->type = PETITROQUE ;
  1527.       (void) execute(12,DUMMYCHAR);
  1528.     } else {
  1529.       m->type = GRANDROQUE ;
  1530.       (void) execute(11,DUMMYCHAR);
  1531.     }
  1532.     /*(void) fprintf(stderr,"ROQUE\n");*/
  1533.     return(TRUE);
  1534.   }
  1535.  
  1536.   return(FALSE);
  1537. }
  1538.  
  1539. #ifdef __STDC__
  1540. int  parse_move(char *token)
  1541. #else
  1542. int  parse_move(token)
  1543.      char *token;
  1544. #endif
  1545. {
  1546.   register int i;
  1547.   int correcte = FALSE ;
  1548.   int erreursyntaxe = FALSE ;
  1549.   int etat =0;
  1550.   int code;
  1551.   
  1552.   m = add_trailing_move(m);
  1553.   init_parse(m);
  1554.   m->type = MOVE;
  1555.  
  1556.   i=0;
  1557.   while ( !correcte && !erreursyntaxe ) {
  1558.     code = typechar(token[i]);
  1559.     (void) execute(action[etat][code],token[i]);
  1560.     etat = transit[etat][code] ;
  1561.     if (etat == -1) 
  1562.       erreursyntaxe = TRUE;
  1563.     if (etat == FINAL)
  1564.       correcte = TRUE ;
  1565.     i++;
  1566.   }
  1567.   if (erreursyntaxe) {
  1568.     (void) fprintf(stderr, "no comprende, senor: %s\n",token);
  1569.     return(FALSE);
  1570.   }
  1571.   if (correcte) {
  1572.     /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
  1573.   }
  1574.   /*init_parse(m);*/
  1575.   return(TRUE);
  1576. }
  1577.  
  1578. #ifdef __STDC__
  1579. void init_parse(depl *m)
  1580. #else
  1581. void init_parse(m)
  1582.      depl * m ;
  1583. #endif
  1584. {
  1585.  
  1586.   /* global position and piece variable initialised to 0
  1587.      */
  1588.   /* move and whiteturn unchanged */ 
  1589.  
  1590.   m->type = MOVE ;
  1591.  
  1592.   curpiece = m->piece = VOID ;
  1593.   curcol = m->tocol = m->fromcol = 0;
  1594.   curlig = m->tolig = m->fromlig = 0;
  1595.  
  1596.   m->promotion = VOID;
  1597.   m->prise = VOID;
  1598.   m->is_check = FALSE ;
  1599.  
  1600.   curdigit = curmove = 0;
  1601.  
  1602.   /*if (movecount != m->move)
  1603.     (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
  1604.            m->move, movecount);*/
  1605.  
  1606. }
  1607.  
  1608. /* ------------------- top routines -------------------- */
  1609.  
  1610. /* cette fonction analyse les arguments de la ligne de commande
  1611.    */
  1612. #ifdef __STDC__
  1613. int parse_options(int argc,char *argv[])
  1614. #else
  1615. int parse_options(argc,argv)
  1616.      int argc;
  1617.      char * argv[];
  1618. #endif
  1619. {
  1620.   int narg =1 ;
  1621.   int i;
  1622.   register int c;
  1623.   char cp[132];
  1624.   char chaine[MAXTOKLEN];
  1625.  
  1626.   infile = stdin;
  1627.   dr->outfile = stdout;
  1628.   nb_move_to_dsp = 0;
  1629.  
  1630.   while (narg < argc ) {
  1631.     (void) strcpy (cp,argv[narg]);
  1632.     switch (cp[0]) {
  1633.     case '-' :
  1634.       switch (cp[1]) {
  1635.       case 'f' : /* from langage */
  1636.     if  ((narg+1) >= argc )
  1637.       fatal((stderr,"missing argument to %s option",cp));
  1638.     narg++ ;
  1639.     in_language = find_keyword (t_language, NBLANGUAGES,
  1640.                     DEFAULT_INPUT_LANGUAGE,
  1641.                     argv[narg],TRUE);
  1642.     break;
  1643.       case 't' : /* to langage */
  1644.     if  ((narg+1) >= argc )
  1645.       fatal((stderr,"missing argument to %s option",cp));
  1646.     narg++ ;
  1647.     out_language = find_keyword (t_language, NBLANGUAGES,
  1648.                      DEFAULT_OUTPUT_LANGUAGE,
  1649.                      argv[narg],TRUE);
  1650.     break;
  1651.       case 'o' : /* next arg is output file */
  1652.     narg++ ;
  1653.     if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
  1654.       (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
  1655.       (void) fprintf (stderr,"assume stdout for output\n");
  1656.     }
  1657.     break;
  1658.       case 'e':
  1659.     if  ((narg+1) >= argc )
  1660.       fatal((stderr,"missing argument to %s option",cp));
  1661.     narg++ ;
  1662.  
  1663.     i=0;
  1664.     nb_move_to_dsp = 0;
  1665.     move_to_display[nb_move_to_dsp] = 0;
  1666.     while (isdigit(argv[narg][i])) {
  1667.       move_to_display[nb_move_to_dsp] =
  1668.         ((int) argv[narg][i] - (int) '0')
  1669.           + move_to_display[nb_move_to_dsp] * 10;
  1670.       i++;
  1671.     }
  1672.     nb_move_to_dsp++;
  1673.     stop_at_display = TRUE;
  1674.     break;
  1675.       case 'c':
  1676.     if  ((narg+1) >= argc )
  1677.       fatal((stderr,"missing argument to %s option",cp));
  1678.     narg++ ;
  1679.  
  1680.     i=0;
  1681.     while (isdigit(argv[narg][i])) {
  1682.       move_to_display[nb_move_to_dsp] = 0;
  1683.       while (isdigit(argv[narg][i])) {
  1684.         move_to_display[nb_move_to_dsp] =
  1685.           ((int) argv[narg][i] - (int) '0')
  1686.           + move_to_display[nb_move_to_dsp] * 10;
  1687.         i++;
  1688.       }
  1689.       nb_move_to_dsp++;
  1690.  
  1691.       if (nb_move_to_dsp > NB_MOVE_TO_DISP)
  1692.         fatal((stderr,"max. number of move to display exceeded"));
  1693.  
  1694.       /* process next number */
  1695.       if (argv[narg][i] == ',')
  1696.         i++;
  1697.     }
  1698.     break;
  1699.       case 'a': /* algebraic output */
  1700.     dr->output_move_format = ALGEBRAIC;
  1701.     break;
  1702.       case 's':  /* shortened output */
  1703.     dr->output_move_format = SHORTENED;
  1704.     break;
  1705.       case 'b': /* display only the board, no move */
  1706.     dr->only_board = TRUE;
  1707.     break;
  1708.       case 'd': /* output driver */
  1709.     if  ((narg+1) >= argc )
  1710.       fatal((stderr,"missing argument to %s option",cp));
  1711.     narg++ ;
  1712.     driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
  1713.                   argv[narg],TRUE);
  1714.     break;
  1715.       case 'i': /* no headers */
  1716.     dr->print_headers = FALSE;
  1717.     break;
  1718.       case 'v': /* print version */
  1719.     /* this already done, so exit() */
  1720.     exit(0);
  1721.     break;
  1722.       case 'h': /* help file */
  1723.     (void) strcpy(chaine,LIB_DIR);
  1724.         if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
  1725.           fatal((stderr,"Can't find help file.\n"));
  1726.         else {
  1727.           while ((c = getc(fhelp)) != EOF)
  1728.             (void) fputc(c,stderr);
  1729.           (void) fclose(fhelp);
  1730.       exit(0);
  1731.         }
  1732.          break;
  1733.       default:
  1734.     error((stderr,"\nUnknown command line options %s\n",cp));
  1735.     break;
  1736.       }
  1737.       break;
  1738.     default: /* assume this is the input file */
  1739.       if ((infile = fopen (cp,"r")) == NULL)
  1740.     fatal((stderr,"can't open %s input file\n",cp));
  1741.     }
  1742.     narg++;
  1743.   } /* process next arg */
  1744.   return(argc);
  1745. }
  1746.  
  1747. #ifdef __STDC__
  1748. void close_files(void)
  1749. #else
  1750. void close_files()
  1751. #endif
  1752. {
  1753.   if (!((infile == stdin)||(infile == NULL)))
  1754.     (void) fclose(infile);
  1755.   if (dr->outfile != stdout )
  1756.     (void) fclose(dr->outfile);
  1757. }
  1758.  
  1759. #ifdef __STDC__
  1760. int associe_traduction (char **table, int language)
  1761. #else
  1762. int associe_traduction (table, language)
  1763. char ** table;
  1764. int language ;
  1765. #endif
  1766. {
  1767.   if (language < 0 || (language >= NBLANGUAGES))
  1768.     error((stderr,"\nUnknown language\n"));
  1769.   else
  1770.     *table = c_language[language];
  1771.   return(language);
  1772. }
  1773.  
  1774. #ifdef __STDC__
  1775. static void print_all_play(play *p)
  1776. #else
  1777. static void print_all_play(p)
  1778. play *p;
  1779. #endif
  1780.   depl *d;
  1781.   d = p->chain;
  1782.   while (d->next != NULL){
  1783.     d = d->next;
  1784.     output_move(dr,d);
  1785.   }
  1786. }
  1787.  
  1788. /* ------------- main --------------------- */
  1789.  
  1790. #ifdef __STDC__
  1791. void main(int argc,char *argv[])
  1792. #else
  1793. int main(argc,argv)
  1794.      int argc;
  1795.      char * argv[];
  1796. #endif
  1797. {
  1798.   (void) fprintf(stderr,"%s\n",version_string);
  1799.   
  1800.   /* allocation of driver descriptor */
  1801.   dr = new_driver();
  1802.  
  1803.   /* default configuration */
  1804.   init_driver(dr,DEFAULT_DRIVER);
  1805.   (void) associe_traduction(&in_table,  DEFAULT_INPUT_LANGUAGE );
  1806.   (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
  1807.  
  1808.   (void) parse_options(argc,argv);
  1809.  
  1810.   (void) associe_traduction (&in_table, in_language);
  1811.   (void) associe_traduction (&(dr->out_table), out_language);
  1812.  
  1813.   /* assoc driver */
  1814.   init_driver(dr,driver);
  1815.  
  1816.   configuring = FALSE;
  1817.   configside = VOID;
  1818.  
  1819.   /* initialise output file */
  1820.   output_init(dr);
  1821.  
  1822.   if (error_flag)
  1823.     fatal((stderr,"\nToo many errors"));
  1824.  
  1825.   /* allocation of board descriptor */
  1826.   tos = new_board();
  1827.   init_board(tos);
  1828.  
  1829.   /* allocation of move descriptor */
  1830.   m = new_move();
  1831.   m->type = VOID ;
  1832.   /*init_move(m);*/
  1833.   
  1834.   /* allocation of the play descriptor */
  1835.   theplay = (play *) malloc (sizeof(play)) ;
  1836.   theplay->initial = tos ;
  1837.   theplay->chain   = m ;
  1838.   movecount = 1;
  1839.  
  1840.   /* main analysis routine */
  1841.   yyin = infile ;
  1842.   yyout = stderr ;
  1843.  
  1844.   /*init_parse(m); */
  1845.   yylex();
  1846.  
  1847.   if ((count == 0) && !error_flag)
  1848.     output_board(dr,tos);
  1849.  
  1850.   if (error_flag) {
  1851.     error((stderr,"\nLast valid position:\n"));
  1852.     output_board(dr,tos);
  1853.     fatal((stderr,"\nToo many errors"));
  1854.   }
  1855.       
  1856.   /* terminates output files */
  1857.   output_end(dr);
  1858.  
  1859.   /* close files */
  1860.   close_files();
  1861.  
  1862.   /* exit properly */
  1863. #ifdef __STDC__
  1864. #else
  1865.   exit(0);
  1866. #endif
  1867. }
  1868.