In this week, we did a coding kata, the subject is to select the top two teams of football group match results.
The requirements are listed below.
- The number of team is not limited.
- The score will be +3 when it wins, the score will be 0 if lose, otherwise the score is 1.
- Rule 1: The advanced team are the top two highest score teams.
- Rule 2: if the score is same, the advanced team is that who has the higher net goal.
- Rule 3: if the score and net goal are same, the advanced team is the more goal team.
- Rule 4: select two teams of group to advance
Below is my draft implementation without any comments and unit test after kata as it was not a success solution during the kata, just for record.
#ifndef TEAM_H_ #define TEAM_H_ #include <string> namespace HW { /** * @class TeamC * @brief */ class TeamC { public: /** * @brief Constructor */ TeamC(); TeamC(std::string iName); /** * @brief Destructor */ ~TeamC() = default; void AddMatch(uint8_t iScore, uint8_t iGoal, uint8_t iLose); std::string GetName(void); int GetScore(void); int GetNetGoal(void); bool operator<(const TeamC& iValue); private: std::string mName; int mScore; uint8_t mGoal; uint8_t mLose; }; } // end of namespace HW #endif /* TEAM_H_ */
#include "Team.h" namespace HW { TeamC::TeamC():mName(""), mScore(0), mGoal(0), mLose(0) { } TeamC::TeamC(std::string iName):mName(iName), mScore(0), mGoal(0), mLose(0) { } bool TeamC::operator<(const TeamC& iValue) { bool rt = false; //the first rule is to compare score if (mScore != iValue.mScore) { rt = mScore > iValue.mScore; } else { //if the score is equal, then compare the net goal when net goals are not identical if (mGoal - mLose != iValue.mGoal - iValue.mLose) { rt = mGoal - mLose > iValue.mGoal - iValue.mLose; } //only compare the goal else { rt = mGoal > iValue.mGoal; } } return rt; } int TeamC::GetScore(void) { return mScore; } int TeamC::GetNetGoal(void) { return mGoal - mLose; } void TeamC::AddMatch(uint8_t iScore, uint8_t iGoal, uint8_t iLose) { mScore += iScore; mGoal += iGoal; mLose += iLose; } std::string TeamC::GetName(void) { return mName; } } // end of namespace HW
#ifndef TEAMSELECTOR_H_ #define TEAMSELECTOR_H_ #include <iostream> #include <vector> #include <string> #include "Team.h" namespace HW { /** * @class ScoreC * @brief */ class TeamSelectorC { public: /** * @brief Constructor */ TeamSelectorC(); /** * @brief Destructor */ ~TeamSelectorC() = default; void AddMatch(std::string iTeam1, std::string iTeam2, uint8_t iGoal1, uint8_t iGoal2); std::vector<std::string> Select(void); /** * @brief Set copy constructor as delete to prevent unintentional creation */ TeamSelectorC(const TeamSelectorC& iValue) = delete; /** * @brief Set copy assignment as delete to prevent unintentional creation */ const TeamSelectorC& operator=(const TeamSelectorC& iValue) = delete; private: std::vector<TeamC> mTeams; private: TeamC& GetTeam(std::string iTeam); }; } // end of namespace HW #endif /* TEAMSELECTOR_H_ */
namespace HW { TeamSelectorC::TeamSelectorC() { } void TeamSelectorC::AddMatch(std::string iTeam1, std::string iTeam2, uint8_t iGoal1, uint8_t iGoal2) { TeamC& team1 = GetTeam(iTeam1); TeamC& team2 = GetTeam(iTeam2); if (iGoal1 > iGoal2) { team1.AddMatch(3, iGoal1, iGoal2); team2.AddMatch(0, iGoal2, iGoal1); } else if (iGoal1 == iGoal2) { team1.AddMatch(1, iGoal1, iGoal2); team2.AddMatch(1, iGoal2, iGoal1); } else { team1.AddMatch(0, iGoal1, iGoal2); team2.AddMatch(3, iGoal2, iGoal1); } } std::vector<std::string> TeamSelectorC::Select(void) { std::sort(mTeams.begin(), mTeams.end()); //debug only for (auto& team: mTeams) { std::cout << team.GetName() << "_" << team.GetScore() << "_" << team.GetNetGoal() << std::endl; } std::vector<std::string> results; if (mTeams.size() > 0) { results.push_back(mTeams[0].GetName()); } if (mTeams.size() > 1) { results.push_back(mTeams[1].GetName()); } return results; } TeamC& TeamSelectorC::GetTeam(std::string iTeam) { for (auto& team: mTeams) { if (team.GetName() == iTeam) { return team; } } TeamC tmp(iTeam); mTeams.push_back(tmp); return mTeams[mTeams.size() - 1]; } } // end of namespace HW
The test code
void TeamSelectTest(void) { HW::TeamSelectorC selector; selector.AddMatch("A", "B", 2, 1); selector.AddMatch("A", "C", 2, 1); selector.AddMatch("A", "D", 2, 1); selector.AddMatch("B", "C", 3, 1); selector.AddMatch("B", "D", 2, 1); selector.AddMatch("C", "D", 3, 1); std::vector<std::string> results = selector.Select(); for (auto result:results) { std::cout << result << std::endl; } }