static void control_spi_listener_build_actions_list (ControlSpiListener *listener, Accessible *parent, int depth) { Accessible* child; AccessibleRole role; int i, child_count; if (depth > SEARCH_DEPTH) return; child_count = Accessible_getChildCount (parent); child_count = MIN (child_count, SEARCH_BREADTH); for (i = 0; i < child_count; ++i) { char *name; char *normalized_name; child = Accessible_getChildAtIndex (parent, i); if (child == parent) continue; name = Accessible_getName (child); #if DEBUG { gchar *role_name; role_name = Accessible_getRoleName (child); g_message ("Looking at %s %s", role_name, name); } #endif if (name) { normalized_name = control_spi_listener_normalize (name); if (normalized_name && strlen(normalized_name) > 0 && is_actionable (child)) { AccessibleItem *item; item = g_new0(AccessibleItem, 1); Accessible_ref (child); item->accessible = child; item->name = g_strdup (normalized_name); listener->actions = g_slist_append (listener->actions, item); } SPI_freeString (name); g_free (normalized_name); } if (is_worth_searching (child)) control_spi_listener_build_actions_list (listener, child, depth+1); Accessible_unref (child); } }
bool ai_move(Player *player, Board *board, enum State *state, Players *players, PairStack *fields_adjacent_enemies, PairStack *fields_adjacent_neutrals) { PairStack *actionable_neutral_fields = create_pair_stack(); PairStack *actionable_enemy_fields = create_pair_stack(); Field *field; for (int x = 0; x < board->width; x++) { for (int y = 0; y < board->height; y++) { if (is_actionable(board, x, y, player, *state)) { if (board->fields[x][y].owner == 0) { push(actionable_neutral_fields, create_pair(x, y)); } else if (board->fields[x][y].owner != player->id) { push(actionable_enemy_fields, create_pair(x, y)); } } } } if ((rand() / (double) RAND_MAX) < 0.75 || actionable_enemy_fields->size == 0) { if (actionable_enemy_fields->size > 0 && ((rand() / (double) RAND_MAX) < 0.35 || actionable_neutral_fields->size == 0)) { Triple actionable_enemy_fields_tab[actionable_enemy_fields->size]; int index = 0; PairItem *pair_item = actionable_enemy_fields->top; while (pair_item != NULL) { actionable_enemy_fields_tab[index] = create_triple(pair_item->pair.x, pair_item->pair.y, board->fields[pair_item->pair.x][pair_item->pair.y].force); pair_item = pair_item->prev; index++; } qsort(actionable_enemy_fields_tab, (size_t) actionable_enemy_fields->size, sizeof(Triple), actionable_enemy_fields_cmp); if ((rand() / (double) RAND_MAX) < 0.5) { field = pair_to_field(create_pair(actionable_enemy_fields_tab[0].x, actionable_enemy_fields_tab[0].y), board); } else { index = rand() % actionable_enemy_fields->size; field = pair_to_field( create_pair(actionable_enemy_fields_tab[index].x, actionable_enemy_fields_tab[index].y), board); } } else if (actionable_neutral_fields->size > 0) { field = random_field(actionable_neutral_fields, board); } else { field = random_field(player->fields_stack, board); } player_move(player, field, board, state, players); } else { if (fields_adjacent_enemies->size > 0) { field = random_field(fields_adjacent_enemies, board); } else if (fields_adjacent_neutrals->size > 0) { field = random_field(fields_adjacent_neutrals, board); } else { field = random_field(player->fields_stack, board); } player_move(player, field, board, state, players); } delete_pair_stack(actionable_enemy_fields); delete_pair_stack(actionable_neutral_fields); return true; }