Skip to content

Commit 410ff69

Browse files
stephencelismluisbrown
authored andcommitted
Model Tic-Tac-Toe board using proper type (#722)
* Model Tic-Tac-Toe board using proper type * Update GameCore.swift * wip * wip
1 parent a60e93e commit 410ff69

File tree

4 files changed

+55
-9
lines changed

4 files changed

+55
-9
lines changed

Examples/TicTacToe/tic-tac-toe/Sources/GameCore/GameCore.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public enum Player: Equatable {
2121
}
2222

2323
public struct GameState: Equatable {
24-
public var board: [[Player?]] = .empty
24+
public var board: Three<Three<Player?>> = .empty
2525
public var currentPlayer: Player = .x
2626
public var oPlayerName: String
2727
public var xPlayerName: String
@@ -74,12 +74,12 @@ public let gameReducer = Reducer<GameState, GameAction, GameEnvironment> { state
7474
}
7575
}
7676

77-
extension Array where Element == [Player?] {
78-
public static let empty: Self = [
79-
[nil, nil, nil],
80-
[nil, nil, nil],
81-
[nil, nil, nil],
82-
]
77+
extension Three where Element == Three<Player?> {
78+
public static let empty = Self(
79+
.init(nil, nil, nil),
80+
.init(nil, nil, nil),
81+
.init(nil, nil, nil)
82+
)
8383

8484
public var isFilled: Bool {
8585
self.allSatisfy { row in row.allSatisfy { $0 != nil } }
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/// A collection of three elements.
2+
public struct Three<Element> {
3+
public var first: Element
4+
public var second: Element
5+
public var third: Element
6+
7+
public init(_ first: Element, _ second: Element, _ third: Element) {
8+
self.first = first
9+
self.second = second
10+
self.third = third
11+
}
12+
13+
public func map<T>(_ transform: (Element) -> T) -> Three<T> {
14+
.init(transform(self.first), transform(self.second), transform(self.third))
15+
}
16+
}
17+
18+
extension Three: MutableCollection {
19+
public subscript(offset: Int) -> Element {
20+
_read {
21+
switch offset {
22+
case 0: yield self.first
23+
case 1: yield self.second
24+
case 2: yield self.third
25+
default: fatalError()
26+
}
27+
}
28+
_modify {
29+
switch offset {
30+
case 0: yield &self.first
31+
case 1: yield &self.second
32+
case 2: yield &self.third
33+
default: fatalError()
34+
}
35+
}
36+
}
37+
38+
public var startIndex: Int { 0 }
39+
public var endIndex: Int { 3 }
40+
public func index(after i: Int) -> Int { i + 1 }
41+
}
42+
43+
extension Three: RandomAccessCollection {}
44+
45+
extension Three: Equatable where Element: Equatable {}
46+
extension Three: Hashable where Element: Hashable {}

Examples/TicTacToe/tic-tac-toe/Sources/GameSwiftUI/GameView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public struct GameView: View {
7878
proxy: GeometryProxy,
7979
viewStore: ViewStore<ViewState, GameAction>
8080
) -> some View {
81-
Button.init(action: {
81+
Button(action: {
8282
viewStore.send(.cellTapped(row: row, column: column))
8383
}) {
8484
Text(viewStore.board[row][column])

Examples/TicTacToe/tic-tac-toe/Sources/GameUIKit/GameViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public final class GameViewController: UIViewController {
88
let viewStore: ViewStore<ViewState, GameAction>
99

1010
struct ViewState: Equatable {
11-
let board: [[String]]
11+
let board: Three<Three<String>>
1212
let isGameEnabled: Bool
1313
let isPlayAgainButtonHidden: Bool
1414
let title: String?

0 commit comments

Comments
 (0)