Beispiel #1
0
// -----------------------------------------------------------------------
// Make_My_Move:
//
void Make_My_Move (Gmp* ge, GO_BOARD board, GO_PIECE my_stone, int move_number)
{
  int  x, y;
fprintf (debug, "\nPOSITION BEFORE OUR MOVE:\n");
Go_Board_Show (board, debug);

  if ((Get_Move (board, my_stone, move_number, &x, &y) > NO_SUITABLE_MOVE) &&
       (x >= 0) && (y >= 0))
  {
    Go_Board_Place_Stone (board, my_stone, x, y);
fprintf (debug, "\nPOSITION AFTER OUR MOVE:\n");
Go_Board_Show (board, debug);
fflush (debug);

    passes = 0;
    gmp_sendMove(ge, x, y);
  }
  else
  {
    //
    // No suitable move. Pass.
    //
    Go_Board_Set_Player (board, my_stone);
    Go_Board_Pass (board);
fprintf (debug, "\nPOSITION AFTER OUR MOVE (Pass):\n");
Go_Board_Show (board, debug);
fflush (debug);
    gmp_sendPass(ge);
  	
    if (++passes >= 2)
    {
      Go_Board_Destroy (&board);
      exit (0);
    }   // 2nd pass, game over, man!
  }   // else pass
}   // Make_My_Move
Beispiel #2
0
/* --------------------------------------------------------------*/
void
play_gmp(Gameinfo *gameinfo, int simplified)
{
  SGFTree sgftree;

  Gmp *ge;
  GmpResult message;
  const char *error;
  
  int i, j;
  int passes = 0; /* two passes and its over */
  int to_move;  /* who's turn is next ? */

  int mycolor = -1;  /* who has which color */
  int yourcolor;

  if (gameinfo->computer_player == WHITE)
    mycolor = 1;
  else if (gameinfo->computer_player == BLACK)
    mycolor = 0;

  sgftree_clear(&sgftree);
  sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap);

  ge = gmp_create(0, 1);
  TRACE("board size=%d\n", board_size);

  /* 
   * The specification of the go modem protocol doesn't even discuss
   * komi. So we have to guess the komi. If the komi is set on the
   * command line, keep it. Otherwise, its value will be 0.0 and we
   * use 5.5 in an even game, 0.5 otherwise.
   */
  if (komi == 0.0) {
    if (gameinfo->handicap == 0)
      komi = 5.5;
    else
      komi = 0.5;
  }

  if (!simplified) {
    /* Leave all the -1's so the client can negotiate the game parameters. */
    if (chinese_rules)
      gmp_startGame(ge, -1, -1, 5.5, -1, mycolor, 0);
    else
      gmp_startGame(ge, -1, -1, 5.5, 0, mycolor, 0);
  }
  else {
    gmp_startGame(ge, board_size, gameinfo->handicap,
		  komi, chinese_rules, mycolor, 1);
  }

  do {
    message = gmp_check(ge, 1, NULL, NULL, &error);
  } while (message == gmp_nothing || message == gmp_reset);
  
  if (message == gmp_err) {
    fprintf(stderr, "gnugo-gmp: Error \"%s\" occurred.\n", error);
    exit(EXIT_FAILURE);
  }
  else if (message != gmp_newGame) {
    fprintf(stderr, "gnugo-gmp: Expecting a newGame, got %s\n",
	    gmp_resultString(message));
    exit(EXIT_FAILURE);
  }

  gameinfo->handicap = gmp_handicap(ge);
  if (!check_boardsize(gmp_size(ge), stderr))
    exit(EXIT_FAILURE);
  
  gnugo_clear_board(gmp_size(ge));

  /* Let's pretend GMP knows about komi in case something will ever change. */
  komi = gmp_komi(ge);

#if ORACLE
  if (metamachine && oracle_exists)
    oracle_clear_board(board_size);
