Esempio n. 1
0
			const string Guard::display() const {
				if (oneline.empty()) {
					string guards;
					if (_condition != nullptr) {
						guards += '[';
						guards += _condition->display();
						guards += ']';
					}
					guards.resize(max(guards.size(), (size_t)40), ' ');
					oneline += guards;

					string end = "nil";
					if (endstate())
						end = endstate()->name();
					end.resize(max(end.size(), (size_t)10), ' ');

					oneline += end;

					string actions;
					actions += '{';
					for (auto action : _actions) {
						actions += action->display();
					}
					actions += '}';

					oneline += actions;
				}
				return oneline;
			}
Esempio n. 2
0
vector<int> DParray::sample_path() const {
    vector<int> path;

    const int I = size()-1;
    int i = I;

    int state2 = endstate();

    vector<double> transition(nstates());

    while(i >= 0) {
        path.push_back(state2);
        for(int state1=0; state1<nstates(); state1++)
            transition[state1] = (*this)(i,state1)*GQ(state1,state2);

        int state1 = choose_scratch(transition);

        if (di(state1)) i--;

        state2 = state1;
    }
    assert(i+di(state2)==0);

    std::reverse(path.begin(),path.end());

#ifndef NDEBUG_DP
    check_sampling_probability(path);
#endif

    return path;
}
Esempio n. 3
0
void endstate(solution *sol, state *s, node_value parent_v, int turn, int low_player) {
    if (s->passes == 2 || target_dead(s)) {
        if (turn) {
            stones_t temp = s->player;
            s->player = s->opponent;
            s->opponent = temp;
        }
        return;
    }
    state child_;
    state *child = &child_;
    for (int j = 0; j < sol->si->num_moves; j++) {
        *child = *s;
        stones_t move = sol->si->moves[j];
        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);
            node_value child_v_p = add_prisoners(sol, child_v, prisoners);
            int is_best_child = (-child_v_p.high == parent_v.low && child_v_p.high_distance + 1 == parent_v.low_distance);
            is_best_child = low_player ? is_best_child : (-child_v_p.low == parent_v.high && child_v_p.low_distance + 1 == parent_v.high_distance);
            if (is_best_child) {
                *s = *child;
                endstate(sol, s, child_v, !turn, !low_player);
                return;
            }
        }
    }
}
Esempio n. 4
0
efloat_t DParray::Pr_sum_all_paths() const {
    const int I = size()-1;

    double total = 0.0;
    for(int state1=0; state1<nstates(); state1++)
        total += (*this)(I,state1) * GQ(state1,endstate());

    return pow<efloat_t>(2.0,scale(I)) * total;
}
Esempio n. 5
0
void endstate(
        dict *d, lin_dict *ko_ld,
        node_value *base_nodes, node_value *pass_nodes, node_value *ko_nodes,
        state *s, node_value parent_v, int turn, int low_player
    ) {
    if (s->passes == 2) {
        if (turn) {
            stones_t temp = s->player;
            s->player = s->opponent;
            s->opponent = temp;
        }
        return;
    }
    state child_;
    state *child = &child_;
    for (int j = -1; j < STATE_SIZE; j++) {
        *child = *s;
        stones_t move;
        if (j == -1){
            move = 0;
        }
        else {
            move = 1UL << j;
        }
        node_value child_v;
        if (make_move(child, move)) {
            canonize(child);
            size_t child_key = to_key(child);
            if (child->passes == 2){
                value_t score = liberty_score(child);
                child_v = (node_value) {score, score, 0, 0};
            }
            else if (child->passes == 1) {
                child_v = pass_nodes[key_index(d, child_key)];
            }
            else if (child->ko) {
                child_key = child_key * STATE_SIZE + bitscan(child->ko);
                child_v = ko_nodes[lin_key_index(ko_ld, child_key)];
            }
            else {
                child_v = base_nodes[key_index(d, child_key)];
            }
            int is_best_child = (-child_v.high == parent_v.low && child_v.high_distance + 1 == parent_v.low_distance);
            is_best_child = low_player ? is_best_child : (-child_v.low == parent_v.high && child_v.low_distance + 1 == parent_v.high_distance);
            if (is_best_child) {
                *s = *child;
                endstate(
                    d, ko_ld,
                    base_nodes, pass_nodes, ko_nodes,
                    s, child_v, !turn, !low_player
                );
            }
        }
    }
}
Esempio n. 6
0
efloat_t DParrayConstrained::Pr_sum_all_paths() const
{
    const int I = size()-1;

    double total = 0.0;
    for(int s1=0; s1<states(I).size(); s1++) {
        int state1 = states(I)[s1];
        total += (*this)(I,state1) * GQ(state1,endstate());
    }

    return pow<efloat_t>(2.0,scale(I)) * total;
}
Esempio n. 7
0
File: match.c Progetto: elly/1k
/* Matches the supplied string against the supplied pattern. Returns 0 for match
 * failure, 1 for match success, and -1 for out of memory. */
