Last active
November 22, 2017 18:28
-
-
Save pbouzakis/88bb76316f6fb8295db5d175b148b975 to your computer and use it in GitHub Desktop.
OCaml Tennis Kata
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
(* Tennis Kata in OCaml! *) | |
type player = PlayerOne | PlayerTwo | |
type point = Love | Fifteen | Thirty | |
type score = | |
| Points of point * point | |
| Forty of player * point | |
| Duece | |
| Advantage of player | |
| GameOver of player | |
let is_player_one p = | |
p = PlayerOne | |
let new_game = | |
Points(Love, Love) | |
let transition_to_forty score player = | |
match score with | |
| Points (p1_point, p2_point) -> | |
if is_player_one player then Forty(PlayerOne, p2_point) | |
else Forty(PlayerTwo, p1_point) | |
| _ -> score (* You can only goto Forty from Points *) | |
let transition_to_duece score player = | |
match score with | |
| Forty (player_w_forty, other_point) -> | |
if player_w_forty <> player then Duece else score | |
| Advantage (player_w_adv) -> | |
Duece | |
| _ -> score (* You can only goto Duece from Forty *) | |
let transition_to_advantage score player = | |
match score with | |
| Duece -> Advantage(player) | |
| _ -> score (* You can only goto Advantage from Deuce *) | |
let transition_to_gameover score player = | |
match score with | |
| Advantage (player_w_adv) -> | |
if player_w_adv = player then GameOver(player) else score | |
| Forty (player_w_forty, other_point) -> | |
if player_w_forty = player then GameOver(player) else score | |
| _ -> score (* You can only goto GameOver from Advantage & Forty *) | |
let next_score_from_points point other_point player score = | |
match point with | |
| Love -> Points(Fifteen, other_point) | |
| Fifteen -> Points(Thirty, other_point) | |
| Thirty -> transition_to_forty score player | |
let next_score_from_forty player_w_forty point score player = | |
match point with | |
| Love -> Forty(player_w_forty, Fifteen) | |
| Fifteen -> Forty(player_w_forty, Thirty) | |
| Thirty -> transition_to_duece score player | |
let player_scored score player = | |
match score with | |
| Points (p1, p2) -> | |
if is_player_one player then next_score_from_points p1 p2 player score | |
else next_score_from_points p2 p1 player score | |
| Forty (player_w_forty, other_point) -> | |
if player_w_forty = player then transition_to_gameover score player | |
else next_score_from_forty player_w_forty other_point score player | |
| Duece -> transition_to_advantage score player | |
| Advantage (player_w_adv) -> | |
if player_w_adv = player then transition_to_gameover score player | |
else transition_to_duece score player | |
| GameOver (winner) -> GameOver (winner) (* Still the winner *) | |
(* Output as string helpers *) | |
let player_to_str = function | |
| PlayerOne -> "Player 1" | |
| PlayerTwo -> "Player 2" | |
let point_to_str = function | |
| Love -> "love" | |
| Fifteen -> "15" | |
| Thirty -> "30" | |
let score_line p1 p2 = | |
"Player 1: " ^ p1 ^ " Player 2: " ^ p2 | |
let score_to_str = function | |
| Points (p_one, p_two) -> | |
score_line (point_to_str p_one) (point_to_str p_two) | |
| Forty (player_w_forty, other) -> | |
if is_player_one player_w_forty then score_line "40" (point_to_str other) | |
else score_line (point_to_str other) "40" | |
| Duece -> | |
"At duece" | |
| Advantage (player) -> | |
"Advantage " ^ player_to_str player | |
| GameOver (player) -> | |
"Game over! " ^ player_to_str player ^ " has won." | |
(* "Test" scenarios *) | |
let scenario_one_player1_kills start_game = | |
let score_1 = player_scored new_game PlayerOne in | |
let score_2 = player_scored score_1 PlayerOne in | |
let score_3 = player_scored score_2 PlayerOne in | |
let score_4 = player_scored score_3 PlayerOne in | |
"START\n" ^ | |
(score_to_str start_game) ^ "\n" ^ | |
(score_to_str score_1) ^ "\n" ^ | |
(score_to_str score_2) ^ "\n" ^ | |
(score_to_str score_3) ^ "\n" ^ | |
(score_to_str score_4) ^ "\n" ^ | |
"END" | |
let scenario_two_good_game start_game = | |
let score_1 = player_scored new_game PlayerOne in | |
let score_2 = player_scored score_1 PlayerOne in | |
let score_3 = player_scored score_2 PlayerOne in | |
let score_4 = player_scored score_3 PlayerTwo in | |
let score_5 = player_scored score_4 PlayerTwo in | |
let score_6 = player_scored score_5 PlayerTwo in | |
let score_7 = player_scored score_6 PlayerTwo in | |
let score_8 = player_scored score_7 PlayerOne in | |
let score_9 = player_scored score_8 PlayerOne in | |
let score_10 = player_scored score_9 PlayerOne in | |
"START (scenario_two_good_game)\n" ^ | |
(score_to_str start_game) ^ "\n" ^ | |
(score_to_str score_1) ^ "\n" ^ | |
(score_to_str score_2) ^ "\n" ^ | |
(score_to_str score_3) ^ "\n" ^ | |
(score_to_str score_4) ^ "\n" ^ | |
(score_to_str score_5) ^ "\n" ^ | |
(score_to_str score_6) ^ "\n" ^ | |
(score_to_str score_7) ^ "\n" ^ | |
(score_to_str score_8) ^ "\n" ^ | |
(score_to_str score_9) ^ "\n" ^ | |
(score_to_str score_10) ^ "\n" ^ | |
"END" | |
let () = | |
print_endline (scenario_one_player1_kills new_game) | |
let () = | |
print_endline (scenario_two_good_game new_game) | |
(* | |
DEBUGGIN' | |
print_endline (score_to_str (Points(Love, Love)));; | |
print_endline (score_to_str (Points(Love, Fifteen)));; | |
print_endline (score_to_str (Forty(PlayerOne, Fifteen)));; | |
print_endline (score_to_str (Forty(PlayerTwo, Thirty)));; | |
print_endline (score_to_str (Advantage(PlayerTwo)));; | |
print_endline (score_to_str (Advantage(PlayerOne)));; | |
print_endline (score_to_str (GameOver(PlayerOne)));; | |
print_endline (score_to_str (transition_to_forty (Points(Love, Fifteen)) PlayerOne));; | |
print_endline (score_to_str (transition_to_forty (Points(Love, Fifteen)) PlayerTwo));; | |
print_endline (score_to_str (transition_to_duece (Forty(PlayerOne, Fifteen))));; | |
print_endline (score_to_str (transition_to_advantage (Duece) PlayerOne));; | |
print_endline (score_to_str (transition_to_advantage (Duece) PlayerTwo));; | |
print_endline (score_to_str (transition_to_gameover (Advantage(PlayerTwo)) PlayerTwo));; | |
print_endline (score_to_str (transition_to_gameover (Advantage(PlayerOne)) PlayerTwo));; | |
print_endline (score_to_str (transition_to_gameover (Forty(PlayerTwo, Love)) PlayerTwo));; | |
print_endline (score_to_str (transition_to_gameover (Forty(PlayerOne, Fifteen)) PlayerTwo));; | |
*) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment