void add_to_type_tree( FactList *t_list, type_tree tree ) { type_tree branch = tree; type_tree_list new_branch; char *this_type; char *super_type; /* step through list and build a hierarchy of types */ for( ; t_list; t_list=t_list->next ) { this_type = t_list->item->item; if ( !t_list->item->next ) { fprintf(stderr, "\n%s: error at '%s'.\n", gact_filename, this_type ); exit( 1 ); } super_type = t_list->item->next->item; if ( strcmp( branch->name, super_type ) != SAME ) { branch = find_branch( super_type, tree ); } if ( !branch ) { fprintf(stderr, "\n%s: unknown type '%s'.\n", gact_filename, super_type ); exit( 1 ); } /* now the type is a subtype of the one currently looked at * in the type tree */ new_branch = new_type_tree_list( this_type ); new_branch->next = branch->sub_types; branch->sub_types = new_branch; } }
/* steps recursively through type tree and searches for name */ type_tree find_branch( char *name, type_tree root ) { type_tree p; type_tree_list ttl; if ( !root ) { return NULL; } if ( strcmp( root->name, name ) == SAME ) { return root; } if ( !root->sub_types ) { return NULL; } for ( ttl=root->sub_types; ttl; ttl=ttl->next ) { if ((p = find_branch( name, ttl->item ))) { return p; } } return NULL; }
vector<HMM::bitmask_t> get_bitpath(const data_partition& P, const vector<int>& nodes) { auto t = P.t(); int b1 = t.find_branch(nodes[1],nodes[0]); int b2 = t.find_branch(nodes[0],nodes[2]); int b3 = t.find_branch(nodes[0],nodes[3]); vector<HMM::bitmask_t> a1 = convert_to_bits(P.get_pairwise_alignment(b1),0,3); vector<HMM::bitmask_t> a2 = convert_to_bits(P.get_pairwise_alignment(b2),3,1); vector<HMM::bitmask_t> a3 = convert_to_bits(P.get_pairwise_alignment(b3),3,2); vector<HMM::bitmask_t> a123 = Glue_A(a1, Glue_A(a2, a3)); return a123; }
/** routetbl_where: * finds the link where the specified net could be routed to * returns: * qnet * of the link, or * NULL if the route couldn't be found */ qnet * routetbl_where(const net_id * p_nid) { struct rtbl_entry * re; /** check if it's any of our neighbours */ foreach_re(re) { if(eq_net_id(p_nid, &re->conn->id)) break; } if(re) { /** yes, its neigbour.. */ return re->conn; } /** no, this must be net more than 1 hops from us... */ re = find_branch(p_nid, NULL); if(!re) { /** route search failed */ /* log_a("routetbl_where: no route found for net \""); log_a(net_id_dump(p_nid)); log("\""); */ return NULL; } return re->conn; }
/** routetbl_add_branch: * adds route branch to specified qnet connection */ void routetbl_add_branch( qnet * net, const net_id * nid ) { struct rtbl_entry * re = find_entry(net); assert(re); debug_a("routetbl_add_branch: route to "); debug_a(net_id_dump(nid)); debug_a(" [through "); debug_a(net_id_dump(&net->id)); debug("]"); /** check that it is'nt already on the list */ if(find_branch(nid, NULL)) { log_a("routetbl_add_branch: the net \""); log_a(net_id_dump(nid)); log("\" already in route table: ignored"); return; } /** ok, not found: insert it */ insert_branch(re, nid); /* broadcast new net */ broadcast_route_change(nid, 1); }
void _take_stairs(stairs_t* stairs) { dungeon_t* prev_dungeon = current_dungeon; TRACE("take_stairs: stairs->to_branch=%s", stairs->to_branch.c_str()); // Arrive from town to infinite dungeon: clear infinite dungeon. if (stairs->to && stairs->to_branch == BRANCH_INFINITE_DUNGEON && current_branch->name != BRANCH_INFINITE_DUNGEON) { stairs->to = nullptr; branch_t* inf_branch = find_branch(stairs->to_branch); for (dungeon_t* dungeon : inf_branch->dungeons) { destroy_dungeon(dungeon); } inf_branch->dungeons.clear(); } // Generate the next dungeon if needed. if (stairs->to == nullptr && stairs->to_branch == current_branch->name) { dungeon_t* next_level = generate_next_level(current_branch); create_up_stairs(next_level, current_branch, prev_dungeon, stairs); } else if (stairs->to == nullptr) { // Stairs to a new branch. branch_t* prev_branch = current_branch; current_branch = create_branch(stairs->to_branch); dungeon_t* next_level = current_branch->dungeons.front(); // Check if the level has stairs that lead back to the branch already. bool has_stairs = false; for (int i = 0; i < next_level->num_stairs; i++) { if (next_level->stairs[i]->to_branch == prev_branch->name) has_stairs = true; } if (!has_stairs) create_up_stairs(next_level, prev_branch, prev_dungeon, stairs); else stairs->to = next_level; } dungeon_t* dst = stairs->to; current_dungeon = dst; current_branch = find_branch(stairs->to_branch); player.pos.x = stairs->warp_x; player.pos.y = stairs->warp_y; // Do not follow player to the world map. if (current_branch->name != "World") { std::vector<coord_t> free_coords; for (int y = player.pos.y - 1; y <= player.pos.y + 1; y++) for (int x = player.pos.x - 1; x <= player.pos.x + 1; x++) if (place_free(current_dungeon, x, y)) free_coords.push_back( coord_t { x, y} ); std::vector<creature_t*> following_creatures; for (int y = stairs->y - 1; y <= stairs->y + 1; y++) { for (int x = stairs->x - 1; x <= stairs->x + 1; x++) { creature_t* creature = get_creature_at(prev_dungeon, x, y); if (creature && following_creatures.size() < free_coords.size()) { following_creatures.push_back(creature); remove_creature_no_destroy(prev_dungeon, creature); } } } for (size_t i = 0; i < following_creatures.size(); i++) { add_creature_to_dungeon(current_dungeon, following_creatures[i], free_coords[i].x, free_coords[i].y); } if (following_creatures.size() == 1) append_msg_log("%s follows you.", capitalize(following_creatures.front()->get_full_name()).c_str()); else if (following_creatures.size() > 1) append_msg_log("Some creatures follow you."); } clear_action_list(); append_action_list(&player); }
FullTree* qsearch_make_fulltree(QSearchTree *clt, const gsl_matrix *dm) { int i,j; int node_count = clt->total_node_count; int leaf_count = (node_count + 2)/2; FullTree *tree = malloc(sizeof(FullTree)); tree->node_count = node_count; tree->data = malloc(sizeof(Misc)); ((Misc *)tree->data)->nodes = malloc(sizeof(FullNode) * node_count); ((Misc *)tree->data)->tmpA = g_array_sized_new(FALSE, FALSE, sizeof(guint32), node_count); ((Misc *)tree->data)->tmpB = g_array_sized_new(FALSE, FALSE, sizeof(guint32), node_count); FullNode *map = get_nodes(tree); GArray *todo = g_array_sized_new(FALSE, FALSE, sizeof(guint32), node_count - leaf_count); g_array_set_size(todo, node_count-leaf_count); for (i = 0; i < node_count; ++i) { FullNode *node = (map + i); for (j = 0; j < 3; ++j) { map[i].connections[j] = -1; map[i].leaf_count[j] = 0; map[i].dist[j] = 0; } guint8 *node_branch = malloc(sizeof(guint8) * node_count); node->node_branch = node_branch; if (i < leaf_count) { for (j=0; j < node_count; ++j) node_branch[j] = 0; node->leaf_count[0] = leaf_count - 1; } else { for (j = 0; j < node_count; ++j) node_branch[j] = -1; g_array_index(todo, guint32, i - leaf_count) = i; } } // set connections (construct tree) for (i = 0; i < node_count; ++i) { QSearchNeighborList *cln = g_ptr_array_index(clt->n, i); // add to connected nodes for (j = 0; j < cln->n->len; ++j) { int node = g_array_index(cln->n, guint32, j); // find unfilled branch int branch = find_branch(map[node].connections, -1); map[node].connections[branch] = i; // set connection if (i < leaf_count) { map[node].leaf_count[branch] = 1; // set leaf } map[node].node_branch[i] = branch; // leaf can be found in branch // set connection back to this node branch = find_branch(map[i].connections, -1); map[i].connections[branch] = node; map[i].node_branch[node] = branch; } } // every iteration, this loop progresses by at least finishing one node. Worst case is n^3 (for 'linear' trees) while (todo->len > 0) { for (i = 0; i < todo->len; ++i) { int this_node = g_array_index(todo, guint32, i); for (j = 0; j < 3; ++j) { int connected_node = map[this_node].connections[j]; int branch = find_branch(map[connected_node].connections, this_node); if (map[connected_node].leaf_count[branch] == 0) { int first = (3 + j-1) % 3; int second = (j + 1) % 3; if (map[this_node].leaf_count[first] != 0 && map[this_node].leaf_count[second] != 0) { map[connected_node].leaf_count[branch] = map[this_node].leaf_count[first] + map[this_node].leaf_count[second]; // set the node_branch information int k; for (k = 0; k < node_count; ++k) { // node present in one of the two branches pointing away from this int node_present = k==this_node || map[this_node].node_branch[k] == first || map[this_node].node_branch[k] == second; if (node_present) map[connected_node].node_branch[k] = branch; } } } } } for (i = 0; i < todo->len; ++i) { int this_node = g_array_index(todo, guint32, i); // we are done when all entries are set for this node, AND there are no pending assignments to neighbours // are all entries set for this node? for (j = 0; j < 3; ++j) { if (map[this_node].leaf_count[j] == 0) { break; } } // are there pending assignments? (we could do the assignments here, but that would duplicate code) int done = 1; for (j = 0; j < 3; ++j) { if (this_node < leaf_count) continue; int connected_node = map[this_node].connections[j]; // find connection int branch = find_branch(map[connected_node].connections, this_node); if (map[connected_node].leaf_count[branch] == 0) { done = 0; break; } } if (done) { //printf("Removing node %d, counts %d %d %d\n", i, map[this_node].leaf_count[0], map[this_node].leaf_count[1], map[this_node].leaf_count[2]); g_array_remove_index_fast(todo, i); --i; } } } g_array_free(todo, TRUE); int k; // now fill in the distances for (i=leaf_count; i < node_count; ++i) { for (j = 0; j < leaf_count; ++j) { for (k = j+1; k < leaf_count; ++k) { int b1 = map[i].node_branch[j]; int b2 = map[i].node_branch[k]; if (b1 == b2) continue; int b3 = 3 - b1 - b2; map[i].dist[b3] += gsl_matrix_get(dm, j, k); } } } set_score(tree); return tree; }