|
|
|
|
|
|
|
|
|
|
| .hex_adjacency_cache <- new.env(hash = TRUE, parent = emptyenv())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| get_hex_adjacency_matrix <- function(rings) {
|
| cache_key <- as.character(rings)
|
|
|
|
|
|
|
| if (exists(cache_key, envir = .hex_adjacency_cache, inherits = FALSE)) {
|
| return(get(cache_key, envir = .hex_adjacency_cache, inherits = FALSE))
|
| }
|
|
|
|
|
| num_pieces <- 3 * rings * (rings - 1) + 1
|
|
|
|
|
|
|
| adj_matrix <- matrix(NA_integer_, nrow = num_pieces, ncol = 6)
|
|
|
|
|
| coord_to_piece <- new.env(hash = TRUE, parent = emptyenv())
|
| piece_coords <- vector("list", num_pieces)
|
|
|
|
|
| for (piece_id in 1:num_pieces) {
|
| axial <- map_piece_id_to_axial(piece_id, rings)
|
| coord_key <- paste(axial$q, axial$r, sep = ",")
|
| coord_to_piece[[coord_key]] <- piece_id
|
| piece_coords[[piece_id]] <- c(axial$q, axial$r)
|
| }
|
|
|
|
|
|
|
| directions <- list(
|
| c(1, 0),
|
| c(1, -1),
|
| c(0, -1),
|
| c(-1, 0),
|
| c(-1, 1),
|
| c(0, 1)
|
| )
|
|
|
|
|
| for (piece_id in 1:num_pieces) {
|
| coords <- piece_coords[[piece_id]]
|
| q <- coords[1]
|
| r <- coords[2]
|
|
|
| for (side in 0:5) {
|
| dir <- directions[[side + 1]]
|
| neighbor_q <- q + dir[1]
|
| neighbor_r <- r + dir[2]
|
| neighbor_key <- paste(neighbor_q, neighbor_r, sep = ",")
|
|
|
|
|
| if (exists(neighbor_key, envir = coord_to_piece, inherits = FALSE)) {
|
| adj_matrix[piece_id, side + 1] <- coord_to_piece[[neighbor_key]]
|
| }
|
|
|
| }
|
| }
|
|
|
|
|
| assign(cache_key, adj_matrix, envir = .hex_adjacency_cache)
|
|
|
| return(adj_matrix)
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| get_hex_neighbor_fast <- function(piece_id, side, rings) {
|
| adj_matrix <- get_hex_adjacency_matrix(rings)
|
| return(adj_matrix[piece_id, side + 1])
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| get_hex_neighbors_fast <- function(piece_id, rings) {
|
| adj_matrix <- get_hex_adjacency_matrix(rings)
|
|
|
|
|
| neighbors <- data.frame(
|
| direction = as.character(0:5),
|
| neighbor_id = adj_matrix[piece_id, ],
|
| is_boundary = is.na(adj_matrix[piece_id, ]),
|
| stringsAsFactors = FALSE
|
| )
|
|
|
| return(neighbors)
|
| }
|
|
|
|
|
|
|
|
|
|
|
| clear_hex_adjacency_cache <- function() {
|
| rm(list = ls(envir = .hex_adjacency_cache), envir = .hex_adjacency_cache)
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| compute_hex_fused_edges_fast <- function(fusion_groups, rings) {
|
| if (is.null(fusion_groups) || length(fusion_groups) == 0) {
|
| return(NULL)
|
| }
|
|
|
|
|
| piece_to_group <- new.env(hash = TRUE, parent = emptyenv())
|
| for (group_idx in seq_along(fusion_groups)) {
|
| group <- fusion_groups[[group_idx]]
|
| for (piece_id in group) {
|
| piece_to_group[[as.character(piece_id)]] <- group_idx
|
| }
|
| }
|
|
|
|
|
| group_sets <- lapply(fusion_groups, function(group) {
|
| group_set <- new.env(hash = TRUE, parent = emptyenv())
|
| for (piece_id in group) {
|
| group_set[[as.character(piece_id)]] <- TRUE
|
| }
|
| group_set
|
| })
|
|
|
|
|
| edge_set <- new.env(hash = TRUE, parent = emptyenv())
|
|
|
|
|
| fused_edges_list <- list()
|
| edge_to_group <- list()
|
|
|
|
|
| for (group_idx in seq_along(fusion_groups)) {
|
| group <- fusion_groups[[group_idx]]
|
| group_set <- group_sets[[group_idx]]
|
|
|
| for (piece_id in group) {
|
|
|
| neighbors <- get_hex_neighbors_for_fusion(piece_id, rings)
|
|
|
| for (i in seq_len(nrow(neighbors))) {
|
| direction <- neighbors$direction[i]
|
| neighbor_id <- neighbors$neighbor_id[i]
|
| is_boundary <- neighbors$is_boundary[i]
|
|
|
|
|
| if (is_boundary || is.na(neighbor_id)) next
|
|
|
|
|
| if (exists(as.character(neighbor_id), envir = group_set, inherits = FALSE)) {
|
|
|
| edge_key <- make_edge_key(piece_id, direction)
|
|
|
|
|
| if (!exists(edge_key, envir = edge_set, inherits = FALSE)) {
|
| edge_set[[edge_key]] <- TRUE
|
| fused_edges_list[[length(fused_edges_list) + 1]] <- edge_key
|
| edge_to_group[[edge_key]] <- group_idx
|
| }
|
| }
|
| }
|
| }
|
| }
|
|
|
|
|
| piece_to_group_list <- as.list(piece_to_group)
|
| names(piece_to_group_list) <- ls(piece_to_group)
|
|
|
| return(list(
|
| fused_edges = unlist(fused_edges_list),
|
| edge_to_group = edge_to_group,
|
| piece_to_group = piece_to_group_list
|
| ))
|
| }
|
|
|