Вложенные циклы - удалить оба элемента i и j - PullRequest
1 голос
/ 30 апреля 2020

Я использую каркас создания игр, реализованный в Lua, чтобы оставаться в карантине. Я делаю простой платформер с ECS / DOP и хотел создать геометрию столкновений, основанную на карте тайлов, а не просто проверять столкновения со всеми тайлами.

Каждая плитка имеет компонент ограничительной рамки, который указывает на список, содержащий базовые c фигуры. Каждая фигура хранит края ограничительной рамки как {{x1, y1}, {x2, y2}}. Первым шагом в этом процессе является анализ таблицы TileMap, которая содержит только имена плиток, а затем вставка копии соответствующей ограничительной рамки, преобразованной строкой / столбцом * grid_dimension, в таблицу с именем BBOX. Следующим шагом является удаление всех экземпляров ребра, если это дубликат, показанный этим изображением

image

, где я застрял.

Требуемый базовый c алгоритм удаления ребер выглядит следующим образом:

for i = #BBOX, 1, -1 do
    local edge1 = BBOX[i]
    for j = i, 1, -1 do
        local edge2 = BBOX[j]
        same_edge = edge1 == edge2 -- Not the actual comparison, just the outcome of it
        if same_edge and i ~= j then
           BBOX[i] = nil
           BBOX[j] = nil
        end
    end
end

Разумеется, проблема в том, что эти ошибки, когда i равна j , который был удален ранее в l oop. Я огляделся и не смог найти способ удалить все экземпляры повторяющихся значений в lua, только решения, которые заботятся об уникальности. Кто-нибудь нашел эффективный способ сделать это или что-то подобное?

1 Ответ

0 голосов
/ 30 апреля 2020

Если вы используете значение, уникальное для каждого ключа, вы можете лучше обнаружить дубликаты. мы назовем это уникальное значение edge.key.

Если ребро будет существовать не более двух раз, тогда:

BBOX[edge.key] = BBOX[edge.key] == nil and edge or nil

сделает свое дело.

Но где Край может существовать любое произвольное количество раз, когда мы можем сделать что-то вроде этого:

local duplicateEdges = {}

for i = #BBOX, 1, -1 do
  if BBOX[edge_key] then
    duplicateEdges[edge_key] = true
  else
    BBOX[edge_key] = edge
  end

  for j = i, 1, -1 do
    if BBOX[edge_key] then
      duplicateEdges[edge_key] = true
    else
      BBOX[edge_key] = edge
    end
  end
end

for k in pairs(duplicateEdges) do
  BBOX[k] = nil
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...