Все ли эти if-утверждения действительно необходимы? - PullRequest
0 голосов
/ 06 октября 2018

У меня есть эта функция, которая соединяет две комнаты с прихожей.Это кажется действительно неэффективным, но я не могу найти лучший способ сделать это.Это часть моего алгоритма BSP для генерации подземелий.Вы можете найти полный алгоритм здесь .

public func createHall(left:Room, right:Room) {
    // Connects 2 rooms together with hallways

    // Reset hallways function to make sure its empty. hallways = [Room]()
    hallways = []

    // get width and height of first room
    let point1 = CGPoint(x: Int.random(in: (left.x1 + 1)..<(left.x2 - 1)),
                         y: Int.random(in: (left.y1 + 1)..<(left.y2 - 1)))

    // get width and height of second room
    let point2 = CGPoint(x: Int.random(in: (right.x1 + 1)..<(right.x2 - 1)),
                         y: Int.random(in: (right.y1 + 1)..<(right.y2 - 1)))

    let w = point2.x - point1.x
    let h = point2.y - point1.y

    if w < 0 {
        if h < 0 {
            if Double.random(in: 0..<1.0) > 0.5 {
                hallways.append(Room(X: Int(point2.x), Y: Int(point1.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point2.x), Y: Int(point2.y), W: 1, H: Int(abs(h))))
            } else {
                hallways.append(Room(X: Int(point2.x), Y: Int(point2.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point1.x), Y: Int(point2.y), W: 1, H: Int(abs(h))))
            }
        } else if h > 0 {
            if Double.random(in: 0..<1.0) > 0.5 {
                hallways.append(Room(X: Int(point2.x), Y: Int(point1.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point2.x), Y: Int(point1.y), W: 1, H: Int(abs(h))))
            } else {
                hallways.append(Room(X: Int(point2.x), Y: Int(point2.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point1.x), Y: Int(point1.y), W: 1, H: Int(abs(h))))
            }
        } else {
            hallways.append(Room(X: Int(point2.x), Y: Int(point2.y), W: Int(abs(w)), H: 1))
        }
    } else if w > 0 {
        if h < 0 {
            if Double.random(in: 0..<1.0) > 0.5 {
                hallways.append(Room(X: Int(point1.x), Y: Int(point2.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point1.x), Y: Int(point2.y), W: 1, H: Int(abs(h))))
            } else {
                hallways.append(Room(X: Int(point1.x), Y: Int(point1.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point2.x), Y: Int(point2.y), W: 1, H: Int(abs(h))))
            }
        } else if h > 0 {
            if Double.random(in: 0..<1.0) > 0.5 {
                hallways.append(Room(X: Int(point1.x), Y: Int(point1.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point2.x), Y: Int(point1.y), W: 1, H: Int(abs(h))))
            } else {
                hallways.append(Room(X: Int(point1.x), Y: Int(point2.y), W: Int(abs(w)), H: 1))
                hallways.append(Room(X: Int(point1.x), Y: Int(point1.y), W: 1, H: Int(abs(h))))
            }
        } else {
            hallways.append(Room(X: Int(point1.x), Y: Int(point1.y), W: Int(abs(w)), H: 1))
        }
    } else {
        if h < 0 {
            hallways.append(Room(X: Int(point2.x), Y: Int(point2.y), W: 1, H: Int(abs(h))))
        } else if h > 0 {
            hallways.append(Room(X: Int(point1.x), Y: Int(point1.y), W: 1, H: Int(abs(h))))
        }
    }
}

Где Room - это пользовательский класс, который я написал для вычисления прямоугольника и его центра:

class Room {
    var x1:Int
    var x2:Int
    var y1:Int
    var y2:Int
    var center:CGPoint

    init(X: Int, Y: Int, W: Int, H: Int) {
        x1 = X
        x2 = X + W
        y1 = Y
        y2 = Y + H
        center = CGPoint(x: (x1 + x2) / 2, y: (y1 + y2) / 2)
    }
}

Моя самая успешная попытка:

func hCorridor(x1: Int, x2: Int, y: Int) {
    for x in min(x1,x2)...max(x1,x2) {
        hallways.append(Room(X: y, Y: y, W: 1, H: Int(abs(h))))
    }
}

func vCorridor(y1: Int, y2: Int, x: Int) {
    for y in min(y1,y2)...max(y1,y2) {
        hallways.append(Room(X: y, Y: y, W: Int(abs(w), H: 1))
    }
}

// Randomly choose to start with horizontal or vertical corridors
if Double.random(in: 0..<1.0) > 0.5 {
    hCorridor(x1: Int(point1.x), x2: Int(point2.x), y: Int(point1.y))
    vCorridor(y1: Int(point1.y), y2: Int(point2.y), x: Int(point2.x))
} else {
    vCorridor(y1: Int(point1.y), y2: Int(point2.y), x: Int(point1.x))
    hCorridor(x1: Int(point1.x), x2: Int(point2.x), y: Int(point2.y))
}

Всеэти операторы if в функции createHall() действительно необходимы?Если нет, то как лучше написать их?Все мои попытки не работают так, как операторы if.Мои попытки дают мне тупики и недоступные комнаты.

1 Ответ

0 голосов
/ 06 октября 2018

Если я правильно понимаю вашу проблему, вы

  • сначала выбираете две случайные точки point1, point2 в левой (соответственно правой) комнате и
  • , затемсоедините комнаты двумя «коридорами» от point1 до point2, либо сначала по горизонтали, а затем по вертикали, либо наоборот.

Помимо случайного выбора, вам не нужно, еслиоператоры, если вы используете min и abs для вычисления координат коридора.Что-то вроде (дополнительные пояснения):

if Bool.random() {
    // Horizontally first, then vertically:
    // From point1 to (point2.x, point1.y):
    hallways.append(Room(X: Int(min(point1.x, point2.x)), Y: Int(point1.y),
                         W: Int(abs(point1.x - point2.x)), H: 1))
    // From (point2.x, point1.y) to point2:
    hallways.append(Room(X: Int(point2.x), Y: Int(min(point1.y, point2.y)),
                         W: 1, H: Int(abs(point1.y - point2.y))))
} else {
    // Vertically first, then Horizontally:
    // From point1 to (point1.x, point2.y):
    hallways.append(Room(X: Int(point1.x), Y: Int(min(point1.y, point2.y)),
                         W: 1, H: Int(abs(point1.y - point2.y))))
    // From (point1.x, point2.y) to point2:
    hallways.append(Room(X: Int(min(point1.x, point2.x)), Y: Int(point2.y),
                         W: Int(abs(point1.x - point2.x)), H: 1))
}
...