#endif

  sgfOverwritePropertyInt(sgftree.root, "SZ", board_size);

  TRACE("size=%d, handicap=%d, komi=%f\n", board_size,
	gameinfo->handicap, komi);

  if (gameinfo->handicap)
    to_move = WHITE;
  else
    to_move = BLACK;

  if (gmp_iAmWhite(ge)) {
    mycolor = WHITE;     /* computer white */
    yourcolor = BLACK;   /* human black */
  }
  else {
    mycolor = BLACK;
    yourcolor = WHITE;
  }

  gameinfo->computer_player = mycolor;
  sgf_write_header(sgftree.root, 1, get_random_seed(), komi,
		   gameinfo->handicap, get_level(), chinese_rules);
  gameinfo->handicap = gnugo_sethand(gameinfo->handicap, sgftree.root);
  sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);

  /* main GMP loop */
  while (passes < 2) {

    if (to_move == yourcolor) {
      int move;
      /* Get opponent's move from gmp client. */
      message = gmp_check(ge, 1, &j, &i, &error);

      if (message == gmp_err) {
	fprintf(stderr, "GNU Go: Sorry, error from gmp client\n");
        sgftreeAddComment(&sgftree, "got error from gmp client");
        sgffile_output(&sgftree);
	return;
      }

      if (message == gmp_undo) {
	int k;
	assert(j > 0);
	
	for (k = 0; k < j; k++) {
	  if (!undo_move(1)) {
	    fprintf(stderr, "GNU Go: play_gmp UNDO: can't undo %d moves\n",
		    j - k);
	    break;
	  }
	  sgftreeAddComment(&sgftree, "undone");
	  sgftreeBack(&sgftree);
	  to_move = OTHER_COLOR(to_move);
	}
	continue;
      }

      if (message == gmp_pass) {
	passes++;
	move = PASS_MOVE;
      }
      else {
	passes = 0;
	move = POS(i, j);
      }

      TRACE("\nyour move: %1m\n\n", move);
      sgftreeAddPlay(&sgftree, to_move, I(move), J(move));
      gnugo_play_move(move, yourcolor);
      sgffile_output(&sgftree);

    }
    else {
      /* Generate my next move. */
      float move_value;
      int move;
      if (autolevel_on)
	adjust_level_offset(mycolor);
      move = genmove(mycolor, &move_value, NULL);
      gnugo_play_move(move, mycolor);
      sgffile_add_debuginfo(sgftree.lastnode, move_value);
      
      if (is_pass(move)) {
	/* pass */
        sgftreeAddPlay(&sgftree, to_move, -1, -1);
	gmp_sendPass(ge);
	++passes;
      }
      else {
	/* not pass */
        sgftreeAddPlay(&sgftree, to_move, I(move), J(move));
	gmp_sendMove(ge, J(move), I(move));
	passes = 0;
	TRACE("\nmy move: %1m\n\n", move);
      }
      sgffile_add_debuginfo(sgftree.lastnode, 0.0);
      sgffile_output(&sgftree);
    }
    
    to_move = OTHER_COLOR(to_move);
  }
  
  /* two passes: game over */
  gmp_sendPass(ge);   
  
  if (!quiet)
    fprintf(stderr, "Game over - waiting for client to shut us down\n");
  who_wins(mycolor, stderr);

  if (showtime) {
    gprintf("\nSLOWEST MOVE: %d at %1m ", slowest_movenum, slowest_move);
    fprintf(stderr, "(%.2f seconds)\n", slowest_time);
    fprintf(stderr, "\nAVERAGE TIME: %.2f seconds per move\n",
	    total_time / movenum);
    fprintf(stderr, "\nTOTAL TIME: %.2f seconds\n",
	    total_time);
  }
  
  
  /* play_gmp() does not return to main(), therefore the score
   * writing code is here.
   */
  { 
    float score = gnugo_estimate_score(NULL, NULL);
    sgfWriteResult(sgftree.root, score, 1);
  }
  sgffile_output(&sgftree);

  if (!simplified) {
    /* We hang around here until cgoban asks us to go, since
     * sometimes cgoban crashes if we exit first.
     *
     * FIXME: Check if this is still needed.  I made it dependand on
     *	      `simplifed' just to avoid changes in GMP mode.
     */
    while (1) {
      message = gmp_check(ge, 1, &j, &i, &error);
      if (!quiet)
	fprintf(stderr, "Message %d from gmp\n", message);
      if (message == gmp_err)
	break;
    }
  }

#if ORACLE
  if (metamachine && oracle_exists)
    dismiss_oracle();
#endif

  if (!quiet)
    fprintf(stderr, "gnugo going down\n");
}
Beispiel #3
0
/*
 * This is just about the world's stupidest go player.  It picks random
 *   locations, checking for moves with at least one liberty.  If it finds
 *   one, it makes the move.  Otherwise it tries again.  Eventually it will
 *   give up and pass.
 * It is so stupid it doesn't even deal with captures or undos.
 */
static void  playGame(Gmp *ge, int size, int himFirst)  {
  int  *board, i, x, y;
  int  moveMade, passes = 0;
  GmpResult  message;
  const char  *error;

  board = malloc(size * size * sizeof(int));
  for (i = 0;  i < size * size;  ++i)
    board[i] = 0;
  for (;;)  {
    if (!himFirst)  {
      moveMade = 0;
      for (i = 0;  (i < 50) && !moveMade;  ++i)  {
	x = rand() % size;
	y = rand() % size;
	if ((board[x + y * size] == 0) &&
	    (((x > 0) && (board[(x - 1) + y * size] == 0)) ||
	     ((y > 0) && (board[x + (y - 1) * size] == 0)) ||
	     ((x < size-1) && (board[(x + 1) + y * size] == 0)) ||
	     ((y < size-1) && (board[x + (y + 1) * size] == 0))))  {
	  passes = 0;
	  gmp_sendMove(ge, x, y);
	  board[x + y * size] = 1;
	  moveMade = 1;
	}
      }
      if (!moveMade)  {
	gmp_sendPass(ge);
	if (++passes == 2)  {
	  /*
	   * Game over!
	   */
	  return;
	}
      }
    }
    himFirst = 0;
    do  {
      message = gmp_check(ge, 1, &x, &y, &error);
    } while (message == gmp_nothing);
    if (message == gmp_err)  {
      fprintf(stderr, "dummy: Got error \"%s\"\n", error);
      exit(1);
    }
    if (message == gmp_move)  {
      passes = 0;
      board[x + y * size] = 1;
    } else if (message == gmp_pass)  {
      if (++passes == 2)  {
	/*
	 * Game over!
	 */
	return;
      }
    } else if (message == gmp_reset)  {
      /* Game over! */
      return;
    } else if (message == gmp_undo)  {
      fprintf(stderr, "dummy: I am asked to undo %d moves.\n", x);
      if ((x & 1) == 0)  {
	/*
	 * Since an even number of undos were made, it is still the other
	 *   player's turn.  This flag makes me skip my turn.
	 */
	himFirst = 1;
      }
    } else  {
      fprintf(stderr, "Got a \"%s\" command during game play.  Exiting.\n",
	      gmp_resultString(message));
      exit(1);
    }
  }
}