hthomas@irisa.fr (Henry Thomas) (04/12/91)
Submitted-by: Henry Thomas <hthomas@irisa.fr> Posting-number: Volume 18, Issue 14 Archive-name: notation/part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 3)." # Contents: notation.c # Wrapped by hthomas@illico on Thu Apr 11 14:44:55 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'notation.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'notation.c'\" else echo shar: Extracting \"'notation.c'\" \(31006 characters\) sed "s/^X//" >'notation.c' <<'END_OF_FILE' X/* Programme d'analyse de notation echiquienne X Copyright (C) 1990 Henry Thomas X Nom: notation.c X Auteur: Henry Thomas X Date: 27/11/90 X */ X/* @(#)notation.c 2.1 4/11/91 (C) Henry Thomas */ X/* XThis file is part of NOTATION program. X XNOTATION is free software; you can redistribute it and/or modify Xit under the terms of the GNU General Public License as published by Xthe Free Software Foundation; either version 1, or (at your option) Xany later version. X XNOTATION is distributed in the hope that it will be useful, Xbut WITHOUT ANY WARRANTY; without even the implied warranty of XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the XGNU General Public License for more details. X XYou should have received a copy of the GNU General Public License Xalong with NOTATION; see the file COPYING. If not, write to Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ X X/* --------------------- data part ---------------------- */ X X/* les tableaux suivants sont les tables de transcription de notation X selon les langages X */ X#include <stdio.h> X#include <string.h> X#include <ctype.h> X X#include "chesstype.h" X#include "drivers.h" X#include "notation.h" X#include "lexer.h" X Xextern void close_files(); X X Xchar * version_string = X "@(#)notation.c 2.1 (C) Henry Thomas\tVersion 2.1\tDated 4/11/91"; X Xstatic char * keywords[]= { X "@startplay" , "@clearboard" , "@showboard" , X "@whitesmove", "@blacksmove", "@configwhite", "@configblack" , X "@default" , "@special", "@null" X }; X Xint configuring = FALSE ; Xint configside = 0 ; X X Xstatic char * t_language[] = { X "french", "english", "italian", "spanish", "german", "dutch" }; X Xstatic int in_language = DEFAULT_INPUT_LANGUAGE ; Xstatic int out_language = DEFAULT_OUTPUT_LANGUAGE ; X Xstatic char c_french[] = { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' } ; Xstatic char c_english[] = { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' } ; Xstatic char c_italian[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ; Xstatic char c_spanish[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ; Xstatic char c_german[] = { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' } ; Xstatic char c_dutch[] = { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' } ; Xstatic char c_russian[] = { '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' } ; X X X/* translation tables */ Xchar *in_table; X X Xchar * c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" }; X X/* various notations for en passant */ X#define N_EP 2 Xchar * c_en_passant[] = { "ep" , "e.p." } ; X X X/* notation for catch */ Xchar c_prise ='x'; X X/* various comments */ Xchar * c_comments[] = { "+" , "++" , X "?" , "??", "!", "!!", "!?", "?!", X "mate", "draw" }; X X/* movement tables */ X/* move only */ X/* white pawn, move */ X#define NB_M_PAWN_MOVE_WD 2 Xstatic int m_pawn_move_wd [][2] = { X { 1, 0}, {2, 0} X}; X X/* black pawn, move */ X#define NB_M_PAWN_MOVE_BD 2 Xstatic int m_pawn_move_bd [][2] = { X {-1, 0}, {-2, 0} X}; X X/* TRICK = we have added the catching move at the end of X the non catching ones; so in check_depl, we try first X the non catching one and then the catching one. X So, even if catching (x) is non indicated in the input, X we succeed in guessing the move X */ X/* white pawn, move */ X/*#define NB_M_PAWN_WD 2*/ X#define NB_M_PAWN_WD 4 Xstatic int m_pawn_wd [][2] = { X { 1, 0}, {2, 0}, X/* catch... */ X { 1, 1}, { 1,-1} X}; X X/* white pawn, catch */ X#define NB_M_PAWN_WX 2 Xstatic int m_pawn_wx [][2] = { X { 1, 1}, { 1,-1} X}; X X/* black pawn, move */ X/*#define NB_M_PAWN_BD 2*/ X#define NB_M_PAWN_BD 4 Xstatic int m_pawn_bd [][2] = { X {-1, 0}, {-2, 0}, X/* catch... */ X {-1, 1}, {-1,-1} X}; X X/* black pawn, catch */ X#define NB_M_PAWN_BX 2 Xstatic int m_pawn_bx [][2] = { X {-1, 1}, {-1,-1} X}; X X X#define NB_M_KNIGHT 8 Xstatic int m_knight[][2] = { X { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1}, X { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2} X}; X X#define NB_M_BISHOP 28 Xstatic int m_bishop[][2] = { X { 7, 7}, {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1}, X { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1}, X {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1}, X {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1} X}; X X#define NB_M_ROOK 28 Xstatic int m_rook[][2] = { X { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0}, X {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, X { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1}, X { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1} X}; X X#define NB_M_QUEEN 56 Xstatic int m_queen[][2] = { X { 7, 7}, {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1}, X { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1}, X {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1}, X {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}, X { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0}, X {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0}, X { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1}, X { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1} X}; X X#define NB_M_KING 8 Xstatic int m_king[][2] = { X { 1, 1}, { 1, 0}, { 1,-1}, X {-1, 1}, {-1, 0}, {-1,-1}, X { 0, 1}, { 0, -1} X}; X X X/* I/O */ XFILE * infile ; XFILE * fhelp; X Xstatic char * t_output[] = X{ "ascii", "postscript", "tex", "roff", "xchess", "gnu" }; X X X/* ---------- automata definitions --------- */ X/* table for syntaxic analysis of move */ X X#define FINAL 10 X#define TML FINAL /* terminal state */ X#define NBETAT 11 X#define NBCLAS 8 X X/* successor of state */ Xstatic int transit[NBETAT][NBCLAS] = { X/* P a-h 1-8 - x = \0 ? */ X/*( 0 1 2 3 4 5 6 7)*/ X { 1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 0 */ X { -1, 2, -1, -1, 4, -1, -1, -1 }, /* etat 1 */ X { -1, 6, 3, 4, 4, 8,TML,TML }, /* etat 2 */ X { -1, 6, -1, 4, 4, 8,TML,TML }, /* etat 3 */ X { 5, 6, -1, -1, -1, -1, -1, -1 }, /* etat 4 */ X { -1, 6, -1, -1, -1, -1, -1, -1 }, /* etat 5 */ X { -1, -1, 7, -1, -1, -1, -1, -1 }, /* etat 6 */ X { -1, -1, -1, -1, -1, 8,TML,TML }, /* etat 7 */ X { 9, -1, -1, -1, -1, -1, -1, -1 }, /* etat 8 */ X { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat 9 */ X { -1, -1, -1, -1, -1, -1, -1, -1 } /* etat 10 == terminal */ X}; X X/* actions to do */ Xstatic int action[NBETAT][NBCLAS] = { X/* P a-h 1-8 - x = \0 ? */ X { 1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 0 */ X { -1, 2, -1, -1, 10, -1, -1, -1 }, /* etat 1 */ X { -1, 13, 3, 4, 5, 14, 6, 7 }, /* etat 2 */ X { -1, 13, -1, 4, 5, 14, 6, 7 }, /* etat 3 */ X { 1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 4 */ X { -1, 2, -1, -1, -1, -1, -1, -1 }, /* etat 5 */ X { -1, -1, 3, -1, -1, -1, -1, -1 }, /* etat 6 */ X { -1, -1, -1, -1, -1, 14, 8, 9 }, /* etat 7 */ X { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat 8 */ X { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat 9 */ X { -1, -1, -1, -1, -1, -1, -1, -1 } /* etat 10 */ X}; X X X X/* current game X the name "tos" means "top of stack" X */ Xstatic game * tos = GULL ; X X/* array to see the king is in check X use in checkroque() X */ X X X/* booleen d'erreur */ Xint error_flag = FALSE; X X X/* move to display board */ Xstatic int count = 0 ; X X Xstatic int move_to_display[NB_MOVE_TO_DISP] ; Xstatic int nb_move_to_dsp = 0; Xstatic int stop_at_display = FALSE; X X/* variable holding current move */ Xstatic depl * m = MULL ; X X/* current move, used by the parser */ Xstatic int curpiece, curcol, curlig ; Xstatic int curdigit, curmove; X Xstatic format * dr; X Xstatic int driver; /* driver type, ie gnu, ascii ... */ X X#define setboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = (P) ; \ X (A)->color[(I)][(J)] = (C);}) X#define clsboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = VOID ; \ X (A)->color[(I)][(J)] = VOID; })) X X/* --------------------------- code part --------------------- */ X X Xstatic int ispiece(c) X char c; X{ X register int i; X X for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ; X /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/ X return(i<NUMPIECES); X} X X Xstatic int piece(c) X char c ; X{ X register int i; X X for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ; X if ( i== NUMPIECES) X i = PAWN ; X return(i); X} X X/* this function return yhe # entry of a keyword in a given table. X if key is not present, it returns the default value X */ Xstatic int find_keyword(tab, nbentry,defaut,key) X char * tab[]; X int nbentry; X int defaut; X char *key; X{ X int i ; X X for(i=0; (i< nbentry) ;i++) X if (strcmp(tab[i],key)==0) X return(i); X X /* we failed to find the keyword */ X (void) fprintf (stderr, "unknow keyword %s in this context\n",key); X return(defaut); X} X X/* ---------- board management function ------------- */ X Xvoid clear_board(g) X game *g; X{ X register int i,j; X X for (i=0; i < 10; i++ ) X for (j=0 ; j< 10 ; j++) { X g->board[i][j] = VOID; X g->color[i][j] = VOID; X } X} X Xgame * new_board() X{ X game * tmp; X int i; X X tmp = (game *) malloc (sizeof(game)); X ALLOCP(tmp); X /*for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++) X ((int *) tmp)[i] = 0;*/ X return(tmp); X} X Xvoid init_board(tgm) X game * tgm; X{ X register int i,j; X X clear_board(tgm); X X for (i=1; i< 9 ; i=i+7) { X tgm->board[i][1]= tgm->board[i][8] = ROOK ; X tgm->board[i][2]= tgm->board[i][7] = KNIGHT ; X tgm->board[i][3]= tgm->board[i][6] = BISHOP ; X tgm->board[i][4]= QUEEN; X tgm->board[i][5]= KING; X } X for (i=2; i< 8 ; i=i+5) X for (j=1; j <=8 ; j++) X tgm->board[i][j] = PAWN; X X for (i=1; i <=2; i++) X for (j=1; j <=8 ; j++) { X tgm->color[i][j] = WHITE; X tgm->color[i+6][j] = BLACK ; X } X} X Xdepl * new_move() X{ X depl * tmp; X int i; X X tmp = (depl *) malloc (sizeof(depl)); X ALLOCP(tmp); X /*for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++) X ((int *) tmp)[i] = 0;*/ X return(tmp); X} X X Xvoid init_move(m) X depl *m; X{ X m->move= 1 ; X m->whiteturn = TRUE ; X} X X/* ----------- semantic evaluation of move ----------- */ X/* check if position lies within the board X */ Xint in_board(l,c) X int l,c; X{ X return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8)); X} X X/* check that the path from pos1 to pos2 is free X */ Xint path_free(l1, c1, l2, c2) Xint l1,c1, l2, c2; X{ X int li = 1 ; X int ci = 1 ; X int lig, col; X X X li = SIGN(l2-l1); X ci = SIGN(c2-c1); X X X if ( c1 == c2 ) { X col = c1; X for (lig = l1 +li; lig != l2 ; lig +=li) X if (tos->board[lig][col] != VOID) X return (FALSE); X return(TRUE); X } X X if ( l1 == l2) { X lig = l1 ; X for (col = c1 + ci; col != c2 ; col +=ci) X if (tos->board[lig][col] != VOID) X return (FALSE); X return(TRUE); X } X X for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci) X if (tos->board[lig][col] != VOID) { X return (FALSE); X } X return(TRUE); X} X X/* check roque is possible */ Xint check_roque() X{ X int lig, col ; X X if (m->whiteturn) X lig = 1 ; X else X lig =8; X if (m->type == GRANDROQUE) X for (col = 2; col < 5 ; col++) X if (tos->board[lig][col] != VOID) X return(FALSE); X if (m->type == PETITROQUE) X for (col = 6; col < 7 ; col++) X if (tos->board[lig][col] != VOID) X return(FALSE); X if (m->is_check[CURCOLOR(m)]) X return(FALSE); X return(TRUE); X} X X/* check -- or guess -- where a given piece come */ Xint guess_piece() {return(tos->board[m->fromlig][m->fromcol]); } X X/* try to guess the move -- low-level function */ Xint guess_depl(nb, tab, pl1, pc1, l2,c2,path) X int nb; X int tab[][2]; X int *pl1, *pc1; X int l2,c2; X int path; X{ X int i; X int c,l; X X for (i=0; i< nb; i++ ) { X l = l2 - tab[i][0]; X c = c2 - tab[i][1]; X if (in_board(l,c)) X if ((tos->board[l][c] == m->piece) && X (tos->color[l][c] == CURCOLOR(m)) && X ( !path || (path && path_free(l,c, l2, c2))) && X ( ((*pl1) == 0) || ((*pl1) == l) ) && X ( ((*pc1) == 0) || ((*pc1) == c) ) ) X { X *pl1 = l; X *pc1 = c; X return(TRUE); X } X } X return(FALSE); X} X X/* check for ambiguitey in a move X used in ouptut function: the piece had beenm already moved and X if we guess another move, there is an ambiguity X */ Xint ambiguity(frompiece, l2, c2) X int frompiece, l2, c2 ; X{ X int l1 = 0 ; X int c1 = 0 ; X X switch(frompiece) { X case PAWN: X if (m->type == PRISE) { X if (m->whiteturn) X return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE)); X else X return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE)); X } else { X if (m->whiteturn) X return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd, X &l1,&c1, l2,c2, FALSE)); X else X return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd, X &l1,&c1, l2,c2, FALSE)); X } X /* break; */ X case KNIGHT: X return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE)); X /* break; */ X case BISHOP: X return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE)); X /* break; */ X case ROOK: X return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE)); X /* break; */ X case QUEEN: X return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE)); X /* break; */ X case KING: X return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE)); X /* break; */ X default: X break; X } X return(TRUE); X} X Xint check_move(m) X depl * m; X{ X int l1,c1,l2,c2,l; X int tmp; /* tmp boolean */ X X l1 = m->fromlig; X c1 = m->fromcol; X l2 = m->tolig; X c2 = m->tocol; X X if ((m->type == GRANDROQUE) || (m->type == PETITROQUE)) X return(check_roque()); X X if ((tos->board[l1][c1] != m->piece)|| X (tos->color[l1][c1] != CURCOLOR(m))){ X printf("==%d\n",tos->board[l1][c1]); X error ((stderr,"from position and piece not correct\n")); X return(FALSE); X } X X /* if prise === FALSE, we must not take a piece */ X if (tos->board[l2][c2] != VOID X && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) { X (void) fprintf(stderr,"catching not indicated at move %d\n",m->move); X return(FALSE); X } X X /* prendre une de ses propres pieces */ X if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) { X (void) fprintf(stderr,"attempt to catch same color piece at move %d\n", X m->move); X return(FALSE); X } X X /* we check if the move is a possible one for the piece X */ X X switch(m->piece) { X case PAWN: X if (m->prise) { X if (m->whiteturn) X tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE); X else X tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE); X } else { X if (m->whiteturn) X tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); X else X tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); X } X /* is it a "prise en passant " */ X if ((c1 != c2) && (tos->board[l2][c2] == VOID) X && (tos->board[l1][c2] == PAWN)) { X m->type = EN_PASSANT ; X l = l1 + (l2 - l1)/2; X /* we must perform here the "en passant" test */ X tos->board[l1][c2] = VOID ; X tos->color[l1][c2] = VOID ; X tmp = TRUE; X } X return(tmp); X /* break; */ X case KNIGHT: X return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE)); X /* break; */ X case BISHOP: X return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE)); X /* break; */ X case ROOK: X return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE)); X /* break; */ X case QUEEN: X return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE)); X /* break; */ X case KING: X return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE)); X /* break; */ X default: X break; X } X X return(TRUE); X} X X/* try to guess the move -- used for shortened notation X */ Xint guess_move() X{ X int l1,c1,l2,c2; X X if ((m->type == GRANDROQUE) || (m->type == PETITROQUE)) X return(TRUE); X X l1 = m->fromlig ; X c1 = m->fromcol ; X l2 = m->tolig; X c2 = m->tocol; X X switch(m->piece) { X case PAWN: X if (m->prise) { X if (m->whiteturn) X (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE); X else X (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE); X } else { X if (m->whiteturn) X (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); X else X (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); X } X break; X case KNIGHT: X (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE); X break; X case BISHOP: X (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE); X break; X case ROOK: X (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE); X break; X case QUEEN: X (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE); X break; X case KING: X (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE); X break; X default: X break; X } X X if ((l1 == 0) || (c1 == 0)) { X if (m->whiteturn) X error((stderr,"unable to guess move %d white (%d)\n", X m->move,m->piece)); X else X error((stderr,"unable to guess move %d black (%d)\n", X m->move,m->piece)); X return(FALSE); X } else { X m->fromcol = c1; X m->fromlig = l1; X return(TRUE); X } X} X X/* --------------- execution of move ----------------- */ X X/* clear a position */ Xint clear_pos(lig,col) X int lig; X int col; X{ X tos->board[lig][col] = VOID ; X tos->color[lig][col] = VOID ; X return(TRUE); X} X X/* configure the board */ Xint configure() X{ X if (configuring) { X if (m->piece == VOID) X m->piece = PAWN ; X tos->board[m->tolig][m->tocol] = m->piece ; X tos->color[m->tolig][m->tocol] = configside ; X } X return(TRUE); X} X X/* execute a move, no checking */ Xint execute_move() X{ X register int i; X X if (m->piece == VOID ) X m->piece = PAWN; X X if ((m->fromlig == 0) || (m->fromcol == 0)) X (void) guess_move(); X X /* supply to the -- maybe -- deficiency of input notation X */ X if ((m->fromlig !=0) || (m->fromcol != 0)) X m->piece = tos->board[m->fromlig][m->fromcol]; X X if (tos->board[m->tolig][m->tocol] != VOID) { X m->type = PRISE; X m->prise = tos->board[m->tolig][m->tocol] ; X } X X if (!check_move(m)) { X if (m->whiteturn) X error((stderr,"white move %d illegal\n",m->move)); X else X error((stderr,"black move %d illegal\n",m->move)); X } X X if (m->type == PETITROQUE) { X if (m->whiteturn) X curlig = 1 ; X else X curlig = 8 ; X tos->board[curlig][7] = KING; X tos->board[curlig][6] = ROOK; X tos->color[curlig][7] = tos->color[curlig][5] ; X tos->color[curlig][6] = tos->color[curlig][5] ; X (void) clear_pos(curlig, 5); X (void) clear_pos(curlig, 8); X } X if (m->type == GRANDROQUE) { X if (m->whiteturn) X curlig = 1 ; X else X curlig = 8 ; X tos->board[curlig][3] = KING; X tos->board[curlig][4] = ROOK; X tos->color[curlig][3] = tos->color[curlig][5] ; X tos->color[curlig][4] = tos->color[curlig][5] ; X (void) clear_pos(curlig, 5); X (void) clear_pos(curlig, 1); X } X X X if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) { X if (m->piece == VOID) X m->piece = tos->board[m->fromlig][m->fromcol]; X /*if (m->topiece == VOID) X m->topiece = tos->board[m->fromlig][m->fromcol];*/ X tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol]; X tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol]; X (void) clear_pos(m->fromlig,m->fromcol); X } X X if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE)) X tos->board[m->tolig][m->tocol] = m->promotion ; X X output_move(dr,m); X X if (error_flag) { X (void) fprintf(dr->outfile, "\nlast position encountered:\n"); X output_board(dr,tos); X close_files(); X exit(0); X } X X /* do we need to display the move ? */ X if (nb_move_to_dsp > 0) { X for (i=0; i < nb_move_to_dsp; i++) X if (m->move == (move_to_display[i] ) && !m->whiteturn ) { X output_board(dr,tos); X if (stop_at_display) { X output_end(dr); X close_files(); X exit(0); X } X } X } X X return(TRUE); X} X X/* ------------------ automata ----------------------- */ X X/* categorise the input for the automata */ Xint typechar(c) X char c; X{ X if (ispiece(c)) X return(0); X if ((c >= 'a') && ( c <= 'h')) X return(1); X if ((c >= '1') && ( c <= '8')) X return(2); X if ( c== '-' ) X return(3); X if ((c == 'x') || (c == 'X' )) X return(4); X if (c == '=' ) X return(5); X if (c == '\0' ) X return(6); X return(7); X} X X X/* execute the actions decided by the automata */ Xint execute(num,c) X int num; X char c; X{ X switch (num) { X case 1: /* set cur piece */ X curpiece = piece(c); X break; X case 2: /* set cur col */ X curcol = lettertocol(c); X break; X case 3: /* set cur lig */ X curlig = lettertolig(c); X break; X case 4: /* from = cur ; prise = false */ X m->piece = curpiece ; X m->fromcol = curcol ; X m->fromlig = curlig; X /*m->topiece = curpiece;*/ X break; X case 5: /* from = cur ; prise = true */ X m->piece = curpiece ; X m->fromcol = curcol ; X m->fromlig = curlig; X m->type = PRISE ; X m->prise = curpiece; X break; X case 6: /* to = cur ; guess from */ X case 7: /* to = cur ; guess from ; parse remaining token */ X m->piece = curpiece ; X m->tocol = curcol; X m->tolig = curlig ; X X /*m->topiece = curpiece ; /* ? */ X X if (configuring) X (void) configure(); X else { X (void) execute_move(); X m->whiteturn = !m->whiteturn ; X if (m->whiteturn) m->move++ ; X } X break; X case 8: /* to = cur */ X case 9: /* to = cur */ X m->tocol = curcol; X m->tolig = curlig ; X /*m->topiece = curpiece ;*/ X X if (configuring) X (void) configure(); X else { X (void) execute_move(); X m->whiteturn = !m->whiteturn ; X if (m->whiteturn) m->move++ ; X } X break; X case 10: /* piece = cur piece ; prise = true */ X /* later : guess from position */ X m->piece = curpiece ; X m->type = PRISE ; X break; X case 11: /* grand roque */ X case 12: /* petit roque */ X X (void) execute_move(); X X m->whiteturn = !m->whiteturn ; X if (m->whiteturn) m->move++ ; X break; X case 13: /* case of simpliest algebraic notation ; X only e2e4 : this is the transition from e2 to e4 X also the case of move such as Nge2 X from =cur; prise = FALSE; X also: X curcol = ... X */ X m->piece = curpiece ; X m->fromcol = curcol ; X m->fromlig = curlig; X /*m->topiece = curpiece;*/ X m->type = MOVE; X curcol = lettertocol(c); X case 14: /* promotion, the "=" */ X break; X case 15: /* promotion, the piece name */ X /* to = cur ; guess from */ X case 16: X /* to = cur */ X X m->tocol = curcol; X m->tolig = curlig ; X /*m->topiece = curpiece ;*/ X X if (m->type == PRISE ) X m->type = PROM_ET_PRISE ; X else X m->type = PROMOTION ; X m->promotion = curpiece = piece(c) ; X X break; X case 17: /* execute move for promotion */ X (void) execute_move(); X X m->whiteturn = !m->whiteturn ; X if (m->whiteturn) m->move++ ; X break; X case -1: X break; X default: X break; X } X return(TRUE); X} X Xint parse_number(token) X char *token; X{ X int curmove = 0 ; X int i; X X /* check coherency with internal numbering */ X i = 0; X while (isdigit(token[i])) { X curmove = curmove * 10 + ((int) token[i++] - (int) '0' ); X } X if (curmove != m->move) X (void) fprintf(stderr,"problem in move numbering: %d vs %d\n", X m->move, curmove); X return(TRUE); X} X Xint parse_keyword(token) X char *token; X{ X char c; X X switch (find_keyword(keywords, NBKEYWORD, KNULL, token)) { X case START: X configuring = FALSE; X m->move = 1; X m->whiteturn = TRUE; X break; X case CLEAR: X clear_board(tos); X break; X case SHOWBOARD: X output_board(dr,tos); X break; X case TOWHITE: X m->move = 1; X m->whiteturn = TRUE; X break; X case TOBLACK: X m->move = 1; X m->whiteturn = FALSE; X break; X case CONFIGWH: X configuring = TRUE ; X configside = WHITE; X break; X case CONFIGBL: X configuring = TRUE ; X configside = BLACK; X break; X case DEFAULTP: X init_board(tos); X break; X case SPECIAL: /* all input, up to \n is copied to output */ X while ((( c = getc(infile)) != EOF) && (c != '\n')) X (void) putc (c,dr->outfile); X putc ('\n', dr->outfile); X break; X case KNULL: X default: X break; X } X return(TRUE); X} X Xint parse_roque(token) X char * token; X{ X int i; X X for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ; X if ( i < NBROQUE ) { X if (strlen(token) == 3) { X m->type = PETITROQUE ; X (void) execute(12,DUMMYCHAR); X } else { X m->type = GRANDROQUE ; X (void) execute(11,DUMMYCHAR); X } X /*(void) fprintf(stderr,"ROQUE\n");*/ X return(TRUE); X } X X return(FALSE); X} X Xint parse_move(token) X char *token; X{ X register int i; X int correcte = FALSE ; X int erreursyntaxe = FALSE ; X int etat =0; X int code; X X i=0; X while ( !correcte && !erreursyntaxe ) { X code = typechar(token[i]); X (void) execute(action[etat][code],token[i]); X etat = transit[etat][code] ; X if (etat == -1) X erreursyntaxe = TRUE; X if (etat == FINAL) X correcte = TRUE ; X i++; X } X if (erreursyntaxe) { X (void) fprintf(stderr, "no comprende, senor: %s\n",token); X return(FALSE); X } X if (correcte) { X /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/ X } X return(TRUE); X} X Xvoid init_parse(m) X depl * m ; X{ X int i; X X /* global position and piece variable initialised to 0 X */ X /* move and whiteturn unchanged */ X X m->type = MOVE ; X X curpiece = m->piece = VOID ; X curcol = m->tocol = m->fromcol = 0; X curlig = m->tolig = m->fromlig = 0; X X m->promotion = VOID; X m->prise = VOID; X X for (i=0; i< 3; i++) X m->is_check[i] = FALSE ; X curdigit = curmove = 0; X} X X/* ------------------- top routines -------------------- */ X X/* cette fonction analyse les arguments de la ligne de commande X */ Xint parse_options(argc,argv) X int argc; X char * argv[]; X{ X int narg =1 ; X int i; X register int c; X char cp[132]; X char chaine[MAXTOKLEN]; X X infile = stdin; X dr->outfile = stdout; X nb_move_to_dsp = 0; X X while (narg < argc ) { X (void) strcpy (cp,argv[narg]); X switch (cp[0]) { X case '-' : X switch (cp[1]) { X case 'f' : /* from langage */ X if ((narg+1) >= argc ) X fatal((stderr,"missing argument to %s option",cp)); X narg++ ; X in_language = find_keyword (t_language, NBLANGUAGE, X DEFAULT_INPUT_LANGUAGE, X argv[narg]); X break; X case 't' : /* to langage */ X if ((narg+1) >= argc ) X fatal((stderr,"missing argument to %s option",cp)); X narg++ ; X out_language = find_keyword (t_language, NBLANGUAGE, X DEFAULT_OUTPUT_LANGUAGE, X argv[narg]); X break; X case 'o' : /* next arg is output file */ X narg++ ; X if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) { X (void) fprintf (stderr,"can't open %s output file\n",argv[narg]); X (void) fprintf (stderr,"assume stdout for output\n"); X } X break; X case 'e': X if ((narg+1) >= argc ) X fatal((stderr,"missing argument to %s option",cp)); X narg++ ; X X i=0; X nb_move_to_dsp = 0; X move_to_display[nb_move_to_dsp] = 0; X while (isdigit(argv[narg][i])) { X move_to_display[nb_move_to_dsp] = X ((int) argv[narg][i] - (int) '0') X + move_to_display[nb_move_to_dsp] * 10; X i++; X } X nb_move_to_dsp++; X stop_at_display = TRUE; X break; X case 'c': X if ((narg+1) >= argc ) X fatal((stderr,"missing argument to %s option",cp)); X narg++ ; X X i=0; X while (isdigit(argv[narg][i])) { X move_to_display[nb_move_to_dsp] = 0; X while (isdigit(argv[narg][i])) { X move_to_display[nb_move_to_dsp] = X ((int) argv[narg][i] - (int) '0') X + move_to_display[nb_move_to_dsp] * 10; X i++; X } X nb_move_to_dsp++; X X if (nb_move_to_dsp > NB_MOVE_TO_DISP) X fatal((stderr,"max. number of move to display exceeded")); X X /* process next number */ X if (argv[narg][i] == ',') X i++; X } X break; X case 'a': /* algebraic output */ X dr->output_move_format = ALGEBRAIC; X break; X case 's': /* shortened output */ X dr->output_move_format = SHORTENED; X break; X case 'b': /* display only the board, no move */ X dr->only_board = TRUE; X break; X case 'd': /* output driver */ X if ((narg+1) >= argc ) X fatal((stderr,"missing argument to %s option",cp)); X narg++ ; X driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER, X argv[narg]); X break; X case 'h': /* help file */ X (void) strcpy(chaine,LIB_DIR); X if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL) X fatal((stderr,"Can't find help file.\n")); X else { X while ((c = getc(fhelp)) != EOF) X (void) fputc(c,stderr); X (void) fclose(fhelp); X exit(0); X } X break; X default: X error((stderr,"unknown command line options %s\n",cp)); X break; X } X break; X default: /* assume this is the input file */ X if ((infile = fopen (cp,"r")) == NULL) X fatal((stderr,"can't open %s input file\n",cp)); X } X narg++; X } /* process next arg */ X return(argc); X} X Xvoid close_files() X{ X if (infile != stdin ) X (void) fclose(infile); X if (dr->outfile != stdout ) X (void) fclose(dr->outfile); X} X Xint associe_traduction (table, langage) Xchar ** table; Xint langage ; X{ X switch (langage) { X case FRENCH : X *table = c_french ; X break; X case ENGLISH: X *table = c_english ; X break; X case ITALIAN: X *table = c_italian ; X break; X case SPANISH: X *table = c_spanish ; X break; X case GERMAN: X *table = c_german ; X break; X case DUTCH: X *table = c_dutch ; X break; X case RUSSIAN: X (void) fprintf(stderr,"russian not yet implemented\n"); X *table = c_russian ; X break; X default: X error((stderr,"unknown langage\n")); X } X return(langage); X} X X/* ------------- main --------------------- */ X Xmain(argc,argv) X int argc; X char * argv[]; X{ X (void) fprintf(stderr,"%s\n",version_string); X X /* allocation of driver descriptor */ X dr = new_driver(); X X /* default configuration */ X init_driver(dr,DEFAULT_DRIVER); X (void) associe_traduction(&in_table, DEFAULT_INPUT_LANGUAGE ); X (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE); X X (void) parse_options(argc,argv); X X (void) associe_traduction (&in_table, in_language); X (void) associe_traduction (&(dr->out_table), out_language); X X /* assoc driver */ X init_driver(dr,driver); X X configuring = FALSE; X configside = VOID; X X /* initialise output file */ X output_init(dr); X X if (error_flag) X fatal((stderr,"too many errors")); X X /* allocation of move descriptor */ X m = new_move(); X init_move(m); X X /* allocation of board descriptor */ X tos = new_board(); X init_board(tos); X X /*output_board(dr,tos);*/ X X while (nexttoken()) { X /*(void) fprintf(stdout,"%s%\n", curtok);*/ X init_parse(m); X (void) parsetoken(); X } X if ((count == 0) && !error_flag) X output_board(dr,tos); X X if (error_flag) { X error((stderr,"last valid position:\n")); X output_board(dr,tos); X fatal((stderr,"too many errors")); X } X X /* terminates output files */ X output_end(dr); X X /* close files */ X close_files(); X X /* exit properly */ X#ifdef TURBOC X return(TRUE); X#else X exit(0); X#endif X} END_OF_FILE if test 31006 -ne `wc -c <'notation.c'`; then echo shar: \"'notation.c'\" unpacked with wrong size! fi # end of 'notation.c' fi echo shar: End of archive 3 \(of 3\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Henry Thomas - IRISA - E-mail: Henry.Thomas@irisa.fr Campus Universitaire de Beaulieu - Phone: (+33)99 36 20 00 +549 35042 RENNES CEDEX FRANCE - Fax: (+33)99 38 38 32 Telex: UNIRISA 950473F Telex Atlas X400: /X121=842950473/@atlas.fr, Fax:/X121=200099383832/@atlas.fr -- ... Words, and the words of men, flicker and flutter and beat Warning, sorrow and gain, salutations and mirth... R. Kipling exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.