int generate_minerals(t_server *s) { t_counters count; count.i = -1; count.save_j = 0; s->minerals_consumed = 0; while (++count.i < NUM_MIN) { count.save_i = s->max_num_minerals - s->current_num_minerals[count.i]; if (count.save_i > 0) { count.save_j = 1; count.j = -1; while (++count.j < count.save_i) { if (add_stone(count.i, s) == -1) return (-1); s->current_num_minerals[count.i]++; } } } if (count.save_j != 0) update_map(s); return (0); }
int func_deraumere(t_gen **map, t_player *player, int i) { if (i == 1) { if (player->inventory->nb_deraumere == 0) return (-1); if (add_stone(map, player->pos->x, player->pos->y, DERAUMERE) == -1) return (-1); --player->inventory->nb_deraumere; return (1); } if (delete_stone(map, player->pos->x, player->pos->y, DERAUMERE) == -1) return (-1); ++player->inventory->nb_deraumere; return (1); }
int func_linemate(t_gen **map, t_player *player, int i) { if (i == 1) { if (player->inventory->nb_linemate == 0) return (-1); if (add_stone(map, player->pos->x, player->pos->y, LINEMATE) == -1) return (-1); --player->inventory->nb_linemate; return (1); } if (delete_stone(map, player->pos->x, player->pos->y, LINEMATE) == -1) return (-1); ++player->inventory->nb_linemate; return (1); }
int place_fixed_handicap(int desired_handicap) { int r; int max_handicap; int remaining_stones; int three = board_size > 11 ? 3 : 2; int mid = board_size/2; /* A handicap of 1 just means that B plays first, no komi. * Black is not told where to play the first stone so no handicap * is set. */ if (desired_handicap < 2) { handicap = 0; return 0; } if ((board_size % 2 == 1) && (board_size >= 9)) max_handicap = 9; else if (board_size >= 7) max_handicap = 4; else max_handicap = 0; /* It's up to the caller of this function to notice if the handicap * was too large for fixed placement and act upon that. */ if (desired_handicap > max_handicap) handicap = max_handicap; else handicap = desired_handicap; remaining_stones = handicap; /* special cases: 5 and 7 */ if (desired_handicap == 5 || desired_handicap == 7) { add_stone(POS(mid, mid), BLACK); remaining_stones--; } for (r = 0; r < remaining_stones; r++) { int i = places[r][0]; int j = places[r][1]; /* Translate the encoded values to board co-ordinates. */ if (i == 2) i = three; /* 2 or 3 */ else if (i == 0) i = mid; else if (i == -2) i = board_size - 1 - three; if (j == 2) j = three; else if (j == 0) j = mid; else if (j == -2) j = board_size - 1 - three; add_stone(POS(i, j), BLACK); } return handicap; }
static int find_free_handicap_pattern() { int k; int highest_value = -1; int sum_values = 0; int r; int anchor; struct pattern *pattern; int ll; int move; number_of_matches = 0; matchpat(free_handicap_callback, BLACK, &handipat_db, NULL, NULL); if (number_of_matches == 0) return 0; /* Find the highest value among the matched patterns. */ for (k = 0; k < number_of_matches; k++) if (highest_value < handicap_matches[k].value) highest_value = handicap_matches[k].value; /* Replace the values by 2^(value - highest_value + 10) and compute * the sum of these values. Fractional values are discarded. */ for (k = 0; k < number_of_matches; k++) { if (handicap_matches[k].value < highest_value - 10) handicap_matches[k].value = 0; else handicap_matches[k].value = 1 << (handicap_matches[k].value - highest_value + 10); sum_values += handicap_matches[k].value; } /* Pick a random number between 0 and sum_values. Don't bother with * the fact that lower numbers will tend to be very slightly * overrepresented. */ r = gg_rand() % sum_values; /* Find the chosen pattern. */ for (k = 0; k < number_of_matches; k++) { r -= handicap_matches[k].value; if (r < 0) break; } /* Place handicap stones according to pattern k. */ anchor = handicap_matches[k].anchor; pattern = handicap_matches[k].pattern; ll = handicap_matches[k].ll; /* Pick up the location of the move */ move = AFFINE_TRANSFORM(pattern->move_offset, ll, anchor); add_stone(move, BLACK); remaining_handicap_stones--; /* Add stones at all '!' in the pattern. */ for (k = 0; k < pattern->patlen; k++) { if (pattern->patn[k].att == ATT_not) { int pos = AFFINE_TRANSFORM(pattern->patn[k].offset, ll, anchor); add_stone(pos, BLACK); remaining_handicap_stones--; } } return 1; }
/* * Sets up free placement handicap stones, returning the number of * placed handicap stones and also setting the global variable * handicap to the same value. */ int place_free_handicap(int desired_handicap) { gg_assert(desired_handicap == 0 || desired_handicap >= 2); if (desired_handicap == 0) { handicap = 0; return 0; } total_handicap_stones = desired_handicap; remaining_handicap_stones = desired_handicap; /* First place black stones in the four corners to enable the * pattern matching scheme. */ add_stone(POS(0, 0), BLACK); add_stone(POS(0, board_size - 1), BLACK); add_stone(POS(board_size - 1, 0), BLACK); add_stone(POS(board_size - 1, board_size - 1), BLACK); /* Find and place free handicap stones by pattern matching. */ while (remaining_handicap_stones > 0) { if (!find_free_handicap_pattern()) break; } /* Remove the artificial corner stones. */ remove_stone(POS(0, 0)); remove_stone(POS(0, board_size - 1)); remove_stone(POS(board_size - 1, 0)); remove_stone(POS(board_size - 1, board_size - 1)); /* Find and place additional free handicap stones by the aftermath * algorithm. */ while (remaining_handicap_stones > 0) { int move; /* Call genmove_conservative() in order to prepare the engine for * an aftermath_genmove() call. We discard the genmove result. */ genmove_conservative(BLACK, NULL); move = aftermath_genmove(BLACK, 0, NULL); if (move != PASS_MOVE) { add_stone(move, BLACK); remaining_handicap_stones--; } else break; } /* Set handicap to the number of actually placed stones. */ handicap = desired_handicap - remaining_handicap_stones; /* Reset these to invalid values, so that improper use of handicap * helper functions can be detected. */ total_handicap_stones = -1; remaining_handicap_stones = -1; return handicap; }
static void replay_node(SGFNode *node, int color_to_replay, float *replay_score, float *total_score) { SGFProperty *sgf_prop; /* iterate over properties of the node */ SGFProperty *move_prop = NULL; /* remember if we see a move property */ int color; /* color of move to be made at this node. */ int old_move; /* The move played in the file. */ int new_move; /* The move generated by GNU Go. */ char buf[BUFSIZE]; /* Handle any AB / AW properties, and note presence * of move properties. */ for (sgf_prop = node->props; sgf_prop; sgf_prop = sgf_prop->next) { switch (sgf_prop->name) { case SGFAB: /* add black */ add_stone(get_sgfmove(sgf_prop), BLACK); break; case SGFAW: /* add white */ add_stone(get_sgfmove(sgf_prop), WHITE); break; case SGFB: case SGFW: move_prop = sgf_prop; /* remember it for later */ break; } } /* Only generate moves at move nodes. */ if (!move_prop) return; old_move = get_sgfmove(move_prop); color = (move_prop->name == SGFW) ? WHITE : BLACK; if (color == color_to_replay || color_to_replay == GRAY) { float new_move_value = 0.0; float old_move_value = 0.0; /* Get a move from the engine for color. */ int resign; new_move = genmove(color, NULL, &resign); /* Pick up the relevant values from the potential_moves[] array. */ if (new_move != PASS_MOVE) new_move_value = potential_moves[new_move]; if (old_move != PASS_MOVE) old_move_value = potential_moves[old_move]; /* Now report on how well the computer generated the move. */ if (new_move != old_move || !quiet) { mprintf("Move %d (%C): ", movenum + 1, color); if (resign) printf("GNU Go resigns "); else { mprintf("GNU Go plays %1m ", new_move); if (new_move != PASS_MOVE) printf("(%.2f) ", new_move_value); } mprintf("- Game move %1m ", old_move); if (new_move != PASS_MOVE && old_move_value > 0.0) printf("(%.2f) ", old_move_value); printf("\n"); *replay_score += new_move_value - old_move_value; *total_score += new_move_value; } if (new_move != old_move) { if (resign) gg_snprintf(buf, BUFSIZE, "GNU Go resigns - Game move %s (%.2f)", location_to_string(old_move), old_move_value); else { gg_snprintf(buf, BUFSIZE, "GNU Go plays %s (%.2f) - Game move %s (%.2f)", location_to_string(new_move), new_move_value, location_to_string(old_move), old_move_value); if (new_move != PASS_MOVE) sgfCircle(node, I(new_move), J(new_move)); } } else gg_snprintf(buf, BUFSIZE, "GNU Go plays the same move %s (%.2f)", location_to_string(new_move), new_move_value); sgfAddComment(node, buf); sgffile_add_debuginfo(node, 0.0); } /* Finally, do play the move from the file. */ play_move(old_move, color); }
static void ascii_free_handicap(Gameinfo *gameinfo, char *handicap_string) { int handi; int i; char line[80]; int stones[MAX_BOARD*MAX_BOARD]; if (sscanf(handicap_string, "%d", &handi) == 1) { /* GNU Go is to place handicap */ if (handi < 0 || handi == 1) { printf("\nInvalid command syntax!\n"); return; } clear_board(); handi = place_free_handicap(handi); printf("\nPlaced %d stones of free handicap.\n", handi); } else { /* User is to place handicap */ clear_board(); handi = 0; while (1) { ascii_showboard(); printf("\nType in coordinates of next handicap stone, or one of the following commands:\n"); printf(" undo take back the last stone placed\n"); printf(" clear remove all the stones placed so far\n"); printf(" done finish placing handicap\n\n"); printf("You have placed %d handicap stone(s) so far.\n\n", handi); if (!fgets(line, 80, stdin)) return; /* EOF or some error */ for (i = 0; i < 80; i++) line[i] = tolower((int) line[i]); if (!strncmp(line, "undo", 4)) { if (!handi) printf("\nNothing to undo.\n"); else { remove_stone(stones[--handi]); gprintf("\nRemoved the stone at %m.\n", I(stones[handi]), J(stones[handi])); } } else if (!strncmp(line, "clear", 5)) { clear_board(); handi = 0; } else if (!strncmp(line, "done", 4)) { if (handi == 1) /* Don't bother with checks later */ printf("\nHandicap cannot be one stone. Either add " "some more, or delete the only stone.\n"); else break; } else { int pos = string_to_location(board_size, line); if (pos != NO_MOVE) { if (board[pos] != EMPTY) printf("\nThere's already a stone there.\n"); else { add_stone(pos, BLACK); stones[handi++] = pos; } } else printf("\nInvalid command: %s", line); } } } gameinfo->handicap = handi; gameinfo->to_move = (handi ? WHITE : BLACK); }