/* Create a new gtp command for all slaves. The slave lock is held * upon entry and upon return, so the command will actually be * sent when the lock is released. The last command is overwritten * if gtp_cmd points to a non-empty string. cmd is a single word; * args has all arguments and is empty or has a trailing \n */ void update_cmd(struct board *b, char *cmd, char *args, bool new_id) { assert(gtp_cmd); /* To make sure the slaves are in sync, we ignore the original id * and use the board number plus some random bits as gtp id. */ static int gtp_id = -1; int moves = is_reset(cmd) ? 0 : b->moves; if (new_id) { int prev_id = gtp_id; do { /* fast_random() is 16-bit only so the multiplication can't overflow. */ gtp_id = force_reply(moves + fast_random(65535) * DIST_GAMELEN); } while (gtp_id == prev_id); reply_count = 0; } snprintf(gtp_cmd, gtp_cmds + CMDS_SIZE - gtp_cmd, "%d %s %s", gtp_id, cmd, *args ? args : "\n"); cmd_count++; /* Remember history for out-of-sync slaves. */ static int slot = 0; static struct cmd_history *last = NULL; if (new_id) { if (last) last->next_cmd = gtp_cmd; slot = (slot + 1) % MAX_CMDS_PER_MOVE; last = &history[moves][slot]; last->gtp_id = gtp_id; last->next_cmd = NULL; } // Notify the slave threads about the new command. pthread_cond_broadcast(&cmd_cond); }
int dfs( int depth, int max_depth, int move,/* order does not matter. */ char* clocks, char* moves, char* num_moves_done ) { if (depth == max_depth) { return is_reset(clocks); } for (; move < NUM_CLOCKS; move++) { if (num_moves_done[move] == 3) { continue; } dial(clocks, move, 0); moves[depth] = move; num_moves_done[move]++; if (dfs(depth + 1, max_depth, move, clocks, moves, num_moves_done)) { return 1; } num_moves_done[move]--; dial(clocks, move, 1); } return 0; }