From 6b6e317a9cedf030aa4a23c852b104db153be19f Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 10 Nov 2018 13:50:28 -0500 Subject: [PATCH] Make Point and Size honest to goodness structs --- Terrain2/Algorithms.swift | 58 +++++++++++++++++----------- Terrain2Tests/AlgorithmsTests.swift | 60 ++++++++++++----------------- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/Terrain2/Algorithms.swift b/Terrain2/Algorithms.swift index 3f44308..ee88760 100644 --- a/Terrain2/Algorithms.swift +++ b/Terrain2/Algorithms.swift @@ -125,18 +125,20 @@ class RandomAlgorithm: Kernel, TerrainGenerator { /// Implementation of the Diamond-Squares algorithm. /// - https://en.wikipedia.org/wiki/Diamond-square_algorithm public class DiamondSquareAlgorithm: TerrainGenerator { - public struct Box { - public typealias Point = (x: Int, y: Int) - public typealias Size = (w: Int, h: Int) + public struct Point { + let x: Int + let y: Int + } + public struct Size { + let w: Int + let h: Int + } + + public struct Box { let origin: Point let size: Size - init(origin o: Point, size s: Size) { - origin = o - size = s - } - var corners: [Point] { return [northwest, southwest, northeast, northwest] } @@ -146,19 +148,19 @@ public class DiamondSquareAlgorithm: TerrainGenerator { } var north: Point { - return (x: origin.x + (size.w / 2 + 1), y: origin.y) + return Point(x: origin.x + (size.w / 2 + 1), y: origin.y) } var west: Point { - return (x: origin.x, y: origin.y + (size.h / 2 + 1)) + return Point(x: origin.x, y: origin.y + (size.h / 2 + 1)) } var south: Point { - return (x: origin.x + (size.w / 2 + 1), y: origin.y + size.h) + return Point(x: origin.x + (size.w / 2 + 1), y: origin.y + size.h) } var east: Point { - return (x: origin.x + size.w, y: origin.y + (size.h / 2 + 1)) + return Point(x: origin.x + size.w, y: origin.y + (size.h / 2 + 1)) } var northwest: Point { @@ -166,19 +168,19 @@ public class DiamondSquareAlgorithm: TerrainGenerator { } var southwest: Point { - return (x: origin.x, y: origin.y + size.h) + return Point(x: origin.x, y: origin.y + size.h) } var northeast: Point { - return (x: origin.x + size.w, y: origin.y) + return Point(x: origin.x + size.w, y: origin.y) } var southeast: Point { - return (x: origin.x + size.w, y: origin.y + size.h) + return Point(x: origin.x + size.w, y: origin.y + size.h) } var midpoint: Point { - return (x: origin.x + (size.w / 2 + 1), y: origin.y + (size.h / 2 + 1)) + return Point(x: origin.x + (size.w / 2 + 1), y: origin.y + (size.h / 2 + 1)) } var subdivisions: [Box] { @@ -186,12 +188,12 @@ public class DiamondSquareAlgorithm: TerrainGenerator { return [] } let midp = midpoint - let newSize = (w: midp.x - origin.x, h: midp.y - origin.y) + let newSize = Size(w: midp.x - origin.x, h: midp.y - origin.y) return [ Box(origin: origin, size: newSize), - Box(origin: (origin.x + newSize.w, origin.y), size: newSize), - Box(origin: (origin.x, origin.y + newSize.h), size: newSize), - Box(origin: (origin.x + newSize.w, origin.y + newSize.h), size: newSize) + Box(origin: Point(x: origin.x + newSize.w, y: origin.y), size: newSize), + Box(origin: Point(x: origin.x, y: origin.y + newSize.h), size: newSize), + Box(origin: Point(x: origin.x + newSize.w, y: origin.y + newSize.h), size: newSize) ] } @@ -230,14 +232,14 @@ public class DiamondSquareAlgorithm: TerrainGenerator { func render() { let size = DiamondSquareAlgorithm.textureSize - func ptToIndex(_ pt: Box.Point) -> Int { + func ptToIndex(_ pt: Point) -> Int { return pt.y * size.width + pt.x } var heightMap = [Float](repeating: 0, count: size.width * size.height) // 0. Set the corners to initial values if they haven't been set yet. - let box = Box(origin: (0, 0), size: (size.width, size.height)) + let box = Box(origin: Point(x: 0, y: 0), size: Size(w: size.width, h: size.height)) for p in box.corners { let idx = ptToIndex(p) if heightMap[idx] == 0.0 { @@ -303,6 +305,18 @@ public class DiamondSquareAlgorithm: TerrainGenerator { } } +extension DiamondSquareAlgorithm.Point: Equatable { + public static func == (lhs: DiamondSquareAlgorithm.Point, rhs: DiamondSquareAlgorithm.Point) -> Bool { + return lhs.x == rhs.x && lhs.y == rhs.y + } +} + +extension DiamondSquareAlgorithm.Size: Equatable { + public static func == (lhs: DiamondSquareAlgorithm.Size, rhs: DiamondSquareAlgorithm.Size) -> Bool { + return lhs.w == rhs.w && lhs.h == rhs.h + } +} + extension DiamondSquareAlgorithm.Box: Equatable { public static func == (lhs: DiamondSquareAlgorithm.Box, rhs: DiamondSquareAlgorithm.Box) -> Bool { return lhs.origin == rhs.origin && lhs.size == rhs.size diff --git a/Terrain2Tests/AlgorithmsTests.swift b/Terrain2Tests/AlgorithmsTests.swift index 9a1475f..d8dad7c 100644 --- a/Terrain2Tests/AlgorithmsTests.swift +++ b/Terrain2Tests/AlgorithmsTests.swift @@ -14,52 +14,50 @@ public typealias Point = DiamondSquareAlgorithm.Box.Point public typealias Size = DiamondSquareAlgorithm.Box.Size class DiamondSquareBoxTests: XCTestCase { + fileprivate let box = Box(origin: Point(x: 3, y: 4), size: Size(w: 5, h: 5)) func testMidpoint() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let midpoint = box.midpoint XCTAssertEqual(midpoint.x, 6) XCTAssertEqual(midpoint.y, 7) } func testSubdivision() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let subdivs = box.subdivisions XCTAssertEqual(subdivs.count, 4) - XCTAssertEqual(subdivs[0], Box(origin: (x: 3, y: 4), size: (w: 3, h: 3))) - XCTAssertEqual(subdivs[1], Box(origin: (x: 6, y: 4), size: (w: 3, h: 3))) - XCTAssertEqual(subdivs[2], Box(origin: (x: 3, y: 7), size: (w: 3, h: 3))) - XCTAssertEqual(subdivs[3], Box(origin: (x: 6, y: 7), size: (w: 3, h: 3))) + XCTAssertEqual(subdivs[0], Box(origin: Point(x: 3, y: 4), size: Size(w: 3, h: 3))) + XCTAssertEqual(subdivs[1], Box(origin: Point(x: 6, y: 4), size: Size(w: 3, h: 3))) + XCTAssertEqual(subdivs[2], Box(origin: Point(x: 3, y: 7), size: Size(w: 3, h: 3))) + XCTAssertEqual(subdivs[3], Box(origin: Point(x: 6, y: 7), size: Size(w: 3, h: 3))) } func testBFS() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) var expectedBoxes: [Box] = [ box, - Box(origin: (x: 3, y: 4), size: (w: 3, h: 3)), - Box(origin: (x: 6, y: 4), size: (w: 3, h: 3)), - Box(origin: (x: 3, y: 7), size: (w: 3, h: 3)), - Box(origin: (x: 6, y: 7), size: (w: 3, h: 3)), + Box(origin: Point(x: 3, y: 4), size: Size(w: 3, h: 3)), + Box(origin: Point(x: 6, y: 4), size: Size(w: 3, h: 3)), + Box(origin: Point(x: 3, y: 7), size: Size(w: 3, h: 3)), + Box(origin: Point(x: 6, y: 7), size: Size(w: 3, h: 3)), - Box(origin: (x: 3, y: 4), size: (w: 2, h: 2)), - Box(origin: (x: 5, y: 4), size: (w: 2, h: 2)), - Box(origin: (x: 3, y: 6), size: (w: 2, h: 2)), - Box(origin: (x: 5, y: 6), size: (w: 2, h: 2)), + Box(origin: Point(x: 3, y: 4), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 5, y: 4), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 3, y: 6), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 5, y: 6), size: Size(w: 2, h: 2)), - Box(origin: (x: 6, y: 4), size: (w: 2, h: 2)), - Box(origin: (x: 8, y: 4), size: (w: 2, h: 2)), - Box(origin: (x: 6, y: 6), size: (w: 2, h: 2)), - Box(origin: (x: 8, y: 6), size: (w: 2, h: 2)), + Box(origin: Point(x: 6, y: 4), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 8, y: 4), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 6, y: 6), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 8, y: 6), size: Size(w: 2, h: 2)), - Box(origin: (x: 3, y: 7), size: (w: 2, h: 2)), - Box(origin: (x: 5, y: 7), size: (w: 2, h: 2)), - Box(origin: (x: 3, y: 9), size: (w: 2, h: 2)), - Box(origin: (x: 5, y: 9), size: (w: 2, h: 2)), + Box(origin: Point(x: 3, y: 7), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 5, y: 7), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 3, y: 9), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 5, y: 9), size: Size(w: 2, h: 2)), - Box(origin: (x: 6, y: 7), size: (w: 2, h: 2)), - Box(origin: (x: 8, y: 7), size: (w: 2, h: 2)), - Box(origin: (x: 6, y: 9), size: (w: 2, h: 2)), - Box(origin: (x: 8, y: 9), size: (w: 2, h: 2)), + Box(origin: Point(x: 6, y: 7), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 8, y: 7), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 6, y: 9), size: Size(w: 2, h: 2)), + Box(origin: Point(x: 8, y: 9), size: Size(w: 2, h: 2)), ].reversed() box.breadthFirstSearch { (box: Box) -> (Void) in @@ -73,28 +71,24 @@ class DiamondSquareBoxTests: XCTestCase { // MARK: Sides func testNorth() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.north XCTAssertEqual(pt.x, 6) XCTAssertEqual(pt.y, 4) } func testWest() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.west XCTAssertEqual(pt.x, 3) XCTAssertEqual(pt.y, 7) } func testSouth() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.south XCTAssertEqual(pt.x, 6) XCTAssertEqual(pt.y, 9) } func testEast() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.east XCTAssertEqual(pt.x, 8) XCTAssertEqual(pt.y, 7) @@ -103,28 +97,24 @@ class DiamondSquareBoxTests: XCTestCase { // MARK: Corners func testNorthwest() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.northwest XCTAssertEqual(pt.x, 3) XCTAssertEqual(pt.y, 4) } func testNortheast() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.northeast XCTAssertEqual(pt.x, 8) XCTAssertEqual(pt.y, 4) } func testSouthwest() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.southwest XCTAssertEqual(pt.x, 3) XCTAssertEqual(pt.y, 9) } func testSoutheast() { - let box = Box(origin: (x: 3, y: 4), size: (w: 5, h: 5)) let pt = box.southeast XCTAssertEqual(pt.x, 8) XCTAssertEqual(pt.y, 9)