Skip to content

Instantly share code, notes, and snippets.

@danpecher
Created August 9, 2023 10:27
Show Gist options
  • Select an option

  • Save danpecher/c0395caeb3d5fb3b30bce42a3bd299e7 to your computer and use it in GitHub Desktop.

Select an option

Save danpecher/c0395caeb3d5fb3b30bce42a3bd299e7 to your computer and use it in GitHub Desktop.
Tennis fun
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