import ComposableArchitecture
import SwiftUI
@Reducer
public struct Game: Sendable {
@ObservableState
public struct State: Equatable {
public var board: Three<Three<Player?>> = .empty
public var currentPlayer: Player = .x
public let oPlayerName: String
public let xPlayerName: String
public init(oPlayerName: String, xPlayerName: String) {
self.oPlayerName = oPlayerName
self.xPlayerName = xPlayerName
}
public var currentPlayerName: String {
switch self.currentPlayer {
case .o: return self.oPlayerName
case .x: return self.xPlayerName
}
}
}
public enum Action: Sendable {
case cellTapped(row: Int, column: Int)
case playAgainButtonTapped
case quitButtonTapped
}
@Dependency(\.dismiss) var dismiss
public init() {}
public var body: some Reducer<State, Action> {
Reduce { state, action in
switch action {
case .cellTapped(let row, let column):
guard
state.board[row][column] == nil,
!state.board.hasWinner
else { return .none }
state.board[row][column] = state.currentPlayer
if !state.board.hasWinner {
state.currentPlayer.toggle()
}
return .none
case .playAgainButtonTapped:
state = Game.State(
oPlayerName: state.oPlayerName,
xPlayerName: state.xPlayerName
)
return .none
case .quitButtonTapped:
return .run { _ in
await self.dismiss()
}
}
}
}
}