home *** CD-ROM | disk | FTP | other *** search
- /* Programme d'analyse de notation echiquienne
- Copyright (C) 1990 Henry Thomas
- Nom: notation.c
- Auteur: Henry Thomas
- Date: 27/11/90
- */
- /* @(#)notation.c 2.1 4/11/91 (C) Henry Thomas */
- /*
- This file is part of NOTATION program.
-
- NOTATION is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- NOTATION is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with NOTATION; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* --------------------- data part ---------------------- */
-
- /* les tableaux suivants sont les tables de transcription de notation
- selon les langages
- */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "chesstype.h"
- #include "drivers.h"
- #include "notation.h"
- #include "lexer.h"
-
- extern void close_files();
-
-
- char * version_string =
- "@(#)notation.c 2.1 (C) Henry Thomas\tVersion 2.1\tDated 4/11/91";
-
- static char * keywords[]= {
- "@startplay" , "@clearboard" , "@showboard" ,
- "@whitesmove", "@blacksmove", "@configwhite", "@configblack" ,
- "@default" , "@special", "@null"
- };
-
- int configuring = FALSE ;
- int configside = 0 ;
-
-
- static char * t_language[] = {
- "french", "english", "italian", "spanish", "german", "dutch" };
-
- static int in_language = DEFAULT_INPUT_LANGUAGE ;
- static int out_language = DEFAULT_OUTPUT_LANGUAGE ;
-
- static char c_french[] = { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' } ;
- static char c_english[] = { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' } ;
- static char c_italian[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ;
- static char c_spanish[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ;
- static char c_german[] = { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' } ;
- static char c_dutch[] = { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' } ;
- static char c_russian[] = { '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' } ;
-
-
- /* translation tables */
- char *in_table;
-
-
- char * c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" };
-
- /* various notations for en passant */
- #define N_EP 2
- char * c_en_passant[] = { "ep" , "e.p." } ;
-
-
- /* notation for catch */
- char c_prise ='x';
-
- /* various comments */
- char * c_comments[] = { "+" , "++" ,
- "?" , "??", "!", "!!", "!?", "?!",
- "mate", "draw" };
-
- /* movement tables */
- /* move only */
- /* white pawn, move */
- #define NB_M_PAWN_MOVE_WD 2
- static int m_pawn_move_wd [][2] = {
- { 1, 0}, {2, 0}
- };
-
- /* black pawn, move */
- #define NB_M_PAWN_MOVE_BD 2
- static int m_pawn_move_bd [][2] = {
- {-1, 0}, {-2, 0}
- };
-
- /* TRICK = we have added the catching move at the end of
- the non catching ones; so in check_depl, we try first
- the non catching one and then the catching one.
- So, even if catching (x) is non indicated in the input,
- we succeed in guessing the move
- */
- /* white pawn, move */
- /*#define NB_M_PAWN_WD 2*/
- #define NB_M_PAWN_WD 4
- static int m_pawn_wd [][2] = {
- { 1, 0}, {2, 0},
- /* catch... */
- { 1, 1}, { 1,-1}
- };
-
- /* white pawn, catch */
- #define NB_M_PAWN_WX 2
- static int m_pawn_wx [][2] = {
- { 1, 1}, { 1,-1}
- };
-
- /* black pawn, move */
- /*#define NB_M_PAWN_BD 2*/
- #define NB_M_PAWN_BD 4
- static int m_pawn_bd [][2] = {
- {-1, 0}, {-2, 0},
- /* catch... */
- {-1, 1}, {-1,-1}
- };
-
- /* black pawn, catch */
- #define NB_M_PAWN_BX 2
- static int m_pawn_bx [][2] = {
- {-1, 1}, {-1,-1}
- };
-
-
- #define NB_M_KNIGHT 8
- static int m_knight[][2] = {
- { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1},
- { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2}
- };
-
- #define NB_M_BISHOP 28
- static int m_bishop[][2] = {
- { 7, 7}, {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
- { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
- {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
- {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}
- };
-
- #define NB_M_ROOK 28
- static int m_rook[][2] = {
- { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
- {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
- { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
- { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
- };
-
- #define NB_M_QUEEN 56
- static int m_queen[][2] = {
- { 7, 7}, {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
- { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
- {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
- {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1},
- { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
- {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
- { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
- { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
- };
-
- #define NB_M_KING 8
- static int m_king[][2] = {
- { 1, 1}, { 1, 0}, { 1,-1},
- {-1, 1}, {-1, 0}, {-1,-1},
- { 0, 1}, { 0, -1}
- };
-
-
- /* I/O */
- FILE * infile ;
- FILE * fhelp;
-
- static char * t_output[] =
- { "ascii", "postscript", "tex", "roff", "xchess", "gnu" };
-
-
- /* ---------- automata definitions --------- */
- /* table for syntaxic analysis of move */
-
- #define FINAL 10
- #define TML FINAL /* terminal state */
- #define NBETAT 11
- #define NBCLAS 8
-
- /* successor of state */
- static int transit[NBETAT][NBCLAS] = {
- /* P a-h 1-8 - x = \0 ? */
- /*( 0 1 2 3 4 5 6 7)*/
- { 1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 0 */
- { -1, 2, -1, -1, 4, -1, -1, -1 }, /* etat 1 */
- { -1, 6, 3, 4, 4, 8,TML,TML }, /* etat 2 */
- { -1, 6, -1, 4, 4, 8,TML,TML }, /* etat 3 */
- { 5, 6, -1, -1, -1, -1, -1, -1 }, /* etat 4 */
- { -1, 6, -1, -1, -1, -1, -1, -1 }, /* etat 5 */
- { -1, -1, 7, -1, -1, -1, -1, -1 }, /* etat 6 */
- { -1, -1, -1, -1, -1, 8,TML,TML }, /* etat 7 */
- { 9, -1, -1, -1, -1, -1, -1, -1 }, /* etat 8 */
- { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat 9 */
- { -1, -1, -1, -1, -1, -1, -1, -1 } /* etat 10 == terminal */
- };
-
- /* actions to do */
- static int action[NBETAT][NBCLAS] = {
- /* P a-h 1-8 - x = \0 ? */
- { 1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 0 */
- { -1, 2, -1, -1, 10, -1, -1, -1 }, /* etat 1 */
- { -1, 13, 3, 4, 5, 14, 6, 7 }, /* etat 2 */
- { -1, 13, -1, 4, 5, 14, 6, 7 }, /* etat 3 */
- { 1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 4 */
- { -1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 5 */
- { -1, -1, 3, -1, -1, -1, -1, -1 }, /* etat 6 */
- { -1, -1, -1, -1, -1, 14, 8, 9 }, /* etat 7 */
- { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat 8 */
- { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat 9 */
- { -1, -1, -1, -1, -1, -1, -1, -1 } /* etat 10 */
- };
-
-
-
- /* current game
- the name "tos" means "top of stack"
- */
- static game * tos = GULL ;
-
- /* array to see the king is in check
- use in checkroque()
- */
-
-
- /* booleen d'erreur */
- int error_flag = FALSE;
-
-
- /* move to display board */
- static int count = 0 ;
-
-
- static int move_to_display[NB_MOVE_TO_DISP] ;
- static int nb_move_to_dsp = 0;
- static int stop_at_display = FALSE;
-
- /* variable holding current move */
- static depl * m = MULL ;
-
- /* current move, used by the parser */
- static int curpiece, curcol, curlig ;
- static int curdigit, curmove;
-
- static format * dr;
-
- static int driver; /* driver type, ie gnu, ascii ... */
-
- #define setboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = (P) ; \
- (A)->color[(I)][(J)] = (C);})
- #define clsboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = VOID ; \
- (A)->color[(I)][(J)] = VOID; }))
-
- /* --------------------------- code part --------------------- */
-
-
- static int ispiece(c)
- char c;
- {
- register int i;
-
- for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
- /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
- return(i<NUMPIECES);
- }
-
-
- static int piece(c)
- char c ;
- {
- register int i;
-
- for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
- if ( i== NUMPIECES)
- i = PAWN ;
- return(i);
- }
-
- /* this function return yhe # entry of a keyword in a given table.
- if key is not present, it returns the default value
- */
- static int find_keyword(tab, nbentry,defaut,key)
- char * tab[];
- int nbentry;
- int defaut;
- char *key;
- {
- int i ;
-
- for(i=0; (i< nbentry) ;i++)
- if (strcmp(tab[i],key)==0)
- return(i);
-
- /* we failed to find the keyword */
- (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
- return(defaut);
- }
-
- /* ---------- board management function ------------- */
-
- void clear_board(g)
- game *g;
- {
- register int i,j;
-
- for (i=0; i < 10; i++ )
- for (j=0 ; j< 10 ; j++) {
- g->board[i][j] = VOID;
- g->color[i][j] = VOID;
- }
- }
-
- game * new_board()
- {
- game * tmp;
- int i;
-
- tmp = (game *) malloc (sizeof(game));
- ALLOCP(tmp);
- /*for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
- ((int *) tmp)[i] = 0;*/
- return(tmp);
- }
-
- void init_board(tgm)
- game * tgm;
- {
- register int i,j;
-
- clear_board(tgm);
-
- for (i=1; i< 9 ; i=i+7) {
- tgm->board[i][1]= tgm->board[i][8] = ROOK ;
- tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
- tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
- tgm->board[i][4]= QUEEN;
- tgm->board[i][5]= KING;
- }
- for (i=2; i< 8 ; i=i+5)
- for (j=1; j <=8 ; j++)
- tgm->board[i][j] = PAWN;
-
- for (i=1; i <=2; i++)
- for (j=1; j <=8 ; j++) {
- tgm->color[i][j] = WHITE;
- tgm->color[i+6][j] = BLACK ;
- }
- }
-
- depl * new_move()
- {
- depl * tmp;
- int i;
-
- tmp = (depl *) malloc (sizeof(depl));
- ALLOCP(tmp);
- /*for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
- ((int *) tmp)[i] = 0;*/
- return(tmp);
- }
-
-
- void init_move(m)
- depl *m;
- {
- m->move= 1 ;
- m->whiteturn = TRUE ;
- }
-
- /* ----------- semantic evaluation of move ----------- */
- /* check if position lies within the board
- */
- int in_board(l,c)
- int l,c;
- {
- return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
- }
-
- /* check that the path from pos1 to pos2 is free
- */
- int path_free(l1, c1, l2, c2)
- int l1,c1, l2, c2;
- {
- int li = 1 ;
- int ci = 1 ;
- int lig, col;
-
-
- li = SIGN(l2-l1);
- ci = SIGN(c2-c1);
-
-
- if ( c1 == c2 ) {
- col = c1;
- for (lig = l1 +li; lig != l2 ; lig +=li)
- if (tos->board[lig][col] != VOID)
- return (FALSE);
- return(TRUE);
- }
-
- if ( l1 == l2) {
- lig = l1 ;
- for (col = c1 + ci; col != c2 ; col +=ci)
- if (tos->board[lig][col] != VOID)
- return (FALSE);
- return(TRUE);
- }
-
- for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
- if (tos->board[lig][col] != VOID) {
- return (FALSE);
- }
- return(TRUE);
- }
-
- /* check roque is possible */
- int check_roque()
- {
- int lig, col ;
-
- if (m->whiteturn)
- lig = 1 ;
- else
- lig =8;
- if (m->type == GRANDROQUE)
- for (col = 2; col < 5 ; col++)
- if (tos->board[lig][col] != VOID)
- return(FALSE);
- if (m->type == PETITROQUE)
- for (col = 6; col < 7 ; col++)
- if (tos->board[lig][col] != VOID)
- return(FALSE);
- if (m->is_check[CURCOLOR(m)])
- return(FALSE);
- return(TRUE);
- }
-
- /* check -- or guess -- where a given piece come */
- int guess_piece() {return(tos->board[m->fromlig][m->fromcol]); }
-
- /* try to guess the move -- low-level function */
- int guess_depl(nb, tab, pl1, pc1, l2,c2,path)
- int nb;
- int tab[][2];
- int *pl1, *pc1;
- int l2,c2;
- int path;
- {
- int i;
- int c,l;
-
- for (i=0; i< nb; i++ ) {
- l = l2 - tab[i][0];
- c = c2 - tab[i][1];
- if (in_board(l,c))
- if ((tos->board[l][c] == m->piece) &&
- (tos->color[l][c] == CURCOLOR(m)) &&
- ( !path || (path && path_free(l,c, l2, c2))) &&
- ( ((*pl1) == 0) || ((*pl1) == l) ) &&
- ( ((*pc1) == 0) || ((*pc1) == c) ) )
- {
- *pl1 = l;
- *pc1 = c;
- return(TRUE);
- }
- }
- return(FALSE);
- }
-
- /* check for ambiguitey in a move
- used in ouptut function: the piece had beenm already moved and
- if we guess another move, there is an ambiguity
- */
- int ambiguity(frompiece, l2, c2)
- int frompiece, l2, c2 ;
- {
- int l1 = 0 ;
- int c1 = 0 ;
-
- switch(frompiece) {
- case PAWN:
- if (m->type == PRISE) {
- if (m->whiteturn)
- return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE));
- else
- return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE));
- } else {
- if (m->whiteturn)
- return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd,
- &l1,&c1, l2,c2, FALSE));
- else
- return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd,
- &l1,&c1, l2,c2, FALSE));
- }
- /* break; */
- case KNIGHT:
- return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
- /* break; */
- case BISHOP:
- return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
- /* break; */
- case ROOK:
- return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
- /* break; */
- case QUEEN:
- return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
- /* break; */
- case KING:
- return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
- /* break; */
- default:
- break;
- }
- return(TRUE);
- }
-
- int check_move(m)
- depl * m;
- {
- int l1,c1,l2,c2,l;
- int tmp; /* tmp boolean */
-
- l1 = m->fromlig;
- c1 = m->fromcol;
- l2 = m->tolig;
- c2 = m->tocol;
-
- if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
- return(check_roque());
-
- if ((tos->board[l1][c1] != m->piece)||
- (tos->color[l1][c1] != CURCOLOR(m))){
- printf("==%d\n",tos->board[l1][c1]);
- error ((stderr,"from position and piece not correct\n"));
- return(FALSE);
- }
-
- /* if prise === FALSE, we must not take a piece */
- if (tos->board[l2][c2] != VOID
- && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
- (void) fprintf(stderr,"catching not indicated at move %d\n",m->move);
- return(FALSE);
- }
-
- /* prendre une de ses propres pieces */
- if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
- (void) fprintf(stderr,"attempt to catch same color piece at move %d\n",
- m->move);
- return(FALSE);
- }
-
- /* we check if the move is a possible one for the piece
- */
-
- switch(m->piece) {
- case PAWN:
- if (m->prise) {
- if (m->whiteturn)
- tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
- else
- tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
- } else {
- if (m->whiteturn)
- tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
- else
- tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
- }
- /* is it a "prise en passant " */
- if ((c1 != c2) && (tos->board[l2][c2] == VOID)
- && (tos->board[l1][c2] == PAWN)) {
- m->type = EN_PASSANT ;
- l = l1 + (l2 - l1)/2;
- /* we must perform here the "en passant" test */
- tos->board[l1][c2] = VOID ;
- tos->color[l1][c2] = VOID ;
- tmp = TRUE;
- }
- return(tmp);
- /* break; */
- case KNIGHT:
- return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
- /* break; */
- case BISHOP:
- return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
- /* break; */
- case ROOK:
- return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
- /* break; */
- case QUEEN:
- return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
- /* break; */
- case KING:
- return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
- /* break; */
- default:
- break;
- }
-
- return(TRUE);
- }
-
- /* try to guess the move -- used for shortened notation
- */
- int guess_move()
- {
- int l1,c1,l2,c2;
-
- if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
- return(TRUE);
-
- l1 = m->fromlig ;
- c1 = m->fromcol ;
- l2 = m->tolig;
- c2 = m->tocol;
-
- switch(m->piece) {
- case PAWN:
- if (m->prise) {
- if (m->whiteturn)
- (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
- else
- (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
- } else {
- if (m->whiteturn)
- (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
- else
- (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
- }
- break;
- case KNIGHT:
- (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
- break;
- case BISHOP:
- (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
- break;
- case ROOK:
- (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
- break;
- case QUEEN:
- (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
- break;
- case KING:
- (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
- break;
- default:
- break;
- }
-
- if ((l1 == 0) || (c1 == 0)) {
- if (m->whiteturn)
- error((stderr,"unable to guess move %d white (%d)\n",
- m->move,m->piece));
- else
- error((stderr,"unable to guess move %d black (%d)\n",
- m->move,m->piece));
- return(FALSE);
- } else {
- m->fromcol = c1;
- m->fromlig = l1;
- return(TRUE);
- }
- }
-
- /* --------------- execution of move ----------------- */
-
- /* clear a position */
- int clear_pos(lig,col)
- int lig;
- int col;
- {
- tos->board[lig][col] = VOID ;
- tos->color[lig][col] = VOID ;
- return(TRUE);
- }
-
- /* configure the board */
- int configure()
- {
- if (configuring) {
- if (m->piece == VOID)
- m->piece = PAWN ;
- tos->board[m->tolig][m->tocol] = m->piece ;
- tos->color[m->tolig][m->tocol] = configside ;
- }
- return(TRUE);
- }
-
- /* execute a move, no checking */
- int execute_move()
- {
- register int i;
-
- if (m->piece == VOID )
- m->piece = PAWN;
-
- if ((m->fromlig == 0) || (m->fromcol == 0))
- (void) guess_move();
-
- /* supply to the -- maybe -- deficiency of input notation
- */
- if ((m->fromlig !=0) || (m->fromcol != 0))
- m->piece = tos->board[m->fromlig][m->fromcol];
-
- if (tos->board[m->tolig][m->tocol] != VOID) {
- m->type = PRISE;
- m->prise = tos->board[m->tolig][m->tocol] ;
- }
-
- if (!check_move(m)) {
- if (m->whiteturn)
- error((stderr,"white move %d illegal\n",m->move));
- else
- error((stderr,"black move %d illegal\n",m->move));
- }
-
- if (m->type == PETITROQUE) {
- if (m->whiteturn)
- curlig = 1 ;
- else
- curlig = 8 ;
- tos->board[curlig][7] = KING;
- tos->board[curlig][6] = ROOK;
- tos->color[curlig][7] = tos->color[curlig][5] ;
- tos->color[curlig][6] = tos->color[curlig][5] ;
- (void) clear_pos(curlig, 5);
- (void) clear_pos(curlig, 8);
- }
- if (m->type == GRANDROQUE) {
- if (m->whiteturn)
- curlig = 1 ;
- else
- curlig = 8 ;
- tos->board[curlig][3] = KING;
- tos->board[curlig][4] = ROOK;
- tos->color[curlig][3] = tos->color[curlig][5] ;
- tos->color[curlig][4] = tos->color[curlig][5] ;
- (void) clear_pos(curlig, 5);
- (void) clear_pos(curlig, 1);
- }
-
-
- if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) {
- if (m->piece == VOID)
- m->piece = tos->board[m->fromlig][m->fromcol];
- /*if (m->topiece == VOID)
- m->topiece = tos->board[m->fromlig][m->fromcol];*/
- tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol];
- tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol];
- (void) clear_pos(m->fromlig,m->fromcol);
- }
-
- if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE))
- tos->board[m->tolig][m->tocol] = m->promotion ;
-
- output_move(dr,m);
-
- if (error_flag) {
- (void) fprintf(dr->outfile, "\nlast position encountered:\n");
- output_board(dr,tos);
- close_files();
- exit(0);
- }
-
- /* do we need to display the move ? */
- if (nb_move_to_dsp > 0) {
- for (i=0; i < nb_move_to_dsp; i++)
- if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
- output_board(dr,tos);
- if (stop_at_display) {
- output_end(dr);
- close_files();
- exit(0);
- }
- }
- }
-
- return(TRUE);
- }
-
- /* ------------------ automata ----------------------- */
-
- /* categorise the input for the automata */
- int typechar(c)
- char c;
- {
- if (ispiece(c))
- return(0);
- if ((c >= 'a') && ( c <= 'h'))
- return(1);
- if ((c >= '1') && ( c <= '8'))
- return(2);
- if ( c== '-' )
- return(3);
- if ((c == 'x') || (c == 'X' ))
- return(4);
- if (c == '=' )
- return(5);
- if (c == '\0' )
- return(6);
- return(7);
- }
-
-
- /* execute the actions decided by the automata */
- int execute(num,c)
- int num;
- char c;
- {
- switch (num) {
- case 1: /* set cur piece */
- curpiece = piece(c);
- break;
- case 2: /* set cur col */
- curcol = lettertocol(c);
- break;
- case 3: /* set cur lig */
- curlig = lettertolig(c);
- break;
- case 4: /* from = cur ; prise = false */
- m->piece = curpiece ;
- m->fromcol = curcol ;
- m->fromlig = curlig;
- /*m->topiece = curpiece;*/
- break;
- case 5: /* from = cur ; prise = true */
- m->piece = curpiece ;
- m->fromcol = curcol ;
- m->fromlig = curlig;
- m->type = PRISE ;
- m->prise = curpiece;
- break;
- case 6: /* to = cur ; guess from */
- case 7: /* to = cur ; guess from ; parse remaining token */
- m->piece = curpiece ;
- m->tocol = curcol;
- m->tolig = curlig ;
-
- /*m->topiece = curpiece ; /* ? */
-
- if (configuring)
- (void) configure();
- else {
- (void) execute_move();
- m->whiteturn = !m->whiteturn ;
- if (m->whiteturn) m->move++ ;
- }
- break;
- case 8: /* to = cur */
- case 9: /* to = cur */
- m->tocol = curcol;
- m->tolig = curlig ;
- /*m->topiece = curpiece ;*/
-
- if (configuring)
- (void) configure();
- else {
- (void) execute_move();
- m->whiteturn = !m->whiteturn ;
- if (m->whiteturn) m->move++ ;
- }
- break;
- case 10: /* piece = cur piece ; prise = true */
- /* later : guess from position */
- m->piece = curpiece ;
- m->type = PRISE ;
- break;
- case 11: /* grand roque */
- case 12: /* petit roque */
-
- (void) execute_move();
-
- m->whiteturn = !m->whiteturn ;
- if (m->whiteturn) m->move++ ;
- break;
- case 13: /* case of simpliest algebraic notation ;
- only e2e4 : this is the transition from e2 to e4
- also the case of move such as Nge2
- from =cur; prise = FALSE;
- also:
- curcol = ...
- */
- m->piece = curpiece ;
- m->fromcol = curcol ;
- m->fromlig = curlig;
- /*m->topiece = curpiece;*/
- m->type = MOVE;
- curcol = lettertocol(c);
- case 14: /* promotion, the "=" */
- break;
- case 15: /* promotion, the piece name */
- /* to = cur ; guess from */
- case 16:
- /* to = cur */
-
- m->tocol = curcol;
- m->tolig = curlig ;
- /*m->topiece = curpiece ;*/
-
- if (m->type == PRISE )
- m->type = PROM_ET_PRISE ;
- else
- m->type = PROMOTION ;
- m->promotion = curpiece = piece(c) ;
-
- break;
- case 17: /* execute move for promotion */
- (void) execute_move();
-
- m->whiteturn = !m->whiteturn ;
- if (m->whiteturn) m->move++ ;
- break;
- case -1:
- break;
- default:
- break;
- }
- return(TRUE);
- }
-
- int parse_number(token)
- char *token;
- {
- int curmove = 0 ;
- int i;
-
- /* check coherency with internal numbering */
- i = 0;
- while (isdigit(token[i])) {
- curmove = curmove * 10 + ((int) token[i++] - (int) '0' );
- }
- if (curmove != m->move)
- (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
- m->move, curmove);
- return(TRUE);
- }
-
- int parse_keyword(token)
- char *token;
- {
- char c;
-
- switch (find_keyword(keywords, NBKEYWORD, KNULL, token)) {
- case START:
- configuring = FALSE;
- m->move = 1;
- m->whiteturn = TRUE;
- break;
- case CLEAR:
- clear_board(tos);
- break;
- case SHOWBOARD:
- output_board(dr,tos);
- break;
- case TOWHITE:
- m->move = 1;
- m->whiteturn = TRUE;
- break;
- case TOBLACK:
- m->move = 1;
- m->whiteturn = FALSE;
- break;
- case CONFIGWH:
- configuring = TRUE ;
- configside = WHITE;
- break;
- case CONFIGBL:
- configuring = TRUE ;
- configside = BLACK;
- break;
- case DEFAULTP:
- init_board(tos);
- break;
- case SPECIAL: /* all input, up to \n is copied to output */
- while ((( c = getc(infile)) != EOF) && (c != '\n'))
- (void) putc (c,dr->outfile);
- putc ('\n', dr->outfile);
- break;
- case KNULL:
- default:
- break;
- }
- return(TRUE);
- }
-
- int parse_roque(token)
- char * token;
- {
- int i;
-
- for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
- if ( i < NBROQUE ) {
- if (strlen(token) == 3) {
- m->type = PETITROQUE ;
- (void) execute(12,DUMMYCHAR);
- } else {
- m->type = GRANDROQUE ;
- (void) execute(11,DUMMYCHAR);
- }
- /*(void) fprintf(stderr,"ROQUE\n");*/
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- int parse_move(token)
- char *token;
- {
- register int i;
- int correcte = FALSE ;
- int erreursyntaxe = FALSE ;
- int etat =0;
- int code;
-
- i=0;
- while ( !correcte && !erreursyntaxe ) {
- code = typechar(token[i]);
- (void) execute(action[etat][code],token[i]);
- etat = transit[etat][code] ;
- if (etat == -1)
- erreursyntaxe = TRUE;
- if (etat == FINAL)
- correcte = TRUE ;
- i++;
- }
- if (erreursyntaxe) {
- (void) fprintf(stderr, "no comprende, senor: %s\n",token);
- return(FALSE);
- }
- if (correcte) {
- /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
- }
- return(TRUE);
- }
-
- void init_parse(m)
- depl * m ;
- {
- int i;
-
- /* global position and piece variable initialised to 0
- */
- /* move and whiteturn unchanged */
-
- m->type = MOVE ;
-
- curpiece = m->piece = VOID ;
- curcol = m->tocol = m->fromcol = 0;
- curlig = m->tolig = m->fromlig = 0;
-
- m->promotion = VOID;
- m->prise = VOID;
-
- for (i=0; i< 3; i++)
- m->is_check[i] = FALSE ;
- curdigit = curmove = 0;
- }
-
- /* ------------------- top routines -------------------- */
-
- /* cette fonction analyse les arguments de la ligne de commande
- */
- int parse_options(argc,argv)
- int argc;
- char * argv[];
- {
- int narg =1 ;
- int i;
- register int c;
- char cp[132];
- char chaine[MAXTOKLEN];
-
- infile = stdin;
- dr->outfile = stdout;
- nb_move_to_dsp = 0;
-
- while (narg < argc ) {
- (void) strcpy (cp,argv[narg]);
- switch (cp[0]) {
- case '-' :
- switch (cp[1]) {
- case 'f' : /* from langage */
- if ((narg+1) >= argc )
- fatal((stderr,"missing argument to %s option",cp));
- narg++ ;
- in_language = find_keyword (t_language, NBLANGUAGE,
- DEFAULT_INPUT_LANGUAGE,
- argv[narg]);
- break;
- case 't' : /* to langage */
- if ((narg+1) >= argc )
- fatal((stderr,"missing argument to %s option",cp));
- narg++ ;
- out_language = find_keyword (t_language, NBLANGUAGE,
- DEFAULT_OUTPUT_LANGUAGE,
- argv[narg]);
- break;
- case 'o' : /* next arg is output file */
- narg++ ;
- if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
- (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
- (void) fprintf (stderr,"assume stdout for output\n");
- }
- break;
- case 'e':
- if ((narg+1) >= argc )
- fatal((stderr,"missing argument to %s option",cp));
- narg++ ;
-
- i=0;
- nb_move_to_dsp = 0;
- move_to_display[nb_move_to_dsp] = 0;
- while (isdigit(argv[narg][i])) {
- move_to_display[nb_move_to_dsp] =
- ((int) argv[narg][i] - (int) '0')
- + move_to_display[nb_move_to_dsp] * 10;
- i++;
- }
- nb_move_to_dsp++;
- stop_at_display = TRUE;
- break;
- case 'c':
- if ((narg+1) >= argc )
- fatal((stderr,"missing argument to %s option",cp));
- narg++ ;
-
- i=0;
- while (isdigit(argv[narg][i])) {
- move_to_display[nb_move_to_dsp] = 0;
- while (isdigit(argv[narg][i])) {
- move_to_display[nb_move_to_dsp] =
- ((int) argv[narg][i] - (int) '0')
- + move_to_display[nb_move_to_dsp] * 10;
- i++;
- }
- nb_move_to_dsp++;
-
- if (nb_move_to_dsp > NB_MOVE_TO_DISP)
- fatal((stderr,"max. number of move to display exceeded"));
-
- /* process next number */
- if (argv[narg][i] == ',')
- i++;
- }
- break;
- case 'a': /* algebraic output */
- dr->output_move_format = ALGEBRAIC;
- break;
- case 's': /* shortened output */
- dr->output_move_format = SHORTENED;
- break;
- case 'b': /* display only the board, no move */
- dr->only_board = TRUE;
- break;
- case 'd': /* output driver */
- if ((narg+1) >= argc )
- fatal((stderr,"missing argument to %s option",cp));
- narg++ ;
- driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
- argv[narg]);
- break;
- case 'h': /* help file */
- (void) strcpy(chaine,LIB_DIR);
- if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
- fatal((stderr,"Can't find help file.\n"));
- else {
- while ((c = getc(fhelp)) != EOF)
- (void) fputc(c,stderr);
- (void) fclose(fhelp);
- exit(0);
- }
- break;
- default:
- error((stderr,"unknown command line options %s\n",cp));
- break;
- }
- break;
- default: /* assume this is the input file */
- if ((infile = fopen (cp,"r")) == NULL)
- fatal((stderr,"can't open %s input file\n",cp));
- }
- narg++;
- } /* process next arg */
- return(argc);
- }
-
- void close_files()
- {
- if (infile != stdin )
- (void) fclose(infile);
- if (dr->outfile != stdout )
- (void) fclose(dr->outfile);
- }
-
- int associe_traduction (table, langage)
- char ** table;
- int langage ;
- {
- switch (langage) {
- case FRENCH :
- *table = c_french ;
- break;
- case ENGLISH:
- *table = c_english ;
- break;
- case ITALIAN:
- *table = c_italian ;
- break;
- case SPANISH:
- *table = c_spanish ;
- break;
- case GERMAN:
- *table = c_german ;
- break;
- case DUTCH:
- *table = c_dutch ;
- break;
- case RUSSIAN:
- (void) fprintf(stderr,"russian not yet implemented\n");
- *table = c_russian ;
- break;
- default:
- error((stderr,"unknown langage\n"));
- }
- return(langage);
- }
-
- /* ------------- main --------------------- */
-
- main(argc,argv)
- int argc;
- char * argv[];
- {
- (void) fprintf(stderr,"%s\n",version_string);
-
- /* allocation of driver descriptor */
- dr = new_driver();
-
- /* default configuration */
- init_driver(dr,DEFAULT_DRIVER);
- (void) associe_traduction(&in_table, DEFAULT_INPUT_LANGUAGE );
- (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
-
- (void) parse_options(argc,argv);
-
- (void) associe_traduction (&in_table, in_language);
- (void) associe_traduction (&(dr->out_table), out_language);
-
- /* assoc driver */
- init_driver(dr,driver);
-
- configuring = FALSE;
- configside = VOID;
-
- /* initialise output file */
- output_init(dr);
-
- if (error_flag)
- fatal((stderr,"too many errors"));
-
- /* allocation of move descriptor */
- m = new_move();
- init_move(m);
-
- /* allocation of board descriptor */
- tos = new_board();
- init_board(tos);
-
- /*output_board(dr,tos);*/
-
- while (nexttoken()) {
- /*(void) fprintf(stdout,"%s%\n", curtok);*/
- init_parse(m);
- (void) parsetoken();
- }
- if ((count == 0) && !error_flag)
- output_board(dr,tos);
-
- if (error_flag) {
- error((stderr,"last valid position:\n"));
- output_board(dr,tos);
- fatal((stderr,"too many errors"));
- }
-
- /* terminates output files */
- output_end(dr);
-
- /* close files */
- close_files();
-
- /* exit properly */
- #ifdef TURBOC
- return(TRUE);
- #else
- exit(0);
- #endif
- }
-