Beispiel #1
0
void repair(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Please enter a filename.\n");
        return;
    }
    char capture_filename[128];
    char japanese_filename[128];
    char temp_filename[128];
    sprintf(capture_filename, "%s_capture.dat", argv[1]);
    sprintf(japanese_filename, "%s_japanese.dat", argv[1]);
    sprintf(temp_filename, "%s_temp.dat", argv[1]);


    solution sol_;
    solution *sol = &sol_;
    char *buffer = file_to_buffer(capture_filename);
    buffer = load_solution(sol, buffer, 1);
    print_state(sol->base_state);
    calculate_leaves(sol);

    solution solj_;
    solution *solj = &solj_;
    buffer = file_to_buffer(japanese_filename);
    buffer = load_solution(solj, buffer, 1);
    print_state(solj->base_state);
    solj->leaf_nodes = sol->leaf_nodes;

    FILE *f = fopen(temp_filename, "wb");
    save_solution(solj, f);
    fclose(f);
    printf("Done!\n");
}
Beispiel #2
0
INT isomorph::find_extension_search_interval(INT *set, 
	INT first, INT len, INT &idx, 
	INT f_btree_idx, INT btree_idx, 
	INT f_through_hash, INT verbose_level)
{
	INT *data = find_extension_set1;
	INT i, id;
	
	for (i = 0; i < len; i++) {
		if (f_btree_idx) {
			load_solution_by_btree(btree_idx, first + i, id, data);
			}
		else {
			if (f_through_hash) {
				id = hash_vs_id_id[first + i];
				}
			else {
				id = first + i;
				}
			load_solution(id, data);
			}
		INT_vec_heapsort(data + level, size - level);
		if (INT_vec_compare(set + level, data + level, size - level) == 0) {
			break;
			}
		}
	if (i == len) {
		return FALSE;
		//cout << "isomorph::find_extension_search_interval did not find extension" << endl;
		//exit(1);
		}
	idx = id;
	return TRUE;
}
Beispiel #3
0
void upgrade(int argc, char *argv[]) {
    parse_args(argc - 1, argv + 1);

    solution sol_;
    solution *sol = &sol_;
    char *buffer = file_to_buffer(tsumego_name);  // Not really a tsumego name. Needs extension too.
    buffer = load_solution(sol, buffer, 1);

    if (sol->si->color_symmetry) {
        num_layers = 2 * abs(ko_threats) + 1;
    }
    else if (num_layers <= 0) {
        num_layers = abs(ko_threats) + 1;
    }

    sol->base_nodes = (node_value**) realloc(sol->base_nodes, sol->num_layers * sizeof(node_value*));
    sol->ko_nodes = (node_value**) realloc(sol->ko_nodes, sol->num_layers * sizeof(node_value*));

    size_t zero_layer = abs(sol->base_state->ko_threats);
    size_t new_zero_layer = abs(ko_threats);

    sol->base_nodes[new_zero_layer] = sol->base_nodes[zero_layer];
    sol->ko_nodes[new_zero_layer] = sol->ko_nodes[zero_layer];

    sol->base_state->ko_threats = ko_threats;
    sol->num_layers = num_layers;

    size_t num_states = num_keys(sol->d);
    for (size_t k = 0; k < sol->num_layers; k++) {
        if (k == new_zero_layer) {
            continue;
        }
        sol->base_nodes[k] = (node_value*) malloc(num_states * sizeof(node_value));
        for (size_t i = 0; i < num_states; i++) {
            (sol->base_nodes[k])[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
    }

    for (size_t k = 0; k < sol->num_layers; k++) {
        if (k == new_zero_layer) {
            continue;
        }
        sol->ko_nodes[k] = (node_value*) malloc(sol->ko_ld->num_keys * sizeof(node_value));
        for (size_t i = 0; i < sol->ko_ld->num_keys; i++) {
            sol->ko_nodes[k][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
    }

    FILE *f = fopen(tsumego_name, "wb");
    save_solution(sol, f);
    fclose(f);
    printf("Done!\n");
}
Beispiel #4
0
idxint ECOS_BB_solve(ecos_bb_pwork* prob) {
    idxint curr_node_idx = 0;

#if MI_PRINTLEVEL > 0
    if (prob->stgs->verbose){
        PRINTTEXT("Iter\tLower Bound\tUpper Bound\tGap\n");
        PRINTTEXT("================================================\n");
    }
#endif

    /* Initialize to root node and execute steps 1 on slide 6 */
    /* of http://stanford.edu/class/ee364b/lectures/bb_slides.pdf*/
    prob->iter = 0;
    initialize_root(prob);
    /*print_node(prob, curr_node_idx);*/
    get_bounds(curr_node_idx, prob);

    prob->global_L = prob->nodes[curr_node_idx].L;
    prob->global_U = prob->nodes[curr_node_idx].U;

    while ( should_continue(prob, curr_node_idx) ){

#if MI_PRINTLEVEL > 0
        if (prob->stgs->verbose){ print_progress(prob); }
#endif

        ++(prob->iter);

        /* Step 2*/
        /* Branch replaces nodes[curr_node_idx] with leftNode*/
        /* and nodes[prob->iter] with rightNode */
        branch(curr_node_idx, prob);

        /* Step 3*/
        get_bounds(curr_node_idx, prob);
        get_bounds(prob->iter, prob);

        /* Step 4*/
        prob->global_L = get_global_L(prob);

        curr_node_idx = get_next_node(prob);
    }
    load_solution(prob);

#if MI_PRINTLEVEL > 0
    if (prob->stgs->verbose){ print_progress(prob); }
#endif

    return get_ret_code(prob);
}
Beispiel #5
0
solution* mmap_solution(char *filename) {
    solution *sol = (solution*) malloc(sizeof(solution));
    char *buffer = file_to_mmap(filename);
    buffer = load_solution(sol, buffer, 1);
    return sol;
}
Beispiel #6
0
void test() {
    solution sol_;
    solution *sol = &sol_;
    char *buffer = file_to_buffer("cho589_capture.dat");
    buffer = load_solution(sol, buffer, 1);
    state s_;
    state *s = &s_;
    // sscanf_state("4337799298623 4335912108032 1879319553 0 1879048192 4335912108032 0 0 0", s);
    sscanf_state("4337799298623 4335918405632 1879319581 0 1879048192 4335912108032 0 0 0", s);
    print_state(s);
    size_t layer;
    size_t key = to_key_s(sol, s, &layer);
    // node_value v = negamax_node(sol, s, key, layer, 0);
    // print_node(v);
    // node_value v_b = sol->base_nodes[layer][key_index(sol->d, key)];
    // print_node(v_b);
    // endstate(sol, s, v, 0, 1);
    // print_state(s);

    state new_s_;
    state *new_s = &new_s_;
    *new_s = *s;
    node_value v = negamax_node(sol, s, key, 0, 0);
    endstate(sol, new_s, v, 0, 1);

    print_state(new_s);

    // Use a flood of life so that partially dead nakade won't give extra points.
    // Note while this won't mark dead groups as alive, it can treat living nakade stones as dead.
    stones_t player_alive = flood(new_s->player, s->player);
    stones_t opponent_alive = flood(new_s->opponent, s->opponent);

    print_stones(player_alive);
    print_stones(opponent_alive);

    int score;

    // First check if a target is not alive.
    stones_t player_target = s->player & s->target;
    stones_t opponent_target = s->opponent & s->target;
    if (opponent_target & ~opponent_alive) {
        assert(!(player_target & ~player_alive));  // Both shouldn't be dead.
        score = TARGET_SCORE;
    }
    else if (player_target & ~player_alive) {
        score = -TARGET_SCORE;
    }
    else {
        stones_t player_territory = 0;
        stones_t opponent_territory = 0;
        stones_t player_region_space = s->playing_area & ~player_alive;
        stones_t opponent_region_space = s->playing_area & ~opponent_alive;
        for (int j = 0; j < STATE_SIZE; j++) {
            stones_t p = 1ULL << j;
            stones_t region = flood(p, player_region_space);
            player_region_space ^= region;
            if (!(region & opponent_alive)) {
                player_territory |= region;
            }
            region = flood(p, opponent_region_space);
            opponent_region_space ^= region;
            if (!(region & player_alive)) {
                opponent_territory |= region;
            }
        }
        // Subtract friendly stones on the board from territory.
        player_territory &= ~s->player;
        opponent_territory &= ~s->opponent;
        score = popcount(player_territory) + popcount(player_territory & s->opponent) - popcount(opponent_territory) - popcount(opponent_territory & s->player);
    }
    printf("%d\n", score);
}
Beispiel #7
0
int main(int argc, char *argv[]) {
    #ifdef TEST
        test();
        return 0;
    #endif
    #ifdef REPAIR
        repair(argc, argv);
        return 0;
    #endif
    #ifdef UPGRADE
        upgrade(argc, argv);
        return 0;
    #endif

    int load_sol = 0;
    int resume_sol = 0;
    if (strcmp(argv[argc - 1], "load") == 0) {
        load_sol = 1;
        argc--;
    }
    if (strcmp(argv[argc - 1], "resume") == 0) {
        resume_sol = 1;
        argc--;
    }
    parse_args(argc - 1, argv + 1);

    int width = board_width;
    int height = board_height;
    if (board_width >= 10) {
        fprintf(stderr, "Width must be less than 10.\n");
        exit(EXIT_FAILURE);
    }
    if (board_height >= 8) {
        fprintf(stderr, "Height must be less than 8.\n");
        exit(EXIT_FAILURE);
    }

    #include "tsumego.c"

    state base_state_;
    state *base_state = &base_state_;

    char sol_name[64] = "unknown";
    char temp_filename[128];
    char filename[128];
    if (board_width > 0) {
        *base_state = (state) {rectangle(width, height), 0, 0, 0, 0};
        sprintf(sol_name, "%dx%d", width, height);
    }
    else {
        int i;
        int found = 0;

        for (i = 0; tsumego_infos[i].name; ++i) {
            if (!strcmp(tsumego_name, tsumego_infos[i].name)) {
                *base_state = *(tsumego_infos[i].state);
                strcpy(sol_name, tsumego_name);
                found = 1;
                break;
            }
        }
        if (!found) {
            fprintf(stderr, "unknown tsumego: `%s'\n", tsumego_name);
            exit(EXIT_FAILURE);
        }
    }
    base_state->ko_threats = ko_threats;

    sprintf(temp_filename, "%s_temp.dat", sol_name);


    state_info si_;
    state_info *si = &si_;
    init_state(base_state, si);

    if (si->color_symmetry) {
        num_layers = 2 * abs(base_state->ko_threats) + 1;
    }
    else if (num_layers <= 0) {
        num_layers = abs(base_state->ko_threats) + 1;
    }
    else {
        assert(num_layers >= abs(base_state->ko_threats) + 1);
    }

    print_state(base_state);
    for (int i = 0; i < si->num_external; i++) {
        print_stones(si->externals[i]);
    }
    printf(
        "width=%d height=%d c=%d v=%d h=%d d=%d\n",
        si->width,
        si->height,
        si->color_symmetry,
        si->mirror_v_symmetry,
        si->mirror_h_symmetry,
        si->mirror_d_symmetry
    );

    state s_;
    state *s = &s_;

    dict d_;
    dict *d = &d_;

    solution sol_;
    solution *sol = &sol_;
    sol->base_state = base_state;
    sol->si = si;
    sol->d = d;
    sol->num_layers = num_layers;
    size_t num_states;

    // Re-used at frontend. TODO: Allocate a different pointer.
    state child_;
    state *child = &child_;

    if (load_sol) {
        goto frontend;
    }

    if (resume_sol) {
        char *buffer = file_to_buffer(temp_filename);
        buffer = load_solution(sol, buffer, 1);
        num_states = num_keys(sol->d);
        if (sol->leaf_rule == japanese_double_liberty) {
            goto iterate_capture;
        }
        else {
            goto iterate_japanese;
        }
    }

    size_t k_size = key_size(sol->si);
    if (!sol->si->color_symmetry) {
        k_size *= 2;
    }
    init_dict(sol->d, k_size);

    size_t total_legal = 0;
    for (size_t k = 0; k < k_size; k++) {
        if (!from_key_s(sol, s, k, 0)){
            continue;
        }
        total_legal++;
        size_t layer;
        size_t key = to_key_s(sol, s, &layer);
        assert(layer == 0);
        add_key(sol->d, key);
    }
    finalize_dict(sol->d);
    num_states = num_keys(sol->d);

    printf("Total positions %zu\n", total_legal);
    printf("Total unique positions %zu\n", num_states);

    node_value **base_nodes = (node_value**) malloc(sol->num_layers * sizeof(node_value*));
    for (size_t i = 0; i < sol->num_layers; i++) {
        base_nodes[i] = (node_value*) malloc(num_states * sizeof(node_value));
    }
    value_t *leaf_nodes = (value_t*) malloc(num_states * sizeof(value_t));

    lin_dict ko_ld_ = (lin_dict) {0, 0, 0, NULL};
    lin_dict *ko_ld = &ko_ld_;

    sol->base_nodes = base_nodes;
    sol->leaf_nodes = leaf_nodes;
    sol->ko_ld = ko_ld;

    size_t child_key;
    size_t key = sol->d->min_key;
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key_s(sol, s, key, 0));
        // size_t layer;
        // assert(to_key_s(sol, s, &layer) == key);
        sol->leaf_nodes[i] = 0;
        for (size_t k = 0; k < sol->num_layers; k++) {
            (sol->base_nodes[k])[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
        for (int j = 0; j < STATE_SIZE; j++) {
            *child = *s;
            int prisoners;
            if (make_move(child, 1ULL << j, &prisoners)) {
                if (target_dead(child)) {
                    continue;
                }
                if (child->ko) {
                    size_t child_layer;
                    child_key = to_key_s(sol, child, &child_layer);
                    add_lin_key(sol->ko_ld, child_key);
                }
            }
        }
        key = next_key(sol->d, key);
    }

    finalize_lin_dict(sol->ko_ld);

    node_value **ko_nodes = (node_value**) malloc(sol->num_layers * sizeof(node_value*));
    sol->ko_nodes = ko_nodes;
    for (size_t i = 0; i < sol->num_layers; i++) {
        sol->ko_nodes[i] = (node_value*) malloc(sol->ko_ld->num_keys * sizeof(node_value));
    }
    printf("Unique positions with ko %zu\n", sol->ko_ld->num_keys);

    for (size_t i = 0; i < sol->ko_ld->num_keys; i++) {
        for (size_t k = 0; k < sol->num_layers; k++) {
            sol->ko_nodes[k][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
    }

    #ifdef CHINESE
    printf("Negamax with Chinese rules.\n");
    sol->count_prisoners = 0;
    sol->leaf_rule = chinese_liberty;
    iterate(sol, temp_filename);
    #endif

    // NOTE: Capture rules may refuse to kill stones when the needed nakade sacrifices exceed triple the number of stones killed.
    printf("Negamax with capture rules.\n");
    sol->count_prisoners = 1;
    sol->leaf_rule = japanese_double_liberty;
    iterate_capture:
    iterate(sol, temp_filename);

    sprintf(filename, "%s_capture.dat", sol_name);
    FILE *f = fopen(filename, "wb");
    save_solution(sol, f);
    fclose(f);


    calculate_leaves(sol);

    // Clear the rest of the tree.
    for (size_t j = 0; j < sol->num_layers; j++) {
        for (size_t i = 0; i < num_states; i++) {
            sol->base_nodes[j][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
        for (size_t i = 0; i < sol->ko_ld->num_keys; i++) {
            sol->ko_nodes[j][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
    }

    printf("Negamax with Japanese rules.\n");
    sol->count_prisoners = 1;
    sol->leaf_rule = precalculated;
    iterate_japanese:
    iterate(sol, temp_filename);

    sprintf(filename, "%s_japanese.dat", sol_name);
    f = fopen(filename, "wb");
    save_solution(sol, f);
    fclose(f);

    frontend:
    if (load_sol) {
        sprintf(filename, "%s_japanese.dat", sol_name);
        char *buffer = file_to_buffer(filename);
        buffer = load_solution(sol, buffer, 1);
    }

    *s = *sol->base_state;

    char coord1;
    int coord2;

    int total_prisoners = 0;
    int turn = 0;

    while (1) {
        size_t layer;
        size_t key = to_key_s(sol, s, &layer);
        node_value v = negamax_node(sol, s, key, layer, 0);
        print_state(s);
        if (turn) {
            print_node((node_value) {total_prisoners - v.high, total_prisoners - v.low, v.high_distance, v.low_distance});
        }
        else {
            print_node((node_value) {total_prisoners + v.low, total_prisoners + v.high, v.low_distance, v.high_distance});
        }
        if (target_dead(s) || s->passes >= 2) {
            break;
        }
        for (int j = -1; j < STATE_SIZE; j++) {
            *child = *s;
            stones_t move;
            if (j == -1){
                move = 0;
            }
            else {
                move = 1ULL << j;
            }
            char c1 = 'A' + (j % WIDTH);
            char c2 = '0' + (j / WIDTH);
            int prisoners;
            if (make_move(child, move, &prisoners)) {
                size_t child_layer;
                size_t child_key = to_key_s(sol, child, &child_layer);
                node_value child_v = negamax_node(sol, child, child_key, child_layer, 0);
                if (sol->count_prisoners) {
                    if (child_v.low > VALUE_MIN && child_v.low < VALUE_MAX) {
                        child_v.low = child_v.low - prisoners;
                    }
                    if (child_v.high > VALUE_MIN && child_v.high < VALUE_MAX) {
                        child_v.high = child_v.high - prisoners;
                    }
                }
                if (move) {
                    printf("%c%c", c1, c2);
                }
                else {
                    printf("pass");
                }
                if (-child_v.high == v.low) {
                    printf("-");
                    if (child_v.high_distance + 1 == v.low_distance) {
                        printf("L");
                    }
                    else {
                        printf("l");
                    }
                }
                if (-child_v.high == v.low) {
                    printf("-");
                    if (child_v.low_distance + 1 == v.high_distance) {
                        printf("H");
                    }
                    else {
                        printf("h");
                    }
                }
                printf(" ");
            }
        }
        printf("\n");
        printf("Enter coordinates:\n");
        assert(scanf("%c %d", &coord1, &coord2));
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
        coord1 = tolower(coord1) - 'a';
        stones_t move;
        if (coord1 < 0 || coord1 >= WIDTH) {
            // printf("%d, %d\n", coord1, coord2);
            move = 0;
        }
        else {
            move = 1ULL << (coord1 + V_SHIFT * coord2);
        }
        int prisoners;
        if (make_move(s, move, &prisoners)) {
            if (turn) {
                total_prisoners -= prisoners;
            }
            else {
                total_prisoners += prisoners;
            }
            turn = !turn;
        }
    }

    return 0;
}