int match(const char *pat, const char *str) {
	struct states ss = { 0, NULL };
	int i;
	if (startstates(&ss, (char *)pat))
		return -1;
	while (*str) {
		if (step(&ss, *(str++)))
			return -1;
		if (!ss.n)
			return 0;
	}
	for (i = 0; i < ss.n; i++) {
		if (endstate(ss.p[i]))
			break;
	}
	free(ss.p);
	return i != ss.n;
}
Esempio n. 8
0
int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s width height\n", argv[0]);
        return 0;
    }
    int width = atoi(argv[1]);
    int height = atoi(argv[2]);
    if (width <= 0) {
        printf("Width must be larger than 0.\n");
        return 0;
    }
    if (width >= 7) {
        printf("Width must be less than 7.\n");
        return 0;
    }
    if (height <= 0) {
        printf("Height must be larger than 0.\n");
        return 0;
    }
    if (height >= 6) {
        printf("Height must be less than 6.\n");
        return 0;
    }

    state s_ = (state) {rectangle(width, height), 0, 0, 0, 0};
    state *s = &s_;

    dict d_;
    dict *d = &d_;

    size_t max_k = max_key(s);
    init_dict(d, max_k);

    size_t key_min = ~0;
    size_t key_max = 0;

    size_t total_legal = 0;
    for (size_t k = 0; k < max_k; k++) {
        if (!from_key(s, k)){
            continue;
        }
        total_legal++;
        canonize(s);
        size_t key = to_key(s);
        add_key(d, key);
        if (key < key_min) {
            key_min = key;
        }
        if (key > key_max) {
            key_max = key;
        }
    }
    resize_dict(d, key_max);
    finalize_dict(d);
    size_t num_states = num_keys(d);

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

    node_value *base_nodes = (node_value*) malloc(num_states * sizeof(node_value));
    node_value *pass_nodes = (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_;

    state child_;
    state *child = &child_;
    size_t child_key;
    size_t key = key_min;
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key(s, key));
        value_t score = liberty_score(s);
        leaf_nodes[i] = score;
        pass_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        base_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        for (int j = 0; j < STATE_SIZE; j++) {
            *child = *s;
            if (make_move(child, 1UL << j)) {
                if (child->ko) {
                    canonize(child);
                    child_key = to_key(child) * STATE_SIZE + bitscan(child->ko);
                    add_lin_key(ko_ld, child_key);
                }
            }
        }
        key = next_key(d, key);
    }

    finalize_lin_dict(ko_ld);

    node_value *ko_nodes = (node_value*) malloc(ko_ld->num_keys * sizeof(node_value));
    printf("Unique positions with ko %zu\n", ko_ld->num_keys);

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

    #ifndef PRELOAD
    printf("Negamax with Chinese rules.\n");
    iterate(
        d, ko_ld,
        base_nodes, pass_nodes, ko_nodes, leaf_nodes,
        s, key_min, 0
    );
    #endif

    char dir_name[16];
    sprintf(dir_name, "%dx%d", width, height);
    struct stat sb;
    if (stat(dir_name, &sb) == -1) {
        mkdir(dir_name, 0700);
    }
    assert(chdir(dir_name) == 0);
    FILE *f;

    #ifndef PRELOAD
    f = fopen("d_slots.dat", "wb");
    fwrite((void*) d->slots, sizeof(slot_t), d->num_slots, f);
    fclose(f);
    f = fopen("d_checkpoints.dat", "wb");
    fwrite((void*) d->checkpoints, sizeof(size_t), (d->num_slots >> 4) + 1, f);
    fclose(f);
    f = fopen("ko_ld_keys.dat", "wb");
    fwrite((void*) ko_ld->keys, sizeof(size_t), ko_ld->num_keys, f);
    fclose(f);

    f = fopen("base_nodes.dat", "wb");
    fwrite((void*) base_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("pass_nodes.dat", "wb");
    fwrite((void*) pass_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("leaf_nodes.dat", "wb");
    fwrite((void*) leaf_nodes, sizeof(value_t), num_states, f);
    fclose(f);
    f = fopen("ko_nodes.dat", "wb");
    fwrite((void*) ko_nodes, sizeof(node_value), ko_ld->num_keys, f);
    fclose(f);
    #endif

    #ifdef PRELOAD
    f = fopen("base_nodes.dat", "rb");
    fread((void*) base_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("pass_nodes.dat", "rb");
    fread((void*) pass_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("leaf_nodes.dat", "rb");
    fread((void*) leaf_nodes, sizeof(value_t), num_states, f);
    fclose(f);
    f = fopen("ko_nodes.dat", "rb");
    fread((void*) ko_nodes, sizeof(node_value), ko_ld->num_keys, f);
    fclose(f);
    #endif

    // Japanese leaf state calculation.
    state new_s_;
    state *new_s = &new_s_;
    key = key_min;
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key(s, key));
        stones_t empty = s->playing_area & ~(s->player | s->opponent);

        *new_s = *s;
        endstate(
            d, ko_ld,
            base_nodes, pass_nodes, ko_nodes,
            new_s, base_nodes[i], 0, 1
        );

        stones_t player_controlled = new_s->player | liberties(new_s->player, new_s->playing_area & ~new_s->opponent);
        stones_t opponent_controlled = new_s->opponent | liberties(new_s->opponent, new_s->playing_area & ~new_s->player);
        value_t score = popcount(player_controlled & empty) - popcount(opponent_controlled & empty);
        score += 2 * (popcount(player_controlled & s->opponent) - popcount(opponent_controlled & s->player));
        leaf_nodes[i] = score;

        *new_s = *s;
        endstate(
            d, ko_ld,
            base_nodes, pass_nodes, ko_nodes,
            new_s, base_nodes[i], 0, 0
        );

        player_controlled = new_s->player | liberties(new_s->player, new_s->playing_area & ~new_s->opponent);
        opponent_controlled = new_s->opponent | liberties(new_s->opponent, new_s->playing_area & ~new_s->player);
        score = popcount(player_controlled & empty) - popcount(opponent_controlled & empty);
        score += 2 * (popcount(player_controlled & s->opponent) - popcount(opponent_controlled & s->player));
        leaf_nodes[i] += score;

        key = next_key(d, key);
    }

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

    printf("Negamax with Japanese rules.\n");
    iterate(
        d, ko_ld,
        base_nodes, pass_nodes, ko_nodes, leaf_nodes,
        s, key_min, 1
    );

    f = fopen("base_nodes_j.dat", "wb");
    fwrite((void*) base_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("pass_nodes_j.dat", "wb");
    fwrite((void*) pass_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("leaf_nodes_j.dat", "wb");
    fwrite((void*) leaf_nodes, sizeof(value_t), num_states, f);
    fclose(f);
    f = fopen("ko_nodes_j.dat", "wb");
    fwrite((void*) ko_nodes, sizeof(node_value), ko_ld->num_keys, f);
    fclose(f);

    return 0;
}
Esempio n. 9
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);
}
Esempio n. 10
0
// Japanese leaf state calculation from capture data.
// We could store territory for the UI, it takes too much space.
void calculate_leaves(solution *sol) {
    state s_;
    state *s = &s_;
    size_t key;
    size_t zero_layer = abs(sol->base_state->ko_threats);
    state new_s_;
    state *new_s = &new_s_;
    key = sol->d->min_key;
    size_t num_states = num_keys(sol->d);
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key_s(sol, s, key, zero_layer));

        *new_s = *s;
        node_value v = negamax_node(sol, s, key, zero_layer, 0);
        node_value v_b = sol->base_nodes[zero_layer][i];
        assert(equal(v, v_b));
        endstate(sol, new_s, v, 0, 1);

        // 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);

        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) {
            // Make sure that both aren't dead.
            assert(!(player_target & ~player_alive));
            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);
        }

        sol->leaf_nodes[i] = score;

        key = next_key(sol->d, key);
    }
}