Created
August 9, 2023 10:27
-
-
Save danpecher/c0395caeb3d5fb3b30bce42a3bd299e7 to your computer and use it in GitHub Desktop.
Tennis fun
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| enum Score { | |
| case love | |
| case fifteen | |
| case thirty | |
| case forty | |
| case deuce | |
| var label: String { | |
| switch self { | |
| case .love: | |
| return "Love" | |
| case .fifteen: | |
| return "Fifteen" | |
| case .thirty: | |
| return "Thirty" | |
| case .forty: | |
| return "Forty" | |
| case .deuce: | |
| return "Deuce" | |
| } | |
| } | |
| } | |
| class Player: Equatable { | |
| let name: String | |
| var score: Int | |
| init(name: String, score: Int) { | |
| self.name = name | |
| self.score = score | |
| } | |
| static func == (lhs: Player, rhs: Player) -> Bool { | |
| lhs.name == rhs.name | |
| } | |
| } | |
| enum GameStatus { | |
| case equal(Score) | |
| case advantage(Player) | |
| case different(Score, Score) | |
| case won(Player) | |
| } | |
| class TennisGame1: TennisGame { | |
| private let player1: Player | |
| private let player2: Player | |
| static let advantageScore = 4 | |
| static let scoreMap: [Int: Score] = [ | |
| 0: .love, | |
| 1: .fifteen, | |
| 2: .thirty, | |
| 3: .forty, | |
| 4: .deuce | |
| ] | |
| required init(player1: String, player2: String) { | |
| self.player1 = Player(name: player1, score: 0) | |
| self.player2 = Player(name: player2, score: 0) | |
| } | |
| func wonPoint(_ playerName: String) { | |
| // TODO: Handle equal names? | |
| [player1, player2] | |
| .first { | |
| $0.name == playerName | |
| }? | |
| .score += 1 | |
| } | |
| var score: String? { | |
| switch status { | |
| case .equal(let score): | |
| if score == .deuce || score == .forty { | |
| return Score.deuce.label | |
| } | |
| return "\(score.label)-All" | |
| case .advantage(let player): | |
| let playerNumber = player == player1 ? "1" : "2" | |
| return "Advantage player\(playerNumber)" | |
| case .different(let score1, let score2): | |
| return "\(score1.label)-\(score2.label)" | |
| case .won(let player): | |
| let playerNumber = player == player1 ? "1" : "2" | |
| return "Win for player\(playerNumber)" | |
| } | |
| } | |
| private var status: GameStatus { | |
| if player1.score == player2.score { | |
| return .equal(Self.scoreMap[player1.score]!) | |
| } | |
| let sortedPlayers = [player1, player2].sorted(by: { $0.score < $1.score }) | |
| let scoreDifference = abs(player1.score - player2.score) | |
| if | |
| scoreDifference >= 2, | |
| let winningPlayer = sortedPlayers.last, | |
| winningPlayer.score >= Self.advantageScore | |
| { | |
| return .won(winningPlayer) | |
| } | |
| if scoreDifference == 1, let advantagePlayer = sortedPlayers.last(where: { $0.score >= Self.advantageScore }) { | |
| return .advantage(advantagePlayer) | |
| } | |
| return .different( | |
| Self.scoreMap[player1.score]!, | |
| Self.scoreMap[player2.score]! | |
| ) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment