Лучший способ написать это сравнение

Я извиняюсь за использование «лучше», но это серьезно то, что мне нужно.

Я пишу алгоритм генерации «рек», и мне нужно сделать кучу сравнений. Мне было интересно, есть ли лучший способ записать все сравнения, которые я должен сделать.

if Rain.value(atPosition: vector_float2(Float(columns),Float(rows))) == 1.0 {
    fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    if Rain.value(atPosition: vector_float2(Float(columns - 1),Float(rows + 1))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns - 1),Float(rows))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns - 1),Float(rows - 1))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns),Float(rows - 1))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns + 1),Float(rows - 1))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns + 1),Float(rows))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns + 1),Float(rows + 1))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
    if Rain.value(atPosition: vector_float2(Float(columns),Float(rows + 1))) == 0.9 {
        fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
    }
}

По сути, «Дождь» — это Perlin HeightMap, которую я использую для определения количества осадков в моей tileMap. Эти операторы if проверяют 8 смежных плиток на полной карте (которые соответствуют критериям высокого уровня осадков) и определяют наименьшее значение, а затем устанавливают плитку воды в виде реки.

Этот метод невероятно неэффективен, так как я собираюсь продолжать писать операторы if в эти операторы if, чтобы после этого проверять каждую соседнюю плитку. Это будет огромный кусок кода. Есть ли лучший способ проверить каждую соседнюю плитку вокруг определенной плитки в tileMap, чтобы уменьшить размер моего кода?


person E. Huckabee    schedule 18.01.2018    source источник


Ответы (2)


Поскольку вы смотрите на число ± 1, вы можете использовать две петли диапазона:

outerLoop:
for dc in -1...1 {
    for dr in -1...1 {
        if dr == 0 && dc == 0 {
            continue
        }
        if Rain.value(atPosition: vector_float2(Float(columns+dc),Float(rows+dr))) == 0.9 {
            fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
            break outerLoop
        }
    }
}
person Sergey Kalinichenko    schedule 18.01.2018
comment
Я запутался, не могли бы вы объяснить лучше, как это работает? это не похоже на работу. - person E. Huckabee; 18.01.2018
comment
@E.Huckabee E.Huckabee Работает ли исходный код? == 0.9 выглядит подозрительно. Чтобы понять, как работает код, рассмотрим два вложенных цикла и то, как изменится пара dr и dc. Тело внутреннего цикла будет выполняться девять раз для пар (-1,-1), (-1, 0), (-1,1), (0,-1), (0, 0) (пропущено), (0,1) и т. д. - person Sergey Kalinichenko; 18.01.2018
comment
код == 0.9 работает. Он работает, проверяя карту высоты перлина Rain вокруг 8 соседних плиток column, row в поисках наименьшего значения (в диапазоне от 1,0, -1,0, округленного до ближайшего десятого места) в этих 8 соседних плитках. Затем ему нужно будет перейти к проверке этих вновь выбранных плиток на наличие наименьшего значения вокруг них. - person E. Huckabee; 18.01.2018
comment
@E.Huckabee Звучит хорошо. Вы поняли, как работают два вложенных цикла? - person Sergey Kalinichenko; 18.01.2018
comment
Да, теперь мне нужно выяснить, как заставить его работать с моим кодом. - person E. Huckabee; 18.01.2018

Это похоже на ответ @dasblinkenlight.

Если вы в конечном итоге делаете это часто в своем коде, вы можете создать массив adjacentOffsets и пройтись по ним:

let adjacentOffsets = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]

if Rain.value(atPosition: vector_float2(Float(columns),Float(rows))) == 1.0 {
    for (dc, dr) in adjacentOffsets {
        if Rain.value(atPosition: vector_float2(Float(columns+dc),Float(rows+dr))) == 0.9 {
            fullMap.setTileGroup(tileDef4, forColumn: columns, row: rows)
            break
        }
    }
}
person vacawama    schedule 18.01.2018
comment
Большое спасибо! Мне придется принять ответ @dasblinkenlights как правильный, поскольку он работает, и он ответил первым - person E. Huckabee; 18.01.2018
comment
Без проблем. В любом случае, мой ответ был просто модификацией его ответа. - person vacawama; 18.01.2018