void
decide_eye(int pos)
{
  int color;
  struct eyevalue value;
  int attack_point;
  int defense_point;
  int eyepos;
  SGFTree tree;

  reset_engine();
  silent_examine_position(BLACK, EXAMINE_DRAGONS_WITHOUT_OWL);
  
  if (black_eye[pos].color == BLACK_BORDER) 
    color = BLACK;
  else if (white_eye[pos].color == WHITE_BORDER) 
    color = WHITE;
  else {
    gprintf("The eye at %1m is not of a single color.\n", pos);
    return;
  }

  if (printboard)
    showboard(0);

  /* Enable sgf output. */
  if (*outfilename)
    sgffile_begindump(&tree);
  count_variations = 1;
  
  if (black_eye[pos].color == BLACK_BORDER) {
    eyepos = black_eye[pos].origin;
    compute_eyes(eyepos, &value, &attack_point, &defense_point,
		 black_eye, half_eye, 0, EMPTY);
    gprintf("Black eyespace at %1m: %s\n", eyepos, eyevalue_to_string(&value));
    if (eye_move_urgency(&value) > 0) {
      gprintf("  vital points: %1m (attack) %1m (defense)\n", attack_point,
	      defense_point);
    }
  }
  
  if (white_eye[pos].color == WHITE_BORDER) {
    eyepos = white_eye[pos].origin;
    compute_eyes(eyepos, &value, &attack_point, &defense_point,
		 white_eye, half_eye, 0, EMPTY);
    gprintf("White eyespace at %1m: %s\n", eyepos, eyevalue_to_string(&value));
    if (eye_move_urgency(&value) > 0) {
      gprintf("  vital points: %1m (attack) %1m (defense)\n", attack_point,
	      defense_point);
    }
  }
  
  /* Finish sgf output. */
  sgffile_enddump(outfilename);
  count_variations = 0;
}
void
decide_dragon_data(int pos)
{
  if (board[pos] == EMPTY) {
    fprintf(stderr, "gnugo: --decide-dragon-data called on an empty vertex\n");
    return ;
  }
  reset_engine();
  silent_examine_position(board[pos], FULL_EXAMINE_DRAGONS);

  gprintf("Dragon at %1m:\n", pos);
  report_dragon(stderr, pos);
}
Example #3
0
void
decide_semeai(int apos, int bpos)
{
  SGFTree tree;
  int resulta, resultb, move, result_certain;
  int color = board[apos];

  if (color == EMPTY || board[bpos] != OTHER_COLOR(color)) {
    gprintf("gnugo: --decide-semeai called on invalid data\n");
    return;
  }

  /* Prepare pattern matcher and reading code. */
  reset_engine();

  silent_examine_position(EXAMINE_DRAGONS_WITHOUT_OWL);
  gprintf("finished examine_position\n");
  count_variations = 1;

  if (*outfilename)
    sgffile_begindump(&tree);

  gprintf("Analyzing semeai between %1m and %1m, %C moves first\n",
	  apos, bpos, board[apos]);
  owl_analyze_semeai(apos, bpos, &resulta, &resultb, &move, &result_certain);
  gprintf("Semeai defense of %1m: result %s %1m\n",
	  apos, result_to_string(resulta), move);
  gprintf("Semeai attack of %1m: result %s %1m\n",
	  bpos, result_to_string(resultb), move);
  gprintf("%d nodes%s\n\n", count_variations,
	  result_certain ? "" : ", uncertain result");
  
  gprintf("Analyzing semeai between %1m and %1m, %C moves first\n",
	  bpos, apos, board[bpos]);
  owl_analyze_semeai(bpos, apos, &resultb, &resulta, &move, &result_certain);
  gprintf("Semeai defense of %1m: result %s %1m\n",
	  bpos, result_to_string(resultb), move);
  gprintf("Semeai attack of %1m: result %s %1m\n",
	  apos, result_to_string(resulta), move);
  gprintf("%d nodes%s\n", count_variations,
	  result_certain ? "" : ", uncertain result");

  sgffile_enddump(outfilename);
  count_variations = 0;
}
void
decide_tactical_semeai(int apos, int bpos)
{
  SGFTree tree;
  int resulta, resultb, move;
  int color = board[apos];

  if (color == EMPTY || board[bpos] != OTHER_COLOR(color)) {
    gprintf("gnugo: --decide-semeai called on invalid data\n");
    return;
  }

  /* Prepare pattern matcher and reading code. */
  reset_engine();

  silent_examine_position(board[apos], EXAMINE_DRAGONS_WITHOUT_OWL);
  gprintf("finished examine_position\n");
  count_variations = 1;

  /* We want to see the reading performed, not just a result picked
   * from the cache. Thus we clear the cache here. */
  reading_cache_clear();
  
  if (*outfilename)
    sgffile_begindump(&tree);

  owl_analyze_semeai(apos, bpos, &resulta, &resultb, &move, 0);
  gprintf("After %s at %1m, %1m is %s, %1m is %s (%d nodes)\n",
	  color == BLACK ? "black" : "white",
	  move,
	  apos, safety_to_string(resulta),
  	  bpos, safety_to_string(resultb),
	  count_variations);
  owl_analyze_semeai(bpos, apos, &resultb, &resulta, &move, 0);
  gprintf("After %s at %1m, %1m is %s, %1m is %s (%d nodes)\n",
	  color == BLACK ? "white" : "black",
	  move,
	  apos, safety_to_string(resulta),
  	  bpos, safety_to_string(resultb),
	  count_variations);

  sgffile_enddump(outfilename);
  count_variations = 0;
}
void
decide_surrounded(int pos)
{
  int surround_status;

  if (board[pos] == EMPTY) {
    fprintf(stderr, "location must not be empty!\n");
    return;
  }

  /* Prepare pattern matcher and reading code. */
  reset_engine();

  silent_examine_position(board[pos], EXAMINE_ALL);
  surround_status = compute_surroundings(pos, NO_MOVE, 1, NULL);
  if (surround_status == 1)
    gprintf("the dragon at %1m is SURROUNDED!\n", pos);
  else if (surround_status == 2)
    gprintf("the dragon at %1m is WEAKLY SURROUNDED!\n", pos);
  else
    gprintf("the dragon at %1m is not surrounded.\n", pos);
}  
void
decide_combination(int color)
{
  int attack_move;
  char defense_moves[BOARDMAX];
  SGFTree tree;
  int first = 1;
  int pos;

  /* Prepare pattern matcher and reading code. */
  reset_engine();

  silent_examine_position(color, EXAMINE_ALL);

  if (*outfilename)
    sgffile_begindump(&tree);
  count_variations = 1;

  if (atari_atari(color, &attack_move, defense_moves, verbose)) {
    gprintf("Combination attack for %C at %1m, defense at ", color,
	    attack_move);
    for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
      if (ON_BOARD(pos) && defense_moves[pos]) {
	if (first)
	  first = 0;
	else
	  gprintf(", ");
	gprintf("%1m", pos);
      }
    }
    gprintf("\n");
  }
  else
    gprintf("No Combination attack for %C\n", color);
  
  sgffile_enddump(outfilename);
  count_variations = 0;
}
void
decide_position(int color)
{
  int pos;
  int move = NO_MOVE;
  int acode = 0, dcode = 0;
  int kworm;
  static const char *snames[] = {"dead", "alive", "critical", "unknown"};
  SGFTree tree;

  /* Prepare pattern matcher and reading code. */
  reset_engine();

  silent_examine_position(color, EXAMINE_DRAGONS_WITHOUT_OWL);

  /* We want to see the reading performed, not just a result picked
   * from the cache. Thus we clear the cache here. */
  reading_cache_clear();

  if (*outfilename)
    sgffile_begindump(&tree);

  count_variations = 1;

  for (pos = BOARDMIN; pos < BOARDMAX; pos++) {
    if (!ON_BOARD(pos)
	|| dragon[pos].origin != pos
	|| board[pos] == EMPTY
	|| DRAGON2(pos).escape_route >= 6)
      continue;

    gprintf("\nanalyzing %1m\n", pos);
    gprintf("status=%s, escape=%d\n", 
	    snames[dragon[pos].crude_status], DRAGON2(pos).escape_route);
    acode = owl_attack(pos, &move, NULL, &kworm);
    if (acode) {
      if (acode == WIN) {
	if (move == NO_MOVE)
	  gprintf("%1m is dead as it stands\n", pos);
	else
	  gprintf("%1m can be attacked at %1m (%d variations)\n", 
		  pos, move, count_variations);
      }
      else if (acode == KO_A)
	gprintf("%1m can be attacked with ko (good) at %1m (%d variations)\n", 
		pos, move, count_variations);
      else if (acode == KO_B)
	gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)\n", 
		pos, move, count_variations);
      else if (acode == GAIN)
	gprintf("%1m can be attacked with gain (captures %1m) at %1m (%d variations)", 
		pos, kworm, move, count_variations);
      
      count_variations = 1;
      dcode = owl_defend(pos, &move, NULL, &kworm);
      if (dcode) {
	if (dcode == WIN) {
	  if (move == NO_MOVE)
	    gprintf("%1m is alive as it stands\n", pos);
	  else 
	    gprintf("%1m can be defended at %1m (%d variations)\n", 
		    pos, move, count_variations);
	}
	else if (dcode == KO_A)
	  gprintf("%1m can be defended with ko (good) at %1m (%d variations)\n", 
		  pos, move, count_variations);
	else if (dcode == KO_B)
	  gprintf("%1m can be defended with ko (bad) at %1m (%d variations)\n",
		  pos, move, count_variations);
	else if (dcode == LOSS)
	  gprintf("%1m can be defended with loss (loses %1m) at %1m (%d variations)", 
		  pos, kworm, move, count_variations);
      }
      else
	gprintf("%1m cannot be defended (%d variations)\n", 
		pos, count_variations);
    }
    else 
      gprintf("%1m cannot be attacked (%d variations)\n", 
	      pos, count_variations);
    
    if (acode) {
      if (dcode)
	gprintf("status of %1m revised to CRITICAL\n", pos);
      else
	gprintf("status of %1m revised to DEAD\n", pos);
    }
    else
      gprintf("status of %1m revised to ALIVE\n", pos);
  }
  
  sgffile_enddump(outfilename);
  count_variations = 0;
}
void
decide_owl(int pos)
{
  int move = NO_MOVE;
  int acode, dcode;
  SGFTree tree;
  int result_certain;
  int kworm;

  if (board[pos] == EMPTY) {
    fprintf(stderr, "gnugo: --decide-dragon called on an empty vertex\n");
    return ;
  }

  /* Prepare pattern matcher and reading code. */
  reset_engine();

  silent_examine_position(board[pos], EXAMINE_DRAGONS_WITHOUT_OWL);
  gprintf("finished examine_position\n");

  /* We want to see the reading performed, not just a result picked
   * from the cache. Thus we clear the cache here.
   */
  reading_cache_clear();
  
  if (*outfilename)
    sgffile_begindump(&tree);

  count_variations = 1;
  acode = owl_attack(pos, &move, &result_certain, &kworm);
  if (acode) {
    if (acode == WIN) {
      if (move == NO_MOVE)
	gprintf("%1m is dead as it stands", pos);
      else
	gprintf("%1m can be attacked at %1m (%d variations)", 
		pos, move, count_variations);
    }
    else if (acode == KO_A)
      gprintf("%1m can be attacked with ko (good) at %1m (%d variations)", 
	      pos, move, count_variations);
    else if (acode == KO_B)
      gprintf("%1m can be attacked with ko (bad) at %1m (%d variations)", 
	      pos, move, count_variations);
    else if (acode == GAIN)
      gprintf("%1m can be attacked with gain (captures %1m) at %1m (%d variations)", 
	      pos, kworm, move, count_variations);
  }
  else 
    gprintf("%1m cannot be attacked (%d variations)", pos, count_variations);
  
  if (result_certain)
    gprintf("\n");
  else
    gprintf(" result uncertain\n");

  reading_cache_clear();
  count_variations = 1;
  dcode = owl_defend(pos, &move, &result_certain, &kworm);

  if (dcode) {
    if (dcode == WIN) {
      if (move == NO_MOVE)
	gprintf("%1m is alive as it stands", pos);
      else 
	gprintf("%1m can be defended at %1m (%d variations)", 
		pos, move, count_variations);
    }
    else if (dcode == KO_A)
      gprintf("%1m can be defended with ko (good) at %1m (%d variations)", 
	      pos, move, count_variations);
    else if (dcode == KO_B)
      gprintf("%1m can be defended with ko (bad) at %1m (%d variations)", 
	      pos, move, count_variations);
    else if (dcode == LOSS)
      gprintf("%1m can be defended with loss (loses %1m) at %1m (%d variations)", 
	      pos, kworm, move, count_variations);
  }
  else
    gprintf("%1m cannot be defended (%d variations)",
	    pos, count_variations);

  if (result_certain)
    gprintf("\n");
  else
    gprintf(" result uncertain\n");
  
  sgffile_enddump(outfilename);
  count_variations = 0;
}
Example #9
0
void
do_play_ascii(Gameinfo *gameinfo)
{
  int m, num;
  float fnum;
  int passes = 0;  /* two passes and its over */
  int tmp;
  char line[80];
  char *line_ptr = line;
  char *command;
  char *tmpstring;
  int state = 1;

  if (have_time_settings())
    clock_on = 1;

  while (state == 1) {
    state = 0;

    /* No score is estimated yet. */
    current_score_estimate = NO_SCORE;

    /* Allow resignation at interface level (the engine may still be not
     * allowed to resign.
     */
    resignation_allowed = 1;

    printf("\nBeginning ASCII mode game.\n\n");
    gameinfo_print(gameinfo);

    /* Does the computer play first?  If so, make a move. */
    if (gameinfo->computer_player == gameinfo->to_move)
      state = computer_move(gameinfo, &passes);

    /* main ASCII Play loop */
    while (state == 0) {
      /* Display game board. */
      if (opt_showboard)
	ascii_showboard();

#if !READLINE
      /* Print the prompt */
      mprintf("%s(%d): ", color_to_string(gameinfo->to_move), movenum + 1);

      /* Read a line of input. */
      line_ptr = line;
      if (!fgets(line, 80, stdin))
	return;
#else
      snprintf(line, 79, "%s(%d): ",
	       color_to_string(gameinfo->to_move), movenum + 1);
      if (!(line_ptr = readline(line)))
	return;

      add_history(line_ptr);
#endif

      while (state == 0
	     && (command = strtok(line_ptr, ";"), line_ptr = 0, command)) {
	/* Get the command or move. */
	switch (get_command(command)) {
	case RESIGN:
	  state = ascii_endgame(gameinfo, 1);
	  break;

	case END:
	case EXIT:
	case QUIT:
	  return;

	case HELP:
	  show_commands();
	  break;

	case CMD_HELPDEBUG:
	  printf(DEBUG_COMMANDS);
	  break;

	case SHOWBOARD:
	  opt_showboard = !opt_showboard;
	  break;

	case INFO:
	  printf("\n");
	  gameinfo_print(gameinfo);
	  break;

	case SETBOARDSIZE:
	  if (sgf_initialized) {
	    printf("Boardsize cannot be changed after record is started!\n");
	    break;
	  }
	  command += 10;
	  if (sscanf(command, "%d", &num) != 1) {
	    printf("\nInvalid command syntax!\n");
	    break;
	  }
	  if (!check_boardsize(num, stdout))
	    break;
	  /* Init board. */
	  board_size = num;
	  clear_board();
	  /* In case max handicap changes on smaller board. */
	  gameinfo->handicap = place_fixed_handicap(gameinfo->handicap);
	  sgfOverwritePropertyInt(sgftree.root, "SZ", board_size);
	  sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
	  break;

	case SETHANDICAP:
	  if (sgf_initialized) {
	    printf("Handicap cannot be changed after game is started!\n");
	    break;
	  }
	  command += 9;
	  if (sscanf(command, "%d", &num) != 1) {
	    printf("\nInvalid command syntax!\n");
	    break;
	  }
	  if (num < 0 || num > MAX_HANDICAP) {
	    printf("\nInvalid handicap: %d\n", num);
	    break;
	  }
	  /* Init board. */
	  clear_board();
	  /* Place stones on board but don't record sgf 
	   * in case we change more info. */
	  gameinfo->handicap = place_fixed_handicap(num);
	  printf("\nSet handicap to %d\n", gameinfo->handicap);
          gameinfo->to_move = (gameinfo->handicap ? WHITE : BLACK);
	  break;

	case FREEHANDICAP:
	  if (sgf_initialized) {
	    printf("Handicap cannot be changed after game is started!\n");
	    break;
	  }
	  while (*command && *command != ' ')
	    command++;
	  ascii_free_handicap(gameinfo, command);
	  break;

	case SETKOMI:
	  if (sgf_initialized) {
	    printf("Komi cannot be modified after game record is started!\n");
	    break;
	  }
	  command += 5;
	  if (sscanf(command, "%f", &fnum) != 1) {
	    printf("\nInvalid command syntax!\n");
	    break;
	  }
	  komi = fnum;
	  printf("\nSet Komi to %.1f\n", komi);
	  break;

	case SETDEPTH:
	  command += 6;
	  if (sscanf(command, "%d", &num) != 1) {
	    printf("\nInvalid command syntax!\n");
	    break;
	  }
	  mandated_depth = num;
	  printf("\nSet depth to %d\n", mandated_depth);
	  break;

	case SETLEVEL:
	  command += 6;
	  if (sscanf(command, "%d", &num) != 1) {
	    printf("\nInvalid command syntax!\n");
	    break;
	  }
	  set_level(num);
	  printf("\nSet level to %d\n", num);
	  break;

	case DISPLAY:
	  if (!opt_showboard)
	    ascii_showboard();
	  break;

	case FORCE:
	  command += 6; /* skip the force part... */
	  switch (get_command(command)) {
	  case MOVE:
	    state = do_move(gameinfo, command, &passes, 1);
	    break;
	  case PASS:
	    state = do_pass(gameinfo, &passes, 1);
	    break;
	  default:
	    printf("Illegal forced move: %s %d\n", command,
		   get_command(command));
	    break;
	  }
	  break;

	case MOVE:
	  state = do_move(gameinfo, command, &passes, 0);
	  break;

	case PASS:
	  state = do_pass(gameinfo, &passes, 0);
	  break;

	case PLAY:
	  command += 5;
	  if (sscanf(command, "%d", &num) != 1) {
	    printf("\nInvalid command syntax!\n");
	    break;
	  }
	  if (num >= 0)
	    for (m = 0; m < num; m++) {
	      gameinfo->computer_player 
		= OTHER_COLOR(gameinfo->computer_player);
	      state = computer_move(gameinfo, &passes);
	      if (state)
		break;
	      if (passes >= 2)
		break;
	    }
	  else {
	    printf("\nInvalid number of moves specified: %d\n", num);
	    break;
	  }
	  break;

	case PLAYBLACK:
	  if (gameinfo->computer_player == WHITE)
	    gameinfo->computer_player = BLACK;
	  if (gameinfo->computer_player == gameinfo->to_move)
	    state = computer_move(gameinfo, &passes);
	  break;

	case PLAYWHITE:
	  if (gameinfo->computer_player == BLACK)
	    gameinfo->computer_player = WHITE;
	  if (gameinfo->computer_player == gameinfo->to_move)
	    state = computer_move(gameinfo, &passes);
	  break;

	case SWITCH:
	  gameinfo->computer_player = OTHER_COLOR(gameinfo->computer_player);
	  state = computer_move(gameinfo, &passes);
	  break;

	case UNDO:
	case CMD_BACK:
	  if (undo_move(1)) {
            sgftreeAddComment(&sgftree, "undone");
	    sgftreeBack(&sgftree);
	    gameinfo->to_move = OTHER_COLOR(gameinfo->to_move);
	  }
	  else
	    printf("\nCan't undo.\n");
	  break;

	case CMD_FORWARD:
         if (sgftreeForward(&sgftree))
           gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode,
						  gameinfo->to_move);
	  else
	    printf("\nEnd of game tree.\n");
	  break;

	case CMD_LAST:
         while (sgftreeForward(&sgftree))
           gameinfo->to_move = gnugo_play_sgfnode(sgftree.lastnode,
						  gameinfo->to_move);
	  break;

	case COMMENT:
	  printf("\nEnter comment. Press ENTER when ready.\n");
	  fgets(line, 80, stdin);
	  sgftreeAddComment(&sgftree, line);
	  break;

	case SCORE:
	  showscore = !showscore;
	  if (!showscore)
	    current_score_estimate = NO_SCORE;
	  break;

	case CMD_DEAD:
	  silent_examine_position(FULL_EXAMINE_DRAGONS);
	  showdead = !showdead;
	  break;

	case CMD_CAPTURE:
	  strtok(command, " ");
	  showcapture(strtok(NULL, " "));
	  break;

	case CMD_DEFEND:
	  strtok(command, " ");
	  showdefense(strtok(NULL, " "));
	  break;

	case CMD_SHOWMOYO:
	  tmp = printmoyo;
	  printmoyo = PRINTMOYO_MOYO;
	  silent_examine_position(EXAMINE_DRAGONS);
	  printmoyo = tmp;
	  break;

	case CMD_SHOWTERRI:
	  tmp = printmoyo;
	  printmoyo = PRINTMOYO_TERRITORY;
	  silent_examine_position(EXAMINE_DRAGONS);
	  printmoyo = tmp;
	  break;

	case CMD_SHOWAREA:
	  tmp = printmoyo;
	  printmoyo = PRINTMOYO_AREA;
	  silent_examine_position(EXAMINE_DRAGONS);
	  printmoyo = tmp;
	  break;

	case CMD_SHOWDRAGONS:
	  silent_examine_position(EXAMINE_DRAGONS);
	  showboard(1);
	  break;

	case CMD_GOTO:
	  strtok(command, " ");
	  ascii_goto(gameinfo, strtok(NULL, " "));
	  break;

	case CMD_SAVE:
	  strtok(command, " ");
	  tmpstring = strtok(NULL, " ");
	  if (tmpstring) {
	    /* discard newline */
	    tmpstring[strlen(tmpstring) - 1] = 0;
	    /* make sure we are saving proper handicap */
	    init_sgf(gameinfo);
	    writesgf(sgftree.root, tmpstring);
	    printf("You may resume the game");
	    printf(" with -l %s --mode ascii\n", tmpstring);
	    printf("or load %s\n", tmpstring);
	  }
	  else
	    printf("Please specify filename\n");
	  break;

	case CMD_LOAD:
	  strtok(command, " ");
	  tmpstring = strtok(NULL, " ");
	  if (tmpstring) {
	    /* discard newline */
	    tmpstring[strlen(tmpstring) - 1] = 0;
	    if (!sgftree_readfile(&sgftree, tmpstring)) {
	      fprintf(stderr, "Cannot open or parse '%s'\n", tmpstring);
	      break;
	    }
            /* to avoid changing handicap etc. */
	    if (gameinfo_play_sgftree(gameinfo, &sgftree, NULL) == EMPTY)
	      fprintf(stderr, "Cannot load '%s'\n", tmpstring);
	    else {
	      sgf_initialized = 1;
	      sgfOverwritePropertyInt(sgftree.root, "HA", gameinfo->handicap);
	    }
	  }
	  else
	    printf("Please specify a filename\n");
	  break;

	case CMD_LISTDRAGONS:
	  silent_examine_position(EXAMINE_DRAGONS);
	  show_dragons();
	  break;

	default:
	  printf("\nInvalid command: %s", command);
	  break;
	}

	if (passes >= 2)
	  state = ascii_endgame(gameinfo, 0);
      }
#if READLINE
      free(line_ptr);
#endif
    }

    sgffile_output(&sgftree);
    passes = 0;
    
    /* Play a different game next time. */
    update_random_seed();

    /* Free the sgf tree and prepare for a new game. */
    sgfFreeNode(sgftree.root);
    sgftree_clear(&sgftree);
    sgftreeCreateHeaderNode(&sgftree, board_size, komi, gameinfo->handicap);
    sgf_initialized = 0;

    gameinfo_clear(gameinfo);
  }
}