Watch Code Kata

Download Code Kata

List of Katas

Kata: Tennisgame

Immutable Tennisgame

  • Framework: csharp.nunit
  • Author: Morten Røgenes
  • Twitter: @NoHuman

Final Solution

========== Tennisgame.cs ==========

using System;
using NUnit.Framework;

[TestFixture]
public class TennisgameTest
{
    private Tennisgame _game;

    [SetUp]
    public void SetUp()
    {
        _game = new Tennisgame();
    }

    [Test]
    public void TestInitiationNotNull()
    {
        Assert.That(_game, Is.Not.Null);
    }

    [Test]
    public void TestInitialScoreIsLoveAll()
    {
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Love-All"));
    }
    [Test]
    public void TestServerScoresThenScoreIsFifteenLove()
    {
        _game = _game.ScoreServer();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Fifteen-Love"));
    }
    [Test]
    public void TestRecieverScoresThenScoreIsLoveFifteen()
    {
        _game = _game.ScoreReciever();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Love-Fifteen"));
    }
    [Test]
    public void TestBothPlayersScoresThenScoreIsFifteenAll()
    {
        _game = _game.ScoreServer();
        _game = _game.ScoreReciever();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Fifteen-All"));
    }
    [Test]
    public void TestServerScoresTwiceThenScoreIsThirtyLove()
    {
        _game = _game.ScoreServer();
        _game = _game.ScoreServer();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Thirty-Love"));
    }
    [Test]
    public void TestBothPlayersScoresTwiceThenScoreIsThirtyAll()
    {
        _game = _game.ScoreServer();
        _game = _game.ScoreServer();
        _game = _game.ScoreReciever();
        _game = _game.ScoreReciever();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Thirty-All"));
    }
    [Test]
    public void TestRecieverScoresThreeTimesThenScoreIsLoveForty()
    {
        _game = _game.ScoreReciever();
        _game = _game.ScoreReciever();
        _game = _game.ScoreReciever();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Love-Forty"));
    }
    [Test]
    public void TestBothPlayersScoresThreeTimesThenScoreIsDeuce()
    {
        for (var i = 0; i < 3; ++i)
        {
            _game = _game.ScoreServer();
            _game = _game.ScoreReciever();
        }
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Deuce"));
    }
    [Test]
    public void TestThatServerScoresFourTimesThenServerIsWinner()
    {
        for (var i = 0; i < 4; i++)
        {
            _game = _game.ScoreServer();
        }
        var winner = _game.GetWinner();
        Assert.That(winner, Is.EqualTo("Server"));
    }
    [Test]
    public void TestThatServerScoresFourTimesThenScoreIsGame()
    {
        for (var i = 0; i < 4; i++)
        {
            _game = _game.ScoreServer();
        }
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Game"));
    }
    [Test]
    public void TestThatRecieverScoresFourTimesThenScoreIsGame()
    {
        for (var i = 0; i < 4; i++)
        {
            _game = _game.ScoreReciever();
        }
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Game"));
    }
    [Test]
    public void TestThatRecieverScoresFourTimesThenWinnerIsReciever()
    {
        for (var i = 0; i < 4; i++)
        {
            _game = _game.ScoreReciever();
        }
        var winner = _game.GetWinner();
        Assert.That(winner, Is.EqualTo("Reciever"));
    }
    [Test]
    public void TestInitialWinnerIsNull()
    {
        var winner = _game.GetWinner();
        Assert.That(winner, Is.Null);
    }
    [Test, ExpectedException]
    public void TestThatNoMorePointsIsAllowedAfterGame()
    {
        for (var i = 0; i < 4; i++)
        {
            _game = _game.ScoreReciever();
        }
        _game = _game.ScoreServer();
    }
    [Test]
    public void TestBothPlayersScoresFourTimesThenScoreIsDeuce()
    {
        for (var i = 0; i < 4; ++i)
        {
            _game = _game.ScoreServer();
            _game = _game.ScoreReciever();
        }
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Deuce"));
    }
    [Test]
    public void TestServerScoresFourTimesAndRecieverScoresThreeThenTheScoreIsAdvantageIn()
    {
        for (var i = 0; i < 3; ++i)
        {
            _game = _game.ScoreServer();
            _game = _game.ScoreReciever();
        }
        _game = _game.ScoreServer();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Advantage In"));
    }
    [Test]
    public void TestServerScoresFourTimesAndRecieverScoresThreeThenTheWinnerIsNull()
    {
        for (var i = 0; i < 3; ++i)
        {
            _game = _game.ScoreServer();
            _game = _game.ScoreReciever();
        }
        _game = _game.ScoreServer();
        var winner = _game.GetWinner();
        Assert.That(winner, Is.Null);
    }
    [Test]
    public void TestServerScoresThreeTimesAndRecieverScoresFourThenTheScoreIsAdvantageOut()
    {
        for (var i = 0; i < 3; ++i)
        {
            _game = _game.ScoreServer();
            _game = _game.ScoreReciever();
        }
        _game = _game.ScoreReciever();
        var score = _game.GetCurrentScore();
        Assert.That(score, Is.EqualTo("Advantage Out"));
    }
}

