tuple_list * label(Graph * graph, int trace_position, int max_used_color, int * trace, int current_vertex) { int i; int * colors = (int *) malloc(sizeof(int) * max_used_color); tuple_list * candidates = NULL; // Inicialización de estructura de control de los // colores que se encuentran mientras se desdeciende // en el arbol para hacer labeling for(i = 0; i < max_used_color; i++) colors[i] = 0; i = 0; // Se comienza a etiquetar los vértices // Nótese que el etiquetado se hace comenzando desde // la raíz, en vez de partir desde el vértice hasta // la raíz. for(i = 0; i < trace_position; i++) { if (is_adjacent(&trace[i], current_vertex, graph)) { int color_candidate = graph[trace[i]].color; if (colors[color_candidate] == 0) { colors[color_candidate] = 1; tuple_list * tmp = (tuple_list *) malloc(sizeof(tuple_list)); tmp->vertex = trace[i]; tmp->position = i; tmp->next = candidates; candidates = tmp; } } } free(colors); return candidates; }
Board adj_friendly(const GameState& gs, const uint8_t for_color) { Board res; const Board& color_board = gs.get_color_board(for_color); for(unsigned int direction = NORTH; direction < num_directions(); ++direction) res |= is_adjacent(color_board, color_board, direction); return res; }
void generate_pushes(const GameState& gs, std::vector<Delta> *pushes) { const uint8_t pushing_color = gs.get_color(); const uint8_t pushed_color = other_color(gs.get_color()); const Board& pushing_mobile = ~frozen_pieces(gs, gs.get_color()); Board pushed_with_adj_empty[4]; // The body of generate_pushes() takes the perspective of the pushed piece. // dir_pushed_from is the direction from which the pushing piece comes from. // dir_pushed is the direction the pushed piece is pushed to. for (unsigned int dir = NORTH; dir < num_directions(); ++dir) { pushed_with_adj_empty[dir] = adj_empty(gs, pushed_color, dir); } for (unsigned int dir_pushed_from = NORTH; dir_pushed_from < num_directions(); ++dir_pushed_from) { // the mobile pushing pieces with an adjacent weaker piece. // We use the opp_dir(dir_pushed_from) here since we are talking about the pushing piece. const Board& pushing_pieces_with_adj_lt = adj_enemy_lt(gs, pushing_color, opp_dir(dir_pushed_from)) & pushing_mobile; for (unsigned int dir_pushed = NORTH; dir_pushed < num_directions(); ++dir_pushed) { if (dir_pushed_from == dir_pushed) continue; // TODO: Try and make symmetric with generate_pulls() -- simplify inner loop here... Board pushing_pieces = is_adjacent(pushing_pieces_with_adj_lt, pushed_with_adj_empty[dir_pushed], opp_dir(dir_pushed_from)); Board pushed_pieces = is_adjacent(pushed_with_adj_empty[dir_pushed], pushing_pieces_with_adj_lt, dir_pushed_from); while(!pushed_pieces.is_empty()) { assert(!pushing_pieces.is_empty()); uint8_t pushed_idx = pushed_pieces.idx_and_reset(); uint8_t pusher_idx = pushing_pieces.idx_and_reset(); assert(gs.get_all_const().contains(pushed_idx)); assert(gs.get_all_const().contains(pusher_idx)); pushes->push_back(Delta(step_from_gs(gs, pushed_idx, dir_pushed), step_from_gs(gs, pusher_idx, opp_dir(dir_pushed_from)))); } } } }
Board adj_empty(const GameState& gs, const uint8_t for_color) { Board adj_mt; const Board& color_board = gs.get_color_board(for_color); const Board empties = ~gs.get_all_const(); for(unsigned int direction = NORTH; direction < num_directions(); ++direction) adj_mt |= is_adjacent(color_board, empties, direction); return adj_mt; }
Board adj_enemy_gt(const GameState& gs, const uint8_t for_color, const unsigned int direction) { Board adj_gt, enemy_gt, these_pieces; const Board& color_board = gs.get_color_board(for_color); const Board& enemy_color = gs.get_color_board(other_color(for_color)); for(int p = E; p >= R; --p) { these_pieces = gs.get_piece_board(p) & color_board; adj_gt |= is_adjacent(these_pieces, enemy_gt, direction); enemy_gt |= gs.get_piece_board(p) & enemy_color; } return adj_gt; }
Board adj_enemy_le(const GameState& gs, const uint8_t for_color, const unsigned int direction) { Board adj_le, enemy_le, these_pieces; const Board& color_board = gs.get_color_board(for_color); const Board& enemy_color = gs.get_color_board(other_color(for_color)); for(int p = R; p < nPieces; ++p) { enemy_le |= gs.get_piece_board(p) & enemy_color; these_pieces = gs.get_piece_board(p) & color_board; adj_le |= is_adjacent(these_pieces, enemy_le, direction); } return adj_le; }
inline void apply(Piece const& piece1, Piece const& piece2, bool first = true) { boost::ignore_unused_variable_warning(first); if ( is_adjacent(piece1, piece2) || detail::disjoint::disjoint_box_box(piece1.robust_envelope, piece2.robust_envelope)) { return; } calculate_turns(piece1, piece2); }
Creature *melee_actor::find_target( monster &z ) const { if( !z.can_act() ) { return nullptr; } Creature *target = z.attack_target(); if( target == nullptr || !is_adjacent( z, *target ) ) { return nullptr; } return target; }
AIMoves *enum_adjacent(const Board *b, int dist) { AIMoves *moves; AIMove move; move.weight = AIW_NONE; moves = aimoves_new(); for (move.y = 0; move.y < board_size; move.y++) for (move.x = 0; move.x < board_size; move.x++) if (is_adjacent(b, move.x, move.y, dist)) aimoves_append(moves, &move); aimoves_shuffle(moves); return moves; }
Board adj_step(const GameState& gs, const uint8_t for_color, const unsigned int direction) { const Board& color_board = gs.get_color_board(for_color); const Board empties = ~gs.get_all_const(); const Board adj = is_adjacent(color_board, empties, direction); if (direction == SOUTH && for_color == W) { Board rabbit_mask = gs.get_piece_board(R) & color_board; return adj & ~rabbit_mask; } else if (direction == NORTH && for_color == B) { Board rabbit_mask = gs.get_piece_board(R) & color_board; return adj & ~rabbit_mask; } else { return adj; } }
void algorithms::KDDecomposer<IROBOT>::build_edges(bool clear_nodes) { all_boundaries.clear(); std::vector<CONFIG> all_corners; std::vector<const CONFIG*> corner_configs; all_corners.reserve(1000000); corner_configs.reserve(200000); get_unique_crn_cfgs(corner_configs, all_corners); std::clock_t t0 = std::clock(); all_boundaries.reserve(300000); // Build all boundaries std::vector<int> containing_cells; for (const CONFIG* cfg : corner_configs) { containing_cells.clear(); ContainedCells(cfg->vector(), containing_cells); if(containing_cells.size() == 0) continue; for (int i = 0; i < containing_cells.size() - 1; ++i) { for (int j = i + 1; j < containing_cells.size(); ++j) { if (is_adjacent(containing_cells[i], containing_cells[j])) continue; int fix_dim = compute_fix_dim(containing_cells[i], containing_cells[j]); // If the fixed dimension is not one, then it is degenerate case if (fix_dim == -1) continue; int boundary_index = get_new_boundary(containing_cells[i], containing_cells[j]); cells[containing_cells[i]].add_boundary(boundary_index); cells[containing_cells[j]].add_boundary(boundary_index); double weight = IROBOT::heuristic(robot_, CONFIG(cells[containing_cells[i]].center()), CONFIG(cells[containing_cells[j]].center())); all_boundaries[boundary_index].set_weight(weight); all_boundaries[boundary_index].set_fix_dim(fix_dim); } } } for (int i = 0; i < all_boundaries.size(); ++i) { compute_bound(i); } std::clock_t t2 = std::clock(); all_boundaries.shrink_to_fit(); if(clear_nodes) nodes.clear(); nodes.shrink_to_fit(); for (Cell<IROBOT>& cell : cells) cell.shrink_to_fit(); std::clock_t t3 = std::clock(); }
int move_matches_diff_inner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; p1=piece_new(move->square_index1,move->rotation1); p2=piece_new(move->square_index2,move->rotation2); //rotation of the same piece //p1==p2 if it is the same piece if (move->pos1==move->pos2) { tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) + solution_piece_matches_inner(s, p1, move->pos1); } else { //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) - solution_piece_matches_inner(s,NULL,move->pos2); //new pieces matches are added tot+=solution_piece_matches_inner(s, p1, move->pos1) + solution_piece_matches_inner(s,p2, move->pos2); d=is_adjacent(move->pos2,move->pos1,s->n); //swap_pos->other_pos //adjacent swap if (d!=NONE) { p1_old=s->mat[(move->pos2)/(s->n)][(move->pos2)%(s->n)]; p2_old=s->mat[(move->pos1)/(s->n)][(move->pos1)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } } piece_free(p1); piece_free(p2); return(tot); }
inline void apply(Section const& section1, Section const& section2, bool first = true) { geofeatures_boost::ignore_unused_variable_warning(first); typedef typename geofeatures_boost::range_value<Pieces const>::type piece_type; piece_type const& piece1 = m_pieces[section1.ring_id.source_index]; piece_type const& piece2 = m_pieces[section2.ring_id.source_index]; if ( piece1.index == piece2.index || is_adjacent(piece1, piece2) || is_on_same_convex_ring(piece1, piece2) || detail::disjoint::disjoint_box_box(section1.bounding_box, section2.bounding_box) ) { return; } calculate_turns(piece1, piece2, section1, section2); }
int move_matches_diff_inner(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; p1=s->mat[1][1]; p2=piece_new(move->square_index,move->rotation); //rotation of the first piece if (s->n+1==move->pos) { tot=s->matches - solution_piece_matches_inner(s,NULL,s->n+1) + solution_piece_matches_inner(s, p2, s->n+1); } else { //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos) - solution_piece_matches_inner(s,NULL,s->n+1); //new pieces matches are added tot+=solution_piece_matches_inner(s, p2, s->n+1) + solution_piece_matches_inner(s,p1, move->pos); d=is_adjacent(s->n+1,move->pos,s->n); //adjacent swap if (d!=NONE) { p1_old=p1; p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } } //piece_free(p1); //placeholder for enhanced versions piece_free(p2); return(tot); }
static void make_adjacent( Segmenter *s, Region* r1, Region* r2 ) { if( !is_adjacent( r1, r2 ) ){ if( r1->flags & SATURATED_REGION_FLAG ){ r2->flags |= FRAGMENTED_REGION_FLAG; }else if( r2->flags & SATURATED_REGION_FLAG ){ r1->flags |= FRAGMENTED_REGION_FLAG; }else{ if( r1->adjacent_region_count == s->max_adjacent_regions ){ make_saturated(r1); r2->flags |= FRAGMENTED_REGION_FLAG; if( r2->adjacent_region_count == s->max_adjacent_regions ){ make_saturated(r2); r1->flags |= FRAGMENTED_REGION_FLAG; } }else if( r2->adjacent_region_count == s->max_adjacent_regions ){ make_saturated(r2); r1->flags |= FRAGMENTED_REGION_FLAG; }else{ assert( !(r1->flags & SATURATED_REGION_FLAG) ); assert( !(r2->flags & SATURATED_REGION_FLAG) ); assert( r1->adjacent_region_count < s->max_adjacent_regions ); assert( r2->adjacent_region_count < s->max_adjacent_regions ); r1->adjacent_regions[ r1->adjacent_region_count++ ] = r2; r2->adjacent_regions[ r2->adjacent_region_count++ ] = r1; } } } // postcondition, adjacency link is bi-directional or isn't created assert( (r1_adjacent_contains_r2( r1, r2 ) && r1_adjacent_contains_r2( r2, r1 )) || (!r1_adjacent_contains_r2( r1, r2 ) && !r1_adjacent_contains_r2( r2, r1 )) ); }
int move_matches_diff_edge(solution_t* s, move_t* move) { int tot; piece_t *p1, *p2, *p1_old, *p2_old; dir d; d=direction_edge(move->pos,s->n); p1=piece_new(s->mat[0][1]->square_index,square_rotate_edge(squares[s->mat[0][1]->square_index],d)); p2=piece_new(move->square_index,move->rotation); //non adjacent swap //old pieces matches are subtracted tot=s->matches - solution_piece_matches_edge(s,NULL,move->pos) - solution_piece_matches_edge(s,NULL,1); //new pieces matches are added tot+=solution_piece_matches_edge(s,p2,1) + solution_piece_matches_edge(s,p1,move->pos); d=is_adjacent(1,move->pos,s->n); //adjacent swap if (d!=NONE) { p1_old=s->mat[0][1]; p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)]; if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) //the match has been subtracted twice tot++; //to avoid counting matches with the previous version of themselves if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) ) tot--; if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) ) tot--; //to count the match between the new versions if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) ) tot++; } piece_free(p1); piece_free(p2); return(tot); }
bool bite_actor::call( monster &z ) const { if( !z.can_act() ) { return false; } Creature *target = z.attack_target(); if( target == nullptr || !is_adjacent( z, *target ) ) { return false; } z.mod_moves( -move_cost ); add_msg( m_debug, "%s attempting to bite %s", z.name().c_str(), target->disp_name().c_str() ); int hitspread = target->deal_melee_attack( &z, z.hit_roll() ); if( hitspread < 0 ) { auto msg_type = target == &g->u ? m_warning : m_info; sfx::play_variant_sound( "mon_bite", "bite_miss", sfx::get_heard_volume( z.pos() ), sfx::get_heard_angle( z.pos() ) ); target->add_msg_player_or_npc( msg_type, _( "The %s lunges at you, but you dodge!" ), _( "The %s lunges at <npcname>, but they dodge!" ), z.name().c_str() ); return true; } damage_instance damage = damage_max_instance; dealt_damage_instance dealt_damage; body_part hit; double multiplier = rng_float( min_mul, max_mul ); damage.mult_damage( multiplier ); target->deal_melee_hit( &z, hitspread, false, damage, dealt_damage ); hit = dealt_damage.bp_hit; int damage_total = dealt_damage.total_damage(); add_msg( m_debug, "%s's bite did %d damage", z.name().c_str(), damage_total ); if( damage_total > 0 ) { auto msg_type = target == &g->u ? m_bad : m_info; //~ 1$s is monster name, 2$s bodypart in accusative if( target->is_player() ) { sfx::play_variant_sound( "mon_bite", "bite_hit", sfx::get_heard_volume( z.pos() ), sfx::get_heard_angle( z.pos() ) ); sfx::do_player_death_hurt( *dynamic_cast<player *>( target ), 0 ); } target->add_msg_player_or_npc( msg_type, _( "The %1$s bites your %2$s!" ), _( "The %1$s bites <npcname>'s %2$s!" ), z.name().c_str(), body_part_name_accusative( hit ).c_str() ); if( one_in( no_infection_chance - damage_total ) ) { if( target->has_effect( effect_bite, hit ) ) { target->add_effect( effect_bite, 400, hit, true ); } else if( target->has_effect( effect_infected, hit ) ) { target->add_effect( effect_infected, 250, hit, true ); } else { target->add_effect( effect_bite, 1, hit, true ); } } } else { sfx::play_variant_sound( "mon_bite", "bite_miss", sfx::get_heard_volume( z.pos() ), sfx::get_heard_angle( z.pos() ) ); target->add_msg_player_or_npc( _( "The %1$s bites your %2$s, but fails to penetrate armor!" ), _( "The %1$s bites <npcname>'s %2$s, but fails to penetrate armor!" ), z.name().c_str(), body_part_name_accusative( hit ).c_str() ); } return true; }
Board adj_friendly(const GameState& gs, const uint8_t for_color, const unsigned int direction) { const Board& color_board = gs.get_color_board(for_color); return is_adjacent(color_board, color_board, direction); }
Board adj_empty(const GameState& gs, const uint8_t for_color, const unsigned int direction) { const Board& color_board = gs.get_color_board(for_color); const Board empties = ~gs.get_all_const(); return is_adjacent(color_board, empties, direction); }
// merge r2 into r1 by first removing all common adjacencies from r2 // then transferring the remainder of adjacencies to r1 after discarding // any excess adjacencies. static void merge_regions( Segmenter *s, Region* r1, Region* r2 ) { int i; assert( r1 != r2 ); assert( !r1_adjacent_contains_r2( r1, r2 ) && !r1_adjacent_contains_r2( r2, r1 ) ); if( r1->flags & SATURATED_REGION_FLAG ){ make_saturated( r2 ); if( r2->flags & SATURATED_REGION_FLAG ) make_saturated( r1 ); }else if( r2->flags & SATURATED_REGION_FLAG ){ make_saturated( r1 ); }else{ // remove adjacencies of r2 which are already in r1 for( i = 0; i<r2->adjacent_region_count; ++i ){ Region *a = r2->adjacent_regions[i]; if( is_adjacent( a, r1 ) ){ remove_adjacent_from( a, r2 ); r2->adjacent_regions[i] = r2->adjacent_regions[ --r2->adjacent_region_count ]; } } if( r1->adjacent_region_count + r2->adjacent_region_count > s->max_adjacent_regions ){ make_saturated( r1 ); make_saturated( r2 ); }else{ // remove adjacencies from r2 and add them to r1 for( i=0; i < r2->adjacent_region_count; ++i ){ Region *a = r2->adjacent_regions[ i ]; replace_adjacent( a, r2, r1 ); // replace r2 with r1 in the adjacency list of a r1->adjacent_regions[r1->adjacent_region_count++] = a; assert( a->adjacent_region_count <= s->max_adjacent_regions ); assert( r1->adjacent_region_count <= s->max_adjacent_regions ); } r2->adjacent_region_count = 0; } } r1->flags |= r2->flags; if( r2->left < r1->left ) r1->left = r2->left; if( r2->top < r1->top ) r1->top = r2->top; if( r2->right > r1->right ) r1->right = r2->right; if( r2->bottom > r1->bottom ) r1->bottom = r2->bottom; // postcondition: all adjacencies to r1 are bidirectional #ifndef NDEBUG for( i = 0; i < r1->adjacent_region_count; ++i ){ Region *a = r1->adjacent_regions[i]; assert( r1_adjacent_contains_r2( r1, a ) ); } #endif }