home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume18
/
notation
/
part02
/
drivers.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-13
|
14KB
|
551 lines
#include<stdio.h>
#include <ctype.h>
#include "chesstype.h"
#include "notation.h"
#include "drivers.h"
/* postscript characters translation table
one entry per piece
each entry has four fields:
- white piece on white case
- white piece on black case
- black piece on ...
..
*/
#define PSINDEX(a,b) ((((a)==WHITE)?0:2)+(((b)%2)?0:1))
static char * postscript_table[][4] = {
{ " ", "x", " ", "x" }, /* void */
{ "k", "\\373", "K", "\\360" }, /* king */
{ "q", "\\317", "Q", "\\316" }, /* queen */
{ "r", "\\250", "R", "\\345" }, /* rook */
{ "b", "\\272", "B", "\\365" }, /* bishop */
{ "n", "\\265", "N", "\\366" }, /* knight */
{ "p", "\\271", "P", "\\270" } /* pawn */
};
/* TeX table for using the chess figure in board design */
static char * metafont_table[][4] = {
/* W/W W/B B/W B/B */
{ "\\WWW", "\\DDD", "\\WWW", "\\DDD" }, /* void */
{ "\\WKW", "\\WKB", "\\BKW", "\\BKB" }, /* king */
{ "\\WQW", "\\WQB", "\\BQW", "\\BQB" }, /* queen */
{ "\\WRW", "\\WRB", "\\BRW", "\\BRB" }, /* rook */
{ "\\WBW", "\\WBB", "\\BBW", "\\BBB" }, /* bishop */
{ "\\WNW", "\\WNB", "\\BNW", "\\BNB" }, /* knight */
{ "\\WPW", "\\WPB", "\\BPW", "\\BPB" } /* pawn */
};
/* TeX table for using the chess figures in move description */
static char * latex_table[] = {
"\\FigVoid", "\\FigK", "\\FigQ", "\\FigR", "\\FigB", "\\FigN", "\\FigP"
};
/* various tex symbols */
static char FigDash[] = "\\FigDash";
static char FigCapt[] = "\\FigCapt";
static char FigDots[] = "\\FigDots";
static char FigDot[] = "\\FigDot";
#define G_ROQUE "O-O-O"
#define P_ROQUE "O-O"
static FILE * ftmp ;
/* ---------------- output functions ---------------- */
/* convert a roque in term of king's move */
static int roque_to_move(m)
depl * m;
{
m->piece = KING;
m->fromcol = 5;
if (m->type == GRANDROQUE)
m->tocol = 3;
else
m->tocol = 7;
if (m->whiteturn)
m->fromlig = m->tolig = 1;
else
m->fromlig = m->tolig = 8;
return(TRUE);
}
/* (kind of) buffering of output */
static void init_buffer(d,side)
format * d;
int side ;
{
switch (d->type) {
case D_ASCII:
if (side != BLACK) (void) sprintf(d->white_buffer,"...");
if (side != WHITE) (void) sprintf(d->black_buffer," ");
break;
case D_TEX:
if (side != BLACK) (void) sprintf(d->white_buffer,"%s",FigDots);
if (side != WHITE) (void) sprintf(d->black_buffer,"~");
break;
default:
if (side != BLACK) d->white_buffer[0] = '\0' ;
if (side != WHITE) d->black_buffer[0] = '\0' ;
break;
}
}
/* this procedure is responsible for PRINTING the move */
static void flush_buffer(d)
format * d;
{
/* if we have been inteerupted (by a comment, a board display etc...
if the move is black
we display <movenumber> ... <blackmove>
*/
if ((d->interrupt == TRUE) && (d->iswhiteturn == FALSE)) {
switch (d->type) {
case D_TEX:
(void) fprintf(d->outfile,
"\\noindent\\movenumber{\\bf %s\\FigDot}\\whitemove{%s}\\blackmove{%s}\n",
d->move_buffer,FigDots,d->black_buffer);
break;
case D_GNU:
/* no special case for GNU */
(void) fprintf(d->outfile,"\t%s\n",d->black_buffer);
break;
default:
(void) fprintf(d->outfile,"%3s.%9s%9s\n",
d->move_buffer,"...",d->black_buffer);
break;
}
d->interrupt = FALSE ;
} else {
/* else (no interrupt)
we display either white or black move
*/
switch (d->type) {
case D_TEX:
if (d->iswhiteturn)
(void) fprintf(d->outfile,
"\\noindent\\movenumber{\\bf %s\\FigDot}\\whitemove{%s}", d->move_buffer,d->white_buffer);
else
(void) fprintf(d->outfile,
"\\blackmove{%s}\n",d->black_buffer);
break;
case D_GNU:
if (d->iswhiteturn)
(void) fprintf(d->outfile,"\t%s",d-> white_buffer);
else
(void) fprintf(d->outfile,"\t%s\n",d->black_buffer);
break;
default:
if (d->iswhiteturn)
(void) fprintf(d->outfile,"%3s.%9s", d->move_buffer,d->white_buffer);
else
(void) fprintf(d->outfile,"%9s\n", d->black_buffer);
break;
}
} /* end printing */
/* reset buffer */
if (! d->iswhiteturn)
init_buffer(d,VOID);
d->interrupt = FALSE;
}
/* a generic parametrised driver for move output
*/
static void output_move_generic(dr,d)
format * dr;
depl *d;
{
char ligne[128] ;
char themove[128] ;
char thepiece[16] ;
char debcol[16];
char frommove[16] ;
char tomove[16] ;
char lie[16] ;
char prom[16];
int ambigue = FALSE ;
ligne[0] = themove[0] = thepiece[0] = debcol[0] = '\0';
frommove[0] = tomove[0] = lie[0] = prom[0] = '\0' ;
(void) sprintf (dr->move_buffer,"%d",d->move);
if ((d->type == PETITROQUE) && !dr->roque_alg)
(void) sprintf (themove,"%s",P_ROQUE);
if ((d->type == GRANDROQUE) && !dr->roque_alg)
(void) sprintf (themove,"%s",G_ROQUE);
if (dr->roque_alg &&
((d->type == GRANDROQUE) || (d->type == PETITROQUE)))
(void) roque_to_move(d);
if (dr-> roque_alg ||
((d->type != GRANDROQUE) && (d->type != PETITROQUE))) {
/* we check here for ambiguous move */
if ((d->type != GRANDROQUE) && (d->type != PETITROQUE)) {
ambigue = ambiguity (d->piece, d->tolig,d->tocol);
/* if ( (ambigue ) && (d->piece != PAWN ))
* (void) fprintf (stderr,"ambiguity at move %d",tos->move);
*/
}
themove[0] = '\0' ;
if ((dr->output_move_format == SHORTENED)
&& (d->type == PRISE) && (d->piece == PAWN))
(void) sprintf (debcol, "%c",coltoletter(d->fromcol));
if (dr->print_piece)
if (d->piece != PAWN || dr->print_pawn) {
if (dr->type == D_TEX )
(void) sprintf(thepiece,"%s ",latex_table[d->piece]);
else
(void) sprintf(thepiece,"%c",dr->out_table[d->piece]);
}
if ((dr->output_move_format == ALGEBRAIC))
(void)sprintf(frommove,"%c%c",
coltoletter(d->fromcol),ligtoletter(d->fromlig));
if ( ambigue && dr->print_liaison ) {
(void) sprintf(lie,"-");
(void)sprintf(frommove,"%c%c",
coltoletter(d->fromcol),ligtoletter(d->fromlig));
debcol[0] = '\0' ;
}
if (d->promotion) {
if (dr->print_piece) {
if (dr->type == D_TEX )
(void) sprintf(prom,"=%s ",latex_table[d->promotion]);
else
(void) sprintf(prom,"=%c",dr->out_table[d->promotion]);
}
}
if (dr->print_liaison) {
if ((d->type == PRISE) || (d->type == PROM_ET_PRISE)
|| (d->type == EN_PASSANT) )
(void) sprintf(lie,"%c",'x');
else
if ((dr->output_move_format == ALGEBRAIC))
(void) sprintf(lie,"%c",'-');
}
(void) sprintf(tomove,"%c%c",coltoletter(d->tocol),ligtoletter(d->tolig));
(void) sprintf (themove,"%s%s%s%s%s%s",
thepiece,debcol,frommove,lie, tomove,prom);
}
if (d->whiteturn)
(void) sprintf (dr->white_buffer, "%s",themove);
else
(void) sprintf (dr->black_buffer, "%s",themove);
dr->iswhiteturn = d->whiteturn;
/*fprintf(dr->outfile, "=%d=%d= ",d->move,d->whiteturn);*/
flush_buffer(dr);
}
/* ---------------- ascii driver ---------- */
static void output_init_ascii(dr)
format *dr;
{}
static void output_board_ascii(dr,g)
format * dr;
game * g;
{
register int i,j;
dr->interrupt = TRUE;
(void) fprintf(dr->outfile,"\n\n");
for (i=8 ; i >=1 ; i--) {
if (dr->coordinates)
(void) fprintf(dr->outfile,"%d ",i);
(void) fputc('|',dr->outfile);
for (j=1 ; j<9 ; j++) {
if (g->board[i][j] != VOID) {
if (g->color[i][j] == WHITE)
(void) fputc(dr->out_table[g->board[i][j]], dr->outfile);
else
(void) fputc(tolower(dr->out_table[g->board[i][j]]),dr->outfile);
} else
(void) fputc ( ((i+j)% 2)?' ':'/', dr->outfile);
(void) fputc('|', dr->outfile);
}
(void) fputc('\n', dr->outfile);
}
if (dr->coordinates)
(void) fprintf(dr->outfile," a b c d e f g h\n");
(void) fprintf(dr->outfile,"\n");
}
/* ---------------- postscript --------- */
static void output_board_ps(dr,g)
format *dr;
game * g;
{
register int i,j;
register int c;
char chaine[MAXTOKLEN];
/* header file */
(void) strcpy(chaine,LIB_DIR);
if ((ftmp = fopen(strcat(chaine,PS_HEADER),"r")) == NULL)
message((stderr,"Can't open ps header file.\n"));
else {
while ((c = getc(ftmp)) != EOF)
(void) fputc(c,dr->outfile);
(void) fclose(ftmp);
}
(void) fprintf(dr->outfile,"( ________) 72 714 T\n");
for (i=8 ; i >=1 ; i--) {
(void) fprintf(dr->outfile,"(/");
for (j=1 ; j<9 ; j++) {
(void) fprintf(dr->outfile,"%s",
postscript_table[g->board[i][j]][PSINDEX(g->color[i][j],(i+j))]);
}
(void) fprintf(dr->outfile,"\\\\) 72 %d T\n",474 + (i-1)*30);
}
(void) fprintf(dr->outfile,"( --------) 72 444 T\n");
/* footer file */
(void) strcpy(chaine,LIB_DIR);
if ((ftmp = fopen(strcat(chaine,PS_FOOTER),"r")) == NULL)
message((stderr,"Can't open ps footer file.\n"));
else {
while ((c = getc(ftmp)) != EOF)
(void) fputc(c,dr->outfile);
(void) fclose(ftmp);
}
}
/* ---------------- nroff --------------- */
static void output_init_roff(dr)
format *dr;
{
}
static void output_board_roff(dr,g)
format *dr;
game * g;
{
register int i,j;
dr->interrupt = TRUE;
(void) fprintf(dr->outfile,".br\n");
for (i=8 ; i >=1 ; i--) {
(void) fprintf(dr->outfile,".ce\n ");
for (j=1 ; j<9 ; j++) {
if (g->board[i][j] != VOID) {
if (g->color[i][j] == WHITE)
(void) fputc(dr->out_table[g->board[i][j]], dr->outfile);
else
(void) fputc(tolower(dr->out_table[g->board[i][j]]),dr->outfile);
} else
/*(void) fputc ( ((i+j)% 2)?' ':'/', dr->outfile);*/
(void) fprintf(dr->outfile,".");
}
(void) fprintf(dr->outfile,"\n.br\n");
}
(void) fprintf(dr->outfile,"\n");
}
/* ---------------- tex -------------------- */
static void output_init_tex(dr)
format *dr;
{
register int c;
char chaine[MAXTOKLEN];
/* header file */
(void) strcpy(chaine,LIB_DIR);
if ((ftmp = fopen(strcat(chaine,TEX_HEADER),"r")) == NULL)
message((stderr,"Can't open tex header file.\n"));
else {
while ((c = getc(ftmp)) != EOF)
(void) fputc(c,dr->outfile);
(void) fclose(ftmp);
}
}
static void output_board_tex(dr,g)
format *dr;
game * g;
{
register int i,j;
dr->interrupt = TRUE;
(void) fprintf(dr->outfile,"\n\n");
(void)fprintf(dr->outfile,"$$\\vbox{\\bigskip\\offinterlineskip\\tabskip=0pt\n");
(void) fprintf(dr->outfile,"\\halign{#\\vvrule \\vvrule \\cr\n");
(void) fprintf(dr->outfile,"\\noalign{\\hhrule}\n");
for (i=8 ; i >=1 ; i--) {
(void) fprintf(dr->outfile,"&");
for (j=1 ; j < 9 ; j++) {
(void) fprintf(dr->outfile,"%s",
metafont_table[g->board[i][j]][PSINDEX(g->color[i][j],(i+j))]);
(void) fprintf(dr->outfile,"&");
}
(void) fprintf(dr->outfile,"\\cr \n");
}
(void) fprintf(dr->outfile,"\\noalign{\\hhrule}}}$$");
(void) fprintf(dr->outfile,"");
(void) fprintf(dr->outfile,"\n\n");
}
static void output_end_tex(dr)
format *dr;
{
(void) fprintf(dr->outfile, "~\n\n\n\\end{document}\n");
}
/* ------------------ gnu - xchess ---------- */
static void output_init_gnu(dr)
format *dr;
{
(void) fprintf(dr->outfile, "X Chess -- Mon Dec 10 11:47:18 MET 1990\n");
(void) fprintf(dr->outfile,"\tGame played on dumbkopft.irisa.fr:0.0\n");
(void) fprintf(dr->outfile,"\talgebraic\n");
}
/* ---------------- driver handler ---------- */
/* dummy driver */
static void null_driver() {}
/* the drivers */
void output_init(dr)
format *dr ;
{
dr->out_init(dr);
}
void output_move(dr,d)
format *dr ;
depl *d;
{
dr->out_move(dr,d);
}
void output_board(dr,g)
format *dr ;
game *g ;
{
dr->out_board(dr,g);
}
void output_end(dr)
format *dr ;
{
dr->out_end(dr);
}
format * new_driver()
{
format * tmp;
int i;
tmp = (format *) malloc (sizeof(format));
ALLOCP(tmp);
/*for (i=0; i < ((sizeof (format))/ sizeof (int)) ; i++)
((int *) tmp)[i] = 0;*/
return(tmp);
}
void init_driver(dr,driver)
format * dr;
int driver;
{
dr->type = driver ;
switch (dr->type) {
case D_ASCII:
dr->print_move = TRUE;
dr->print_piece = TRUE;
dr->print_pawn = FALSE;
dr->roque_alg = FALSE;
dr->print_liaison = TRUE;
dr->out_init = output_init_ascii;
dr->out_move = output_move_generic;
dr->out_board = output_board_ascii;
dr->out_end = null_driver;
break;
case D_POST:
dr->out_init = null_driver;
dr->out_move = null_driver;
dr->out_board = output_board_ps;
dr->out_end = null_driver;
break;
case D_TEX:
dr->print_move = TRUE;
dr->print_piece = TRUE;
dr->print_pawn = FALSE;
dr->roque_alg = FALSE;
dr->print_liaison = TRUE;
dr->out_init = output_init_tex;
dr->out_move = output_move_generic;
dr->out_board = output_board_tex;
dr->out_end = output_end_tex;
break;
case D_ROFF:
dr->print_move = TRUE;
dr->print_piece = TRUE;
dr->print_pawn = FALSE;
dr->roque_alg = FALSE;
dr->print_liaison = TRUE;
dr->out_init = output_init_roff;
dr->out_move = output_move_generic;
dr->out_board = output_board_roff;
dr->out_end = null_driver;
break;
case D_XCHESS:
dr->print_move = TRUE;
dr->print_piece = FALSE;
dr->print_pawn = FALSE;
dr->roque_alg = TRUE;
dr->print_liaison = FALSE;
dr->out_init = output_init_gnu;
dr->out_move = output_move_generic;
dr->out_board = null_driver;
dr->out_end = null_driver;
break;
case D_GNU:
dr->print_move = FALSE;
dr->print_piece = FALSE;
dr->print_pawn = FALSE;
dr->roque_alg = TRUE;
dr->print_liaison = FALSE;
dr->out_init = null_driver;
dr->out_move = output_move_generic;
dr->out_board = null_driver;
dr->out_end = null_driver;
break;
default:
error((stderr,"unknown driver"));
break;
}
if (dr->only_board)
dr->out_move = null_driver ;
dr->variation_level = 0;
dr->iswhiteturn = FALSE ;
dr->interrupt = FALSE;
init_buffer(dr, VOID);
}