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);
    }
}
Beispiel #2
0
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;
}