/* load.l Copyright (C) 1994 Lambert Klasen & Detlef Steuer klasen@asterix.uni-muenster.de steuer@amadeus.statistik.uni-dortmund.de This file is free source code; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program 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 COPYING for more details. */ %{ #include #include #include #include #include "xgammon.h" #include "gammon.h" /* for some irix */ #ifdef irix #define usleep(a) sleep((a/10)) #endif char kind; char *player[2]; int games_replayed; static float fval, *inarray; static int count = 0, endarray; static int found_black, found_white; static int have_tournament = 0; static int wraped = 0; void replay_init_game (); void print_move (MOVE *m); extern float point_values[], prime_length_factor[]; extern int replaying; extern unsigned long delaytime; extern FILE * protokol_file; extern void ShowCompiMove (); extern void DrawEmptyBoard (); extern void DrawBoard (); extern void RedrawAllStones (); extern void RemoveStone (); extern void DrawDice (); extern void DrawDoubler (); extern void open_protokol (); %} %s LOAD %s LOAD_CONFIG %s REPLAY %s GETMOVE %s FIBSLOAD %% .*" and ".*" start a "[0-9]+" point match."\n { char *r = yytext; int i = 1; while (*(r+i) != ' ') i++; player[0] = malloc (i+1); strncpy (player[0], r, i); r = strstr (yytext, " and ") + 5; i = 1; while (*(r+i) != ' ') i++; player[1] = malloc (i+1); strncpy (player[1], r, i); r = r + i + 9; tournament.winning_point = atoi (r); #ifdef DEBUG_REPLAY fprintf (stderr, "player: %s %s\n", player[0], player[1]); fprintf (stderr, "winning_point: %d\n", tournament.winning_point); #endif AppendDialogText (LOWER, yytext); } [A-Za-z0-9]*" rolls "[1-6]" and "[1-6]"."\n { AppendDialogText (LOWER, yytext); roll[0] = *(yytext+yyleng-9) - '0'; roll[1] = *(yytext+yyleng-3) - '0'; if (strncmp (player[1], yytext, strlen (player[1])) == 0) turn = BLACK; else if (strncmp (player[0], yytext, strlen (player[0])) == 0) turn = WHITE; #ifdef DEBUG_REPLAY fprintf (stderr,"roll %c %c turn %d\n", *(yytext+yyleng-9), *(yytext+yyleng-3), turn); #endif DrawDice (turn); XSync (Player[0].X11Set.dpy, 0); while(1) { XEvent event; XtAppNextEvent(app_con, &event); if (event.type == ButtonRelease && event.xbutton.window == Player[0].X11Set.board.window) { XtDispatchEvent (&event); break; } else if (event.type == KeyRelease && event.xkey.window == Player[0].X11Set.board.window) { break; } XtDispatchEvent(&event); } } [A-Za-z0-9]*" rolled "[1-6]", "[A-Za-z0-9]*" rolled "[1-6]\n[a-zA-Z0-9]*" makes the first move."\n { char *r = yytext; count = 0; AppendDialogText (LOWER, yytext); while (*r != ',') r++; roll[0] = *(r-1) - '0'; while (*r != '\n') r++; roll[1] = *(r-1) - '0'; #ifdef DEBUG_REPLAY fprintf (stderr, "initial roll %s", yytext ); fprintf (stderr, "roll %d %d\n", roll[0], roll[1]); #endif if (games_replayed%2 == 0) { char *p; p = player[0]; player[0] = player[1]; player[1] = p; } games_replayed++; if (strncmp ((r+1), player[0], strlen (player[0])) == 0) turn = BLACK; else turn = WHITE; #ifdef DEBUG_REPLAY fprintf (stderr ,"turn %d\n", turn); #endif replay_init_game (); } [a-zA-Z0-9]*" doubles."\n { if (strncmp (player[0], yytext, strlen(player[0])) == 0) { doubler.owner = BLACK; } else if (strncmp (player[1], yytext, strlen(player[1])) == 0) { doubler.owner = WHITE; } AppendDialogText (LOWER, yytext); XSync (Player[0].X11Set.dpy, 0); while(1) { XEvent event; XtAppNextEvent(app_con, &event); if (event.type == ButtonRelease && event.xbutton.window == Player[0].X11Set.board.window) { XtDispatchEvent(&event); break; } else if (event.type == KeyRelease && event.xkey.window == Player[0].X11Set.board.window) { break; } XtDispatchEvent(&event); } } [a-zA-Z0-9]*" accepts the double."\n { if (strncmp (player[0], yytext, strlen(player[0])) == 0 || strncmp (player[1], yytext, strlen(player[1])) == 0) { doubler.value *= 2; DrawDoubler (doubler.value, doubler.owner); #ifdef DEBUG_REPLAY fprintf (stderr,"doubling accepted\n"); #endif } AppendDialogText (LOWER, yytext); } "gives up." { AppendDialogText (LOWER, yytext); #ifdef DEBUG_REPLAY fprintf (stderr,"doubling resign\n"); #endif } [a-zA-Z0-9]*" moves " { if (strncmp (player[0], yytext, strlen(player[0]) - 1) == 0) BEGIN GETMOVE; else if (strncmp (player[1], yytext, strlen(player[1]) - 1) == 0) BEGIN GETMOVE; AppendDialogText (LOWER, yytext); count = 0; #ifdef DEBUG_REPLAY fprintf (stderr,"switching to getmove\n"); #endif } [a-zA-Z0-9]*" can't move." { AppendDialogText (LOWER, yytext); if (turn == BLACK) turn = WHITE; else turn = BLACK; } ([1-9]|1[0-9]|2[0-4])"-"([1-9]|1[0-9]|2[0-4]) { char *to = yytext; int f, t; AppendDialogText (LOWER, yytext); f = atoi (yytext); turn = Pin[f].color; while (*to != '-') to++; to++; t = atoi (to); #ifdef DEBUG_REPLAY fprintf (stderr,"from %d to %d\n", f, t); #endif RemoveStone (f); if (Pin[t].count == 1 && Pin[t].color != turn) { PutStone (Pin[t].color, (turn == BLACK) ? WHITE_BAR : BLACK_BAR); RemoveStone (t); } PutStone (turn, t); XSync (Player[0].X11Set.dpy, 0); usleep (delaytime); } "bar-"([1-9]|1[0-9]|2[0-4]) { int f, t, f_color; AppendDialogText (LOWER, yytext); t = atoi ((yytext+4)); if (t < 7) { f_color = BLACK; f = BLACK_BAR; turn = BLACK; /* for RemoveStone () */ } else { f_color = WHITE; f = WHITE_BAR; turn = WHITE; } #ifdef DEBUG_REPLAY fprintf (stderr,"from (bar) %d to %d\n", f, t); #endif RemoveStone (f); if (Pin[t].count == 1 && Pin[t].color != f_color) { PutStone (Pin[t].color, (f_color == BLACK) ? WHITE_BAR : BLACK_BAR); RemoveStone (t); } PutStone (f_color, t); XSync (Player[0].X11Set.dpy, 0); usleep (delaytime); } ([1-9]|1[0-9]|2[0-4])"-off" { int f, t; AppendDialogText (LOWER, yytext); f = atoi (yytext); if (Pin[f].color == BLACK) { t = 25+BLACK; turn = BLACK; } else { t = 25+WHITE; turn = WHITE; } #ifdef DEBUG_REPLAY fprintf (stderr, "from %d to %d (off)\n", f, t); #endif RemoveStone (f); PutStone (turn, t); XSync (Player[0].X11Set.dpy, 0); usleep (delaytime); } [a-zA-Z0-9]* { AppendDialogText (LOWER, yytext); } [a-zA-Z0-9]* { AppendDialogText (LOWER, yytext); } . { AppendDialogText (LOWER, yytext); } . { AppendDialogText (LOWER, yytext); } \n { AppendDialogText (LOWER, "\n"); } \n { AppendDialogText (LOWER, "\n"); BEGIN REPLAY; } "turn: "(black|white) { if (strncmp( yytext+6, "black", 5) == 0) { turn = BLACK; other = WHITE; direction = 1; start_pin = 0; end_pin = 25; Player[0].beginner_of_game = 1; Player[1].beginner_of_game = 0; } if (strncmp( yytext+6, "white", 5) == 0) { turn = WHITE; other = BLACK; direction = -1; start_pin = 25; end_pin = 0; Player[1].beginner_of_game = 1; Player[0].beginner_of_game = 0; } } "dice values: "[1-6]" "[1-6] { roll[0] = *(yytext+13) - '0'; roll[1] = *(yytext+15) - '0'; roll[0] *= direction; roll[1] *= direction; if (roll[0] == roll[1]) { roll[3] = roll[0]; roll[2] = roll[1]; to_move = 4; pash = 1; } else { roll[2] = roll[3] = 0; pash = 0; to_move = 2; } } "doubler value: "(1|2|4|8|16|32|64) { doubler.value = atoi((yytext+15)); } "last doubler: "(none|black|white) { if (*(yytext+14) == 'b') doubler.owner = BLACK; else if (*(yytext+14) == 'w') doubler.owner = WHITE; else doubler.owner = 0; } "on bar: "(black|white)": "[0-9]+", "(black|white)": "[0-9]+\n { char *r = yytext+8; r = strstr (yytext, "black: ") + strlen ("black: "); if ((Pin[0].count = atoi(r))) Pin[0].color = BLACK; r = strstr (yytext, "white: ") + strlen ("white: "); if ((Pin[25].count = atoi(r))) Pin[25].color = WHITE; found_black += Pin[0].count; found_white += Pin[25].count; } "pin "[0-9]+": "[0-9]+" "(black|white) { int p, m; char *r = yytext+4; p = atoi(r); while (*r != ' ') r++; r++; m = atoi (r); while (*r != ' ') r++; r++; if (strncmp(r, "black", 5) == 0) { Pin[p].color = BLACK; found_black += m; } else if (strncmp(r, "white", 5) == 0) { Pin[p].color = WHITE; found_white += m; } Pin[p].count = m; } ("money-game"|"best of "[0-9]+|[0-9]+" points")" match between "[a-zA-Z0-9]*" and "[a-zA-Z0-9]*":"\n { int i = 1; char *r = strstr(yytext, "between") + 8; if (kind == 'g') { while (*(r+i) != ' ') i++; strncpy (Player[0].name, r, i-1); *(Player[0].name+i) = '\0'; r = r+i+5; i=1; while (*(r+i) != ':') i++; strncpy (Player[1].name, r, i); *(Player[0].name+i) = '\0'; have_tournament = 1; if (strncmp (yytext, "money-game", 10) == 0) { sprintf (add_text, "%s and %s play a money-game match", Player[0].name, Player[1].name); tournament.winning_point = 0; gammon_resource.moneygame = 1; } else { sprintf (add_text, "%s and %s play a %d points match", Player[0].name, Player[1].name, tournament.winning_point); gammon_resource.moneygame = 0; gammon_resource.winat = tournament.winning_point = atoi(yytext); } AppendDialogText (UPPER, add_text); } } [a-zA-Z0-9]*" has "[0-9]+"points, "[a-zA-Z0-9]*" has "[0-9]+"points."\n { char *r = strstr (yytext, "has") + 4, *p; if (strncmp (yytext, Player[0].name, strlen(Player[0].name)) == 0) Player[0].points = atoi(yytext); else if (strncmp (yytext, Player[1].name, strlen(Player[1].name)) == 0) Player[1].points = atoi(yytext); while (*r != ',') r++; r+=2; if (strncmp (r, Player[0].name, strlen(Player[0].name)) == 0) { p = strstr(r, "has") + 4; Player[0].points = atoi(p); } else if (strncmp (r, Player[1].name, strlen(Player[1].name)) == 0) { p = strstr(r, "has") + 4; Player[1].points = atoi(p); } sprintf (add_text, "%s points: %d, %s points: %d", Player[1].name, Player[1].points, Player[0].name, Player[0].points); AppendDialogText (UPPER, add_text); } "point values:" { count = 0; endarray = 24; inarray = (point_values+1); } "prime length factors:" { if (count < 24) { fprintf (stderr, "incomplete array: point_values\n"); } count = 0; endarray = 8; inarray = prime_length_factor; } [0-9]*"."[0-9]* { fval = atof (yytext); if ((count ++) >= endarray) { fprintf (stderr, "too many float values for array %s\n", (endarray == 24) ? "point_values" : "prine_length_factor"); } else { *(inarray++) = fval; } } . ; \n ; %% void load (Widget w, XEvent *e, String *vector, Cardinal *count) { FILE *f; char * filename = "xgammon.save"; int i; if (*vector[0] == 'p') kind = 'p'; /* position */ else if (*vector[0] == 'g') kind = 'g'; /* game */ else if (*vector[0] == 'r') kind = 'r'; /* replay */ else if (*vector[0] == 'm') { /* menu */ if (replaying) kind = 'r'; else kind = 'g'; filename = vector[1]; } f = fopen (filename,"r"); if (!f) { AppendDialogText (LOWER, "Couldn't open save file for reading, sorry!\n"); return; } for (i=0; i<29; i++) { Pin[i].color = 0; Pin[i].count = 0; } found_black = found_white = 0; if (!wraped) { yyin = f; wraped = 1; } else { yyin = f; YY_NEW_FILE; } count = 0; have_tournament = 0; if (kind != 'r') BEGIN LOAD; else { BEGIN REPLAY; games_replayed = 0; } Player[0].points = Player[1].points = 0; if (!gammon_resource.rollout) { AppendDialogText (LOWER, "\ngame aborted\n"); } if (kind != 'r') AppendDialogText (LOWER, "\ntournament restart\nloading position\n\n"); yylex(); fclose (f); if (!replaying) { if (found_white<15) Pin[25+WHITE].count = 15 - found_white; if (found_black<15) Pin[25+BLACK].count = 15 - found_black; if (turn == BLACK) { Player[0].beginner_of_game = 1; Player[1].beginner_of_game = 0; } else { Player[0].beginner_of_game = 0; Player[1].beginner_of_game = 1; } } else { end_of_game = 1; end_of_tournament = 1; break_loop = REPLAY_GAME; initialize = REPLAY_GAME; replaying = 0; return; } if (!gammon_resource.rollout) { DrawEmptyBoard (); DrawBoard (); RedrawAllStones (); DrawDice (turn); DrawDoubler (doubler.value, doubler.owner); sprintf (add_text, "%s rolls %d and %d.\n", Player[turn-1].name, roll[0], roll[1]); AppendDialogText (LOWER, add_text); break_loop = initialize = LOADED_POSITION; end_of_game = 1; } } void print_move (MOVE *m) { int i; for (i=0; i<4; i++) fprintf (stderr,"%d %d\t", (m+i)->from, (m+i)->to); fprintf (stderr,"\n"); } void replay_init_game (void) { int i; DrawEmptyBoard (); DrawBoard (); for (i=0; i<29; i++) { Pin[i].count=0; Pin[i].color=0; } Pin[ 1].color = BLACK; Pin[ 1].count = 2; Pin[12].color = BLACK; Pin[12].count = 5; Pin[17].color = BLACK; Pin[17].count = 3; Pin[19].color = BLACK; Pin[19].count = 5; Pin[ 6].color = WHITE; Pin[ 6].count = 5; Pin[ 8].color = WHITE; Pin[ 8].count = 3; Pin[13].color = WHITE; Pin[13].count = 5; Pin[24].color = WHITE; Pin[24].count = 2; RedrawAllStones (); Pin[(25+BLACK)].color = BLACK; Pin[(25+WHITE)].color = WHITE; doubler.value = 1; doubler.owner = 0; DrawDoubler (doubler.value, doubler.owner); } void load_config (void) { FILE *f; if (!(f = fopen ("xgammon.config", "r"))) { fprintf (stderr, "Couldn't open config file for reading, sorry!\n"); return; } if (!wraped) { yyin = f; wraped = 1; } else { yyin = f; YY_NEW_FILE; } BEGIN LOAD_CONFIG; yylex(); if (count < 8) { fprintf (stderr, "incomplete array: prime_length_factors\n"); } count = 0; fclose (f); }