/** * Computes the next level from src according to the strategy in result. */ static inline void compute_strategy_level(vset_t strategy_level, const int* src, const int player, const recursive_result* strategy) { // Initialise strategy level to the empty set vset_clear(strategy_level); // Find the right strategy level. For each level that contains src, there is either a transition // to the same level, or (preferrably) to a lower level. for (int i=0; i < strategy->strategy_boundary_count[player]; i++) { int begin = (i==0) ? 0 : strategy->strategy_boundaries[player][i-1]; int end = strategy->strategy_boundaries[player][i]; //printf("considering segment %d (begin=%d, end=%d).\n", i, begin, end); //assert(first <= last); assert(strategy->strategy_boundaries[player][i]<=strategy->strategy_levels_count[player]); bool src_found = false; for (int j = begin; j < end && !src_found; j++) { if (vset_member(strategy->strategy_levels[player][j], src)) { if (j==begin) { vset_union(strategy_level, strategy->strategy_levels[player][j]); //printf("choosing move from segment %d, moving from level %d to level %d.\n", i, j, j); } else { vset_union(strategy_level, strategy->strategy_levels[player][j-1]); //printf("choosing move from segment %d, moving from level %d to level %d.\n", i, j, j-1); } assert(!vset_is_empty(strategy_level)); src_found = true; } } } // strategy_level now contains any target states that can be reached from src // in one step and are conform the strategy. }
static void vector_next(void*arg,int*lbl,int*dst){ int *src_ofs_p=(int*)arg; if (!vset_member(visited_set,dst)) { visited++; vset_add(visited_set,dst); vset_add(next_set,dst); } if (write_lts) enum_seg_vec(output_handle,0,*src_ofs_p,dst,lbl); trans++; }
int get_priority(const parity_game* g, const int* s) { int priority = -1; bool found = false; for (priority=g->min_priority; priority <= g->max_priority; priority++) { if (vset_member(g->v_priority[priority], s)) { found = true; break; } } assert(found); (void) found; return priority; }
int choose_strategy_move(const parity_game* g, const recursive_result* strategy, const int player, const int* src, int* current_player, bool* strategy_play, bool* result, bool* deadlock, int* dst) { int group = -1; vset_t level = vset_create(g->domain, -1, NULL); vset_t tmp = vset_create(g->domain, -1, NULL); vset_t singleton = vset_create(g->domain, -1, NULL); vset_add(singleton, src); // Do a random run through the game, conforming to // the strategy in result. *current_player = (vset_member(g->v_player[player], src) ? player : 1-player); Print(hre_debug, "Using strategy of player %d. The position is owned by player %d.", player, *current_player); if (*current_player==player && vset_member(strategy->win[player], src)) { //printf("Player %d chooses according to his/her winning strategy.\n", player); // Choose a transition according to the strategy of player *strategy_play = true; vset_t strategy_level = vset_create(g->domain, -1, NULL); compute_strategy_level(strategy_level, src, player, strategy); vset_clear(level); for (int i=0; i < g->num_groups; i++) { vset_next(tmp, singleton, g->e[i]); vset_intersect(tmp, strategy_level); if (!vset_is_empty(tmp)) { vset_copy(level, tmp); // Choose a random element: //printf("Choosing a transition from transition group %d.\n", i); group = i; vset_random(level, dst); break; } } // Check for deadlocks if (vset_is_empty(level)) { *deadlock = true; *result = (*current_player != player); Print(infoLong, "Deadlock for player %d, player %s has won, result is %s.", *current_player, (*current_player==1) ? "0 (even / or)" : "1 (odd / and)", *result ? "true" : "false"); } } else { //Print(info, "Not player %d's turn or player %d has no winning strategy. Choosing an arbitrary move for player %d.", // player, player, *current_player); // this states belongs to (1-player) or player does not have a winning strategy *strategy_play = false; vset_t strategy_level = vset_create(g->domain, -1, NULL); /* if (vset_member(result.win[current_player], src)) { // winning move after all compute_strategy_level(strategy_level, src, current_player, result); if (vset_is_empty(strategy_level)) { Print(info, "Unexpected: src is in win[%d], but strategy_level is empty.", current_player); } else { strategy_play = true; } } */ // choose a random move vset_clear(level); for (int i=0; i < g->num_groups; i++) { vset_next(tmp, singleton, g->e[i]); if (*strategy_play && !vset_is_empty(tmp)) { vset_intersect(tmp, strategy_level); if (!vset_is_empty(tmp)) { vset_copy(level, tmp); // Choose a random element: //printf("Choosing a transition from transition group %d.\n", i); group = i; vset_random(level, dst); break; } } else { vset_union(level, tmp); } } // Check for deadlocks if (vset_is_empty(level)) { *deadlock = true; *result = (*current_player != player); Print(infoLong, "Deadlock for player %d, player %s has won, result is %s.", *current_player, (*current_player==1) ? "0 (even / or)" : "1 (odd / and)", *result ? "true" : "false"); } else if (!*strategy_play) { //Print(info, "choose randomly"); vset_random(level, dst); } } return group; }