dgv

Code Kata: Tennis


I have started doing code katas, inspired by a video Emily Bache did at the Modern Software Engineering YouTube channel (video). These are actually quite fun, and I have found them to be a neat way to get into Test Driven Development.

Here is my solution for the Tennis code kata (link):

import pytest


def get_game_score(p1, p2):
    if (p1 > p2 + 2) and (p2 > 3):
        raise ValueError("Impossible score")
    if (p1 > 4) and (p2 < 3):
        raise ValueError("Impossible score")

    score_map = {0: "Love", 1: "Fifteen", 2: "Thirty", 3: "Forty"}
    if p1 < 3 and p2 < 3:
        return f"{score_map[p1]}-{score_map[p2]}"
    if (p1 == 4) and (p2 < 3):
        return "Victory P1"
    if (p2 == 4) and (p1 < 3):
        return "Victory P2"
    if (p1 == p2) and p1 >= 3:
        return "Deuce"
    if (p1 > p2) and (p1 <= p2 + 1) and p2 >= 3:
        return "Advantage P1"
    if (p2 > p1) and (p2 <= p1 + 1) and p1 >= 3:
        return "Advantage P2"
    if (p1 > p2) and (p1 == p2 + 2) and p2 >= 3:
        return "Victory P1"
    if (p2 > p1) and (p2 == p1 + 2) and p1 >= 3:
        return "Victory P2"


@pytest.mark.parametrize(
    "p1, p2, expected",
    [
        (0, 0, "Love-Love"),  # p1==p2==0
        (0, 1, "Love-Fifteen"),  # p2 > p1
        (1, 0, "Fifteen-Love"),  # p1 > p2
        (2, 2, "Thirty-Thirty"),  # p1==p2==2
        (3, 3, "Deuce"),  # p1==p2==3
        (4, 3, "Advantage P1"),  # p1>p2>=3
        (3, 4, "Advantage P2"),  # p2>p1>=3
        (4, 0, "Victory P1"),  # P1 won
        (0, 4, "Victory P2"),  # P2 won
        (5, 3, "Victory P1"),  # P1 won after adv
        (7, 5, "Victory P1"),  # P1 won after adv
        (4, 6, "Victory P2"),  # P2 won after adv
    ],
)
def test_scores(p1, p2, expected):
    assert get_game_score(p1, p2) == expected


def test_impossible_score_before_Deuce():
    with pytest.raises(ValueError):
        get_game_score(5, 2)  # p1 > 4 and p<3 -- Should have won before


def test_impossible_score_after_Deuce():
    with pytest.raises(ValueError):
        get_game_score(7, 4)  # p1 > p2+2 and p2>3 -- Should have won before