Source

Kata Tennis C++ / src / Game.cpp


#include "Game.h"

#include <iostream>
#include "Player.h"
using namespace std;

Game::Game(Player * player1, Player * player2)
{
	this->player1 = player1;
	this->player2 = player2;

	scores.push_back("Love");
	scores.push_back("Fifteen");
	scores.push_back("Thirty");
	scores.push_back("Forty");

	setState(INITIAL);
}

Game::~Game()
{
	delete player1;
	delete player2;
}

void Game::pointTo(Player * player)
{
	if(not isOver())
	{
		player->winPoint();

		updateState();
	}
}

void Game::updateState()
{
	if(thereIsDeuce())
	{
		setState(DEUCE);
	}
	else if(getState() == DEUCE)
	{
		setState(ADVANTAGE);
	}
	else if(hasGameFinished())
	{
		setState(GAME_OVER);
	}
}

std::string Game::score() const
{
	std::string scoreMessage;

	switch(getState()) {
		case DEUCE:
			scoreMessage = "Deuce";
		break;

		case GAME_OVER:
			scoreMessage = victoryMessage();
		break;

		case ADVANTAGE:
			scoreMessage = advantageMessage();
		break;

		default:
			scoreMessage = computeScore(player1) + "-" + computeScore(player2);
		break;
	}

	return scoreMessage;
}

std::string Game::victoryMessage() const
{
	return whoWon()->getName() + " won!";
}

Player * Game::whoWon() const
{
	if(playerThatWonIs(player1))
		return player1;

	return player2;
}

std::string Game::advantageMessage() const
{
	std::string message = "Advantage for ";

	if(player1->getPoints() > player2->getPoints())
		return message + player1->getName();

	return message + player2->getName();
}

std::string Game::computeScore(Player * player) const
{
	return scores[player->getPoints()];
}

bool Game::thereIsDeuce() const
{
	return playersAreTight() and player1->getPoints() >= 3;
}

bool Game::playersAreTight() const
{
	return player1->getPoints() == player2->getPoints();
}

bool Game::isOver() const
{
	return getState() == GAME_OVER;
}

bool Game::hasGameFinished() const
{
	return playerThatWonIs(player1) or playerThatWonIs(player2);
}

bool Game::playerThatWonIs(Player * player) const
{
	if(getState() == INITIAL)
		return player->wonMoreThanThreePoints();

	return player->getPoints() > getOtherPlayer(player)->getPoints();
}

Player * Game::getOtherPlayer(Player * player) const
{
	if(player == player1)
		return player2;

	return player1;
}

GameState Game::getState() const
{
	return state;
}

void Game::setState(GameState state)
{
	this->state = state;
}