Anterior
Próximo
Coding Dojo Partida de Tenispublicado em 12/02/2010
Recentemente postei aqui no site a resolução
do problema FizzBuzz usando TDD sugerido no Dojo do .Net
Architects.
Caso você tenha assistido ao vídeo até o final, pôde
perceber que por falta de tempo, o problema do Jogo de Tênis não foi resolvido. Por este motivo estou postando aqui a minha solução.
O Objetivo do problema é simular uma partida de tênis simples com apenas um game, onde os jogadores podem pontuar e trocar vantagens até o fim do jogo.
Segue as regras:
- Todos os jogadores podem pontuar, a ordem de pontuação é 0,15,30,40 pontos.
- Um jogador com 40 pontos, ganha o jogo sem precisar de vantagem caso marque mais um ponto e seu oponente tenha menos de 40 pontos.
- Um jogador ganha a vantagem caso marque ponto e seu oponente possua 40 pontos.
- Um jogador perde a vantagem caso seu oponente pontue.
- Se um jogador com vantagem pontuar, ganha o jogo.
Comecei com testes básicos e fui avançando ponto a ponto, ao fim do problema eles ficaram assim:
[TestClass]
public class Dada_Uma_Partida_De_Tenis
{
[TestMethod]
public void Ao_Iniciar_Partida_A_Pontuacao_Esta_Zerada()
{
PartidaDeTenis partida = new PartidaDeTenis();
Assert.AreEqual(Pontos.Zero, partida.Jogador1.Pontuacao);
Assert.AreEqual(Pontos.Zero, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P1_Pontua_1x_E_Sua_Pontuacao_Fica_15()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
Assert.AreEqual(Pontos.Quinze, partida.Jogador1.Pontuacao);
}
[TestMethod]
public void P1_Pontua_2x_E_Sua_Pontuacao_Fica_30()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
partida.PontuarJogador1();
Assert.AreEqual(Pontos.Trinta, partida.Jogador1.Pontuacao);
}
[TestMethod]
public void P2_Pontua_1x_E_Sua_Pontuacao_Fica_15()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Quinze, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P2_Pontua_2x_E_Sua_Pontuacao_Fica_30()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Trinta, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P2_Pontua_3x_E_Sua_Pontuacao_Fica_40()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Quarenta, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P1_Pontua_4x_P2_Nao_Pontua_P1_Ganha_O_Jogo()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
Assert.AreEqual(Pontos.Ganhou, partida.Jogador1.Pontuacao);
}
[TestMethod]
public void P2_Pontua_4x_P1_Nao_Pontua_P2_Ganha()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Ganhou, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P1_Possui_40_Pontos_P2_Possui_40_Pontos_Entao_P1_Ao_Pontuar_Ganha_Vantagem()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
Assert.AreEqual(Pontos.Vantagem, partida.Jogador1.Pontuacao);
}
[TestMethod]
public void P1_Possui_Vantagem_Entao_P1_Ao_Pontuar_Ganha_O_Jogo()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador1();
Assert.AreEqual(Pontos.Ganhou, partida.Jogador1.Pontuacao);
}
[TestMethod]
public void P1_Possui_Vantagem_P2_Pontua_Entao_P1_Perde_Vantagem()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Quarenta, partida.Jogador1.Pontuacao);
}
[TestMethod]
public void P2_Possui_40_Pontos_P1_Possui_40_Pontos_Entao_P2_Ao_Pontuar_Ganha_Vantagem()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Vantagem, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P2_Possui_Vantagem_P2_Ao_Pontuar_Ganha_O_Jogo()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Ganhou, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void P2_Possui_Vantagem_P1_Pontua_Entao_P2_Perde_Vantagem()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador1();
Assert.AreEqual(Pontos.Quarenta, partida.Jogador2.Pontuacao);
}
[TestMethod]
public void Partida_Completa_Com_Troca_De_Vantagens_Onde_P2_Ganha()
{
PartidaDeTenis partida = new PartidaDeTenis();
partida.PontuarJogador1();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador1();
partida.PontuarJogador2();
partida.PontuarJogador2();
Assert.AreEqual(Pontos.Ganhou, partida.Jogador2.Pontuacao);
}
}
Depois de muitos testes e refatorações cheguei ao código abaixo, acho que ainda poderia melhorar o método Pontuar() diminuindo o número de Ifs, mas como o
tempo estava curto deixei para uma outra oportunidade:
public class PartidaDeTenis
{
public Jogador Jogador1 { get; private set; }
public Jogador Jogador2 { get; private set; }
public PartidaDeTenis()
{
// Iniciando jogadores da partida
this.Jogador1 = new Jogador();
this.Jogador2 = new Jogador();
}
public void PontuarJogador1()
{
this.Pontuar(Jogador1, Jogador2);
}
public void PontuarJogador2()
{
this.Pontuar(Jogador2, Jogador1);
}
private void Pontuar(Jogador jogadorPontuador, Jogador jogadorPontuado)
{
if (jogadorPontuador.TemVantagem)
jogadorPontuador.Pontuacao = Pontos.Ganhou;
else
{
if (jogadorPontuado.TemVantagem)
jogadorPontuado.Pontuacao = Pontos.Quarenta;
else
{
// verifica se é necessário dar vantagem
if (jogadorPontuador.Pontuacao.Equals(Pontos.Quarenta) && jogadorPontuado.Pontuacao.Equals(Pontos.Quarenta))
jogadorPontuador.Pontuacao = Pontos.Vantagem;
else
{
switch (jogadorPontuador.Pontuacao)
{
case Pontos.Zero:
jogadorPontuador.Pontuacao = Pontos.Quinze;
break;
case Pontos.Quinze:
jogadorPontuador.Pontuacao = Pontos.Trinta;
break;
case Pontos.Trinta:
jogadorPontuador.Pontuacao = Pontos.Quarenta;
break;
case Pontos.Quarenta:
jogadorPontuador.Pontuacao = Pontos.Ganhou;
break;
}
}
}
}
}
}
public enum Pontos
{
Zero = 0,
Quinze = 15,
Trinta = 30,
Quarenta = 40,
Vantagem = 45,
Ganhou = 50
}
public class Jogador
{
public Pontos Pontuacao { get; set; }
public bool TemVantagem
{
get { return this.Pontuacao.Equals(Pontos.Vantagem); }
}
}
E você ? Fez o Dojo também ? Comente a minha solução e sugira novos problemas para que eu possa postar as soluções por aqui!
Faça o download da Solution com tudo funcionando:
Referencias úteis:
Tags: