/* rollout.c 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 #include #include #include "xgammon.h" #include "gammon.h" extern XtAppContext app_con; extern FILE *endgame_database; extern void Quit (); extern void CreateRolloutText (); extern void load (); extern void save (); extern int do_double (); extern int test_move (); extern MOVE *find_best_move (); extern int end_of_game_test (); void RollOut (); void RolloutLoop (void); void RolloutGame (void); void RolloutMove (void); void init_rollout (void); void rollout_roll_dice (); void exec_rollout (); void RollOut (void) { Widget toplevel = Player[0].X11Set.toplevel; char *v[2], *flag = "m"; XEvent event; int i; CreateRolloutText (toplevel); XtRealizeWidget (toplevel); v[0] = flag; v[1] = gammon_resource.position_file; load (0L, 0L, v, 0); for (i=0; i<29; i++) { rollout_position[i].count = Pin[i].count; rollout_position[i].color = Pin[i].color; } rollout_save.turn = turn; rollout_save.doubler_value = doubler.value; rollout_save.doubler_owner = doubler.owner; rollout_save.roll[0] = roll[0]; rollout_save.roll[1] = roll[1]; tournament.winning_point = gammon_resource.num_rollouts; AppendDialogText (LOWER, "xgammon rollout: "); sprintf (add_text, "rollout: %d games\n", gammon_resource.num_rollouts); AppendDialogText (LOWER, add_text); AppendDialogText (LOWER, "points: white 0, black 0\n"); Player[0].points = 0; Player[1].points = 0; XSync (Player[0].X11Set.dpy, 0); RolloutLoop (); while (XtAppPending (app_con)) { /* delete event queue */ XtAppNextEvent (app_con, &event); XtDispatchEvent (&event); } AppendDialogText (LOWER, "rollout done\n(any button or key event will quit.)\n\n"); while (1) { XtAppNextEvent (app_con, &event); if (event.type == ButtonPress || event.type == KeyPress) break; XtDispatchEvent (&event); } Quit (toplevel, 0L, 0L); } void RolloutLoop (void) { FILE *result_file; unsigned int won_games[3] ={0,0,0}; while (tournament.game_number < tournament.winning_point) { init_rollout (); RolloutGame (); Player[turn-1].points += doubler.value; won_games[turn] ++; sprintf (add_text, "done.. won games: black %d, white %d points: black %d, white %d\n",won_games[BLACK], won_games[WHITE], Player[0].points, Player[1].points); AppendDialogText (LOWER, add_text); } result_file = fopen (gammon_resource.position_file, "a"); AppendDialogText(LOWER, "\nrollout complete. result:\n"); fprintf (result_file, "\nrollout result of %d games:\n", tournament.winning_point); sprintf (add_text, "of %d games\n", tournament.winning_point); AppendDialogText (LOWER, add_text); sprintf (add_text, " black won %d games and got %d points.\n", won_games[BLACK], Player[0].points); fprintf (result_file, add_text); AppendDialogText (LOWER, add_text); sprintf (add_text, " white won %d games and got %d points.\n", won_games[WHITE], Player[1].points); fprintf (result_file, add_text); AppendDialogText (LOWER, add_text); sprintf (add_text, " backgammons: black: %d white %d\n", Player[BLACK].backgammons, Player[WHITE].backgammons); fprintf (result_file, add_text); AppendDialogText (LOWER, add_text); sprintf (add_text, " gammons: black: %d white %d\n", Player[BLACK].gammons, Player[WHITE].gammons); fprintf (result_file, add_text); AppendDialogText (LOWER, add_text); sprintf (add_text, " in percent: black won %2.2f%%, white won %2.2f%%\n\n\n", ((float) won_games[BLACK] * 100 / (float) tournament.winning_point), ((float) won_games[WHITE] * 100 / (float) tournament.winning_point)); fprintf (result_file, add_text); AppendDialogText (LOWER, add_text); fclose (result_file); XSync (Player[0].X11Set.dpy, 0); /* and 7 seconds */ } void RolloutGame (void) { end_of_game = 0; while (1) { RolloutMove(); if (end_of_game) break; switch_turn(); /* RolloutMove(); if (end_of_game) break; switch_turn(); */ } } void RolloutMove (void) { int i; if (gammon_resource.doubling) { if (doubler.owner != turn && doubler.value <= 64) { doubler.owner = turn; if (!do_double (OFFER)) { end_of_game = 1; return; } } } rollout_roll_dice(); if (test_move()) { MOVE *this_move; this_move = find_best_move (); for (i=0; ifrom].count--; if (Pin[(this_move+i)->from].count == 0) Pin[(this_move+i)->from].color = 0; if ((this_move+i)->to == end_pin) { if ((end_of_game = end_of_game_test(turn))) return; } else if (Pin[(this_move+i)->to].color == other) { Pin[(this_move+i)->to].color = turn; Pin[OTHER_BAR].count++; Pin[OTHER_BAR].color = other; } else { Pin[(this_move+i)->to].count++; Pin[(this_move+i)->to].color = turn; } } } } void init_rollout (void) { int i; for (i=0; i<29; i++) { Pin[i].count = rollout_position[i].count; Pin[i].color = rollout_position[i].color; } turn = rollout_save.turn; doubler.value = rollout_save.doubler_value; doubler.owner = rollout_save.doubler_owner; /*roll[0] = rollout_save.roll[0]; roll[1] = rollout_save.roll[1]; if (roll[0] != roll[1]) { roll[2] = 0; roll[3] = 0; to_move = 2; pash = 0; } else { roll[2] = roll[0]; roll[3] = roll[1]; to_move = 4; pash = 1; }*/ rollout_roll_dice (); switch_turn(); switch_turn(); /* set vars */ tournament.game_number++; sprintf(add_text,"rollout game number %d\n", tournament.game_number); AppendDialogText(LOWER, add_text); } void rollout_roll_dice (void) { roll[0] = (random()%6 + 1) * direction; roll[1] = (random()%6 + 1) * direction; if (roll[0] != roll[1]) { roll[2] = 0; /* sure and necessary */ roll[3] = 0; to_move = 2; pash = 0; } else { roll[2] = roll[0]; roll[3] = roll[1]; to_move = 4; pash = 1; } } /* saves the current position in a (position) save file, and then execs a xgammon with approriate options. this is why: 1. cause of some problems with X* libs xgammon will grow (fast) in memory usage. After about 650 games with certain optins, it will use about 24 Mb space. (This is not an xgammon fault (!?!) Other programs also do, for example play (at least older versions of) xbombs and do a ps -m sometimes). But they are running only short times and don't use that much graphics). This may be fixed some day. 2. you'll get bored with it and your eyes will hurt, and it's slow 3. you can continue playing */ void exec_rollout (void) { int pid; /* execed process */ int ppid = getpid(); /* this process */ static int called_rollout = 0; /* count to make files somewhat unequivocal */ char *argv[8]; char *v[3]; char rollout_save_file[50]; char nr[7]; sprintf (nr, "%d", gammon_resource.num_rollouts); sprintf (rollout_save_file, "xgammon.rollout.%d.save", (ppid + called_rollout++)); v[0] = "r"; v[1] = rollout_save_file; v[2] = NULL; save (0L, 0L, v, 0); argv[0] = "xgammon"; argv[1] = "-rollout"; argv[2] = "-nr"; argv[3] = nr; argv[4] = "-f"; argv[5] = rollout_save_file; argv[6] = "-doubling"; /* yet necessary */ argv[7] = NULL; #ifdef SIGCHLD signal(SIGCHLD, SIG_IGN); #else signal(SIGCLD, SIG_IGN); #endif if ((pid=fork()) == 0) { execvp ("xgammon", argv); } else if (pid>0) { return; } else { /* should not happen */ AppendDialogText(LOWER, "sorry, couldn't fork rollout process\n"); return; } }