Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Commit

Permalink
add: Introduce DirectedDistance
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuniwak committed Apr 30, 2020
1 parent f7c65ce commit b41c39b
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 50 deletions.
3 changes: 1 addition & 2 deletions Reversi/MVCArchitecture/Models/Board.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ extension Board where T == Disk? {
// NOTE: Break if the line is out of the board.
guard let line = Line(
start: coordinateForSameColor,
direction: direction,
distance: distance
directedDistance: DirectedDistance(direction: direction, distance: distance)
) else {
break
}
Expand Down
15 changes: 7 additions & 8 deletions Reversi/MVCArchitecture/Models/BoardTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import MirrorDiffKit
@testable import Reversi



class BoardTests: XCTestCase {
func testAvailability() {
struct TestCase {
Expand All @@ -11,6 +12,8 @@ class BoardTests: XCTestCase {
let expected: Set<Line>
}



let testCases: [UInt: TestCase] = [
#line: TestCase(
board: Board(unsafeArray: [
Expand All @@ -28,26 +31,22 @@ class BoardTests: XCTestCase {
Line(
start: Coordinate(x: .four, y: .four),
unsafeEnd: Coordinate(x: .four, y: .six),
direction: .bottom,
distance: .two
directedDistance: DirectedDistance(direction: .bottom, distance: .two)
),
Line(
start: Coordinate(x: .four, y: .four),
unsafeEnd: Coordinate(x: .six, y: .four),
direction: .right,
distance: .two
directedDistance: DirectedDistance(direction: .right, distance: .two)
),
Line(
start: Coordinate(x: .five, y: .five),
unsafeEnd: Coordinate(x: .five, y: .three),
direction: .top,
distance: .two
directedDistance: DirectedDistance(direction: .top, distance: .two)
),
Line(
start: Coordinate(x: .five, y: .five),
unsafeEnd: Coordinate(x: .three, y: .five),
direction: .left,
distance: .two
directedDistance: DirectedDistance(direction: .left, distance: .two)
),
])
),
Expand Down
32 changes: 32 additions & 0 deletions Reversi/MVCArchitecture/Models/Coordinate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,38 @@ struct Coordinate: Hashable {
}


func moved(to directedDistance: DirectedDistance) -> Coordinate? {
// NOTE: Be nil if the X is out of boards.
let unsafeX: CoordinateX?
switch directedDistance.direction {
case .top, .bottom:
unsafeX = self.x
case .left, .topLeft, .bottomLeft:
unsafeX = CoordinateX(rawValue: self.x.rawValue - directedDistance.distance.rawValue)
case .right, .topRight, .bottomRight:
unsafeX = CoordinateX(rawValue: self.x.rawValue + directedDistance.distance.rawValue)
}

// NOTE: Be nil if the Y is out of boards.
let unsafeY: CoordinateY?
switch directedDistance.direction {
case .left, .right:
unsafeY = self.y
case .top, .topLeft, .topRight:
unsafeY = CoordinateY(rawValue: self.y.rawValue - directedDistance.distance.rawValue)
case .bottom, .bottomLeft, .bottomRight:
unsafeY = CoordinateY(rawValue: self.y.rawValue + directedDistance.distance.rawValue)
}

switch (unsafeX, unsafeY) {
case (.none, _), (_, .none):
return nil
case (.some(let x), .some(let y)):
return Coordinate(x: x, y: y)
}
}


static let allCases: [Coordinate] = CoordinateY.allCases.flatMap { y in
CoordinateX.allCases.map { x in
Coordinate(x: x, y: y)
Expand Down
27 changes: 27 additions & 0 deletions Reversi/MVCArchitecture/Models/DirectedDistance.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
struct DirectedDistance: Hashable {
let direction: Direction
let distance: Distance


var next: DirectedDistance? {
guard let nextDistance = self.distance.next else {
return nil
}
return DirectedDistance(direction: self.direction, distance: nextDistance)
}


var prev: DirectedDistance? {
guard let prevDistance = self.distance.prev else {
return nil
}
return DirectedDistance(direction: self.direction, distance: prevDistance)
}
}


extension DirectedDistance: CustomDebugStringConvertible {
public var debugDescription: String {
"direction=\(self.direction), distance=\(self.distance)"
}
}
53 changes: 13 additions & 40 deletions Reversi/MVCArchitecture/Models/Line.swift
Original file line number Diff line number Diff line change
@@ -1,73 +1,46 @@
struct Line: Hashable {
let start: Coordinate
let end: Coordinate
let direction: Direction
let distance: Distance
let directedDistance: DirectedDistance


init(start: Coordinate, unsafeEnd: Coordinate, direction: Direction, distance: Distance) {
init(start: Coordinate, unsafeEnd: Coordinate, directedDistance: DirectedDistance) {
self.start = start
self.end = unsafeEnd
self.direction = direction
self.distance = distance
self.directedDistance = directedDistance
}


init?(start: Coordinate, direction: Direction, distance: Distance) {
// NOTE: Be nil if the X is out of boards.
let unsafeX: CoordinateX?
switch direction {
case .top, .bottom:
unsafeX = start.x
case .left, .topLeft, .bottomLeft:
unsafeX = CoordinateX(rawValue: start.x.rawValue - distance.rawValue)
case .right, .topRight, .bottomRight:
unsafeX = CoordinateX(rawValue: start.x.rawValue + distance.rawValue)
}

// NOTE: Be nil if the Y is out of boards.
let unsafeY: CoordinateY?
switch direction {
case .left, .right:
unsafeY = start.y
case .top, .topLeft, .topRight:
unsafeY = CoordinateY(rawValue: start.y.rawValue - distance.rawValue)
case .bottom, .bottomLeft, .bottomRight:
unsafeY = CoordinateY(rawValue: start.y.rawValue + distance.rawValue)
}

switch (unsafeX, unsafeY) {
case (.none, _), (_, .none):
init?(start: Coordinate, directedDistance: DirectedDistance) {
guard let end = start.moved(to: directedDistance) else {
return nil
case (.some(let x), .some(let y)):
self.start = start
self.end = Coordinate(x: x, y: y)
self.direction = direction
self.distance = distance
}
self.start = start
self.end = end
self.directedDistance = directedDistance
}


var shortened: Line? {
guard let prevDistance = self.distance.prev else {
guard let prevDirectedDistance = self.directedDistance.prev else {
return nil
}
return Line(start: start, direction: self.direction, distance: prevDistance)
return Line(start: start, directedDistance: prevDirectedDistance)
}


var grown: Line? {
guard let nextDistance = self.distance.next else {
guard let nextDirectedDistance = self.directedDistance.next else {
return nil
}
return Line(start: start, direction: self.direction, distance: nextDistance)
return Line(start: start, directedDistance: nextDirectedDistance)
}
}



extension Line: CustomDebugStringConvertible {
public var debugDescription: String {
"{Line: start=\(self.start.debugDescription), end=\(self.end.debugDescription), direction=\(self.direction), distance=\(self.distance)}"
"{Line: start=\(self.start.debugDescription), end=\(self.end.debugDescription), \(self.directedDistance)}"
}
}

0 comments on commit b41c39b

Please sign in to comment.