public class Tennisgame
{
    private readonly int _serverScore;
    private readonly int _recieverScore;
    private readonly string _winner;

    public Tennisgame()
    {

    }
    private Tennisgame(int serverScore, int recieverScore)
    {
        _serverScore = serverScore;
        _recieverScore = recieverScore;
        if (_serverScore > 3 && _serverScore - _recieverScore >= 2)
        {
            _winner = "Server";
        }
        else if (_recieverScore > 3 && _recieverScore - _serverScore >= 2)
        {
            _winner = "Reciever";
        }
    }

    public string GetCurrentScore()
    {
        if (_winner != null)
        {
            return "Game";
        }
        if (_recieverScore == _serverScore && _recieverScore >= 3)
        {
            return "Deuce";
        }
        if (_serverScore >= 3 && _recieverScore >= 3)
        {
            return "Advantage " + (_serverScore > _recieverScore ? "In" : "Out");
        }
        string server = ConvertScore(_serverScore);
        string reciever = _recieverScore == _serverScore ? "All" : ConvertScore(_recieverScore);
        return string.Format("{0}-{1}", server, reciever);
    }

    private static string ConvertScore(int score)
    {
        switch (score)
        {
            case 0:
                return "Love";
            case 1:
                return "Fifteen";
            case 2:
                return "Thirty";
            case 3:
                return "Forty";
            default:
                return "";
        }
    }

    public Tennisgame ScoreServer()
    {
        if (_winner != null)
        {
            throw new Exception();
        }
        return new Tennisgame(_serverScore + 1, _recieverScore);
    }

    public Tennisgame ScoreReciever()
    {
        if (_winner != null)
        {
            throw new Exception();
        }
        return new Tennisgame(_serverScore, _recieverScore + 1);
    }

    public string GetWinner()
    {
        return _winner;
    }
}

Statistics

Framework Started Number of Moves Duration Number of modifications
kata per move kata per move
csharp.nunit 25-Aug-2011, 12:22:02 PM 53 63m 33s 72 seconds 501 9.5
Chart?chtt=seconds+per+move&cht=bvg&chxt=x,y&chbh=a,0,2&chs=600x200&chxr=1,0,285.0&chds=0,285.0&chco=ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000|ff0000&chd=t:71.0,69.0,12.0,235.0,150.0,110.0,109.0,164.0,15.0,44.0,100.0,36.0,94.0,285.0,87.0,197.0,90.0,28.0,99.0,17.0,72.0,19.0,57.0,100.0,25.0,28.0,48.0,25.0,33.0,240.0,19.0,34.0,40.0,41.0,12.0,43.0,34.0,59.0,39.0,28.0,76.0,86.0,59.0,44.0,20.0,58.0,121.0,106.0,39.0,33.0,24.0,23.0,116

Longest three moves

Duration in seconds Move
285 14 Goto move
240 30 Goto move
235 4 Goto move

Sharing

Link to Kata: http://codersdojo.org/statistics/4ae427402f8a7f2cebc66e8432415815cc9de3ab

Short link to Kata: http://bit.ly/qCBJQf

@