rewrite command parser
This commit is contained in:
195
src/main.cpp
195
src/main.cpp
@ -118,13 +118,39 @@ namespace BackEnd {
|
|||||||
const int kMaxTeamNumber = 10005;
|
const int kMaxTeamNumber = 10005;
|
||||||
std::unordered_map<std::string, int> team_name_to_id;
|
std::unordered_map<std::string, int> team_name_to_id;
|
||||||
std::vector<std::string> team_id_to_name = {"nobody"};
|
std::vector<std::string> team_id_to_name = {"nobody"};
|
||||||
int team_number = 0;
|
|
||||||
enum CompetitionStatusType { kNotStarted, kNormalRunning, kFrozen, kEnded };
|
enum CompetitionStatusType { kNotStarted, kNormalRunning, kFrozen, kEnded };
|
||||||
enum SubmissionStatusType { kAC = 0, kWA = 1, kRE = 2, kTLE = 3 };
|
enum SubmissionStatusType { kAC = 0, kWA = 1, kRE = 2, kTLE = 3 };
|
||||||
|
enum CommandType {
|
||||||
|
kADDTEAM,
|
||||||
|
kSTART,
|
||||||
|
kSUBMIT,
|
||||||
|
kFLUSH,
|
||||||
|
kFREEZE,
|
||||||
|
kSCROLL,
|
||||||
|
kQUERY_RANKING,
|
||||||
|
kQUERY_SUBMISSION,
|
||||||
|
kEND
|
||||||
|
};
|
||||||
|
std::unordered_map<std::string, SubmissionStatusType> SubmitStatusParser = {
|
||||||
|
{"Accepted", kAC},
|
||||||
|
{"Wrong_Answer", kWA},
|
||||||
|
{"Runtime_Error", kRE},
|
||||||
|
{"Time_Limit_Exceed", kTLE}};
|
||||||
|
std::unordered_map<std::string, CommandType> CommandParser = {
|
||||||
|
{"ADDTEAM", kADDTEAM},
|
||||||
|
{"START", kSTART},
|
||||||
|
{"SUBMIT", kSUBMIT},
|
||||||
|
{"FLUSH", kFLUSH},
|
||||||
|
{"FREEZE", kFREEZE},
|
||||||
|
{"SCROLL", kSCROLL},
|
||||||
|
{"QUERY_RANKING", kQUERY_RANKING},
|
||||||
|
{"QUERY_SUBMISSION", kQUERY_SUBMISSION},
|
||||||
|
{"END", kEND}};
|
||||||
CompetitionStatusType competition_status = kNotStarted;
|
CompetitionStatusType competition_status = kNotStarted;
|
||||||
bool score_board_up_to_date = true;
|
bool score_board_up_to_date = true;
|
||||||
int competition_duration_time;
|
int competition_duration_time;
|
||||||
int total_number_of_problems;
|
int total_number_of_problems;
|
||||||
|
int team_number = 0;
|
||||||
/**
|
/**
|
||||||
* @brief the definition of struct RawTeamDataType
|
* @brief the definition of struct RawTeamDataType
|
||||||
*
|
*
|
||||||
@ -142,15 +168,21 @@ struct RawTeamDataType {
|
|||||||
std::set<int, std::greater<int>> unfreeze_pass_time;
|
std::set<int, std::greater<int>> unfreeze_pass_time;
|
||||||
int query_status_index[4], query_problem_index[26],
|
int query_status_index[4], query_problem_index[26],
|
||||||
query_problem_status_index[26][4];
|
query_problem_status_index[26][4];
|
||||||
|
// as index in submissions are 0 based, so we use -1 to indicate that the team
|
||||||
|
// has not submitted a problem satisfying the query condition.
|
||||||
bool is_frozen[26] = {false};
|
bool is_frozen[26] = {false};
|
||||||
std::vector<SubmissionStatusType> submissions;
|
std::vector<SubmissionStatusType> submissions;
|
||||||
RawTeamDataType() { ; }
|
RawTeamDataType() { ; }
|
||||||
};
|
};
|
||||||
std::vector<RawTeamDataType> team_data = {RawTeamDataType()};
|
std::vector<RawTeamDataType> team_data = {RawTeamDataType()};
|
||||||
|
// warning: team_data[0] has no meaning
|
||||||
struct ScoreBoredElementType {
|
struct ScoreBoredElementType {
|
||||||
int tid;
|
int tid;
|
||||||
int score;
|
int score;
|
||||||
int penalty;
|
int penalty;
|
||||||
|
ScoreBoredElementType() {}
|
||||||
|
ScoreBoredElementType(int tid, int score, int penalty)
|
||||||
|
: tid(tid), score(score), penalty(penalty) {}
|
||||||
};
|
};
|
||||||
inline bool operator<(const ScoreBoredElementType &a,
|
inline bool operator<(const ScoreBoredElementType &a,
|
||||||
const ScoreBoredElementType &b) {
|
const ScoreBoredElementType &b) {
|
||||||
@ -186,6 +218,16 @@ void AddTeam(const char *const team_name) {
|
|||||||
team_number++;
|
team_number++;
|
||||||
team_name_to_id[team_name] = team_number;
|
team_name_to_id[team_name] = team_number;
|
||||||
team_id_to_name.push_back(team_name);
|
team_id_to_name.push_back(team_name);
|
||||||
|
team_data.push_back(RawTeamDataType());
|
||||||
|
team_data[team_number].name = team_name;
|
||||||
|
team_data[team_number].id = team_number;
|
||||||
|
/*update three index to -1*/
|
||||||
|
for (int i = 0; i < 4; i++) team_data[team_number].query_status_index[i] = -1;
|
||||||
|
for (int i = 0; i < 26; i++) {
|
||||||
|
team_data[team_number].query_problem_index[i] = -1;
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
team_data[team_number].query_problem_status_index[i][j] = -1;
|
||||||
|
}
|
||||||
write("[Info]Team added.\n");
|
write("[Info]Team added.\n");
|
||||||
}
|
}
|
||||||
void StartCompetition(int duration_time, int problem_count) {
|
void StartCompetition(int duration_time, int problem_count) {
|
||||||
@ -196,11 +238,27 @@ void StartCompetition(int duration_time, int problem_count) {
|
|||||||
competition_duration_time = duration_time;
|
competition_duration_time = duration_time;
|
||||||
total_number_of_problems = problem_count;
|
total_number_of_problems = problem_count;
|
||||||
competition_status = kNormalRunning;
|
competition_status = kNormalRunning;
|
||||||
|
/*init the score board*/
|
||||||
|
for (int i = 1; i <= team_number; i++) {
|
||||||
|
score_board.insert(ScoreBoredElementType(i, 0, 0));
|
||||||
|
}
|
||||||
write("[Info]Competition starts.\n");
|
write("[Info]Competition starts.\n");
|
||||||
}
|
}
|
||||||
inline void Submit(char problem_name, char *team_name, char *submit_status,
|
inline void Submit(char problem_name, char *team_name,
|
||||||
int time) {
|
const char *submit_status, int time) {
|
||||||
;
|
int team_id = team_name_to_id[team_name];
|
||||||
|
SubmissionStatusType status = SubmitStatusParser[submit_status];
|
||||||
|
switch(status)
|
||||||
|
{
|
||||||
|
case kAC:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kRE: case kWA: case kTLE:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void FlushScoreBoard() { ; }
|
void FlushScoreBoard() { ; }
|
||||||
void FreezeScoreBoard() { competition_status = kFrozen; }
|
void FreezeScoreBoard() { competition_status = kFrozen; }
|
||||||
@ -238,19 +296,37 @@ inline void StartCompetition(int duration_time, int problem_count) {
|
|||||||
}
|
}
|
||||||
inline void Submit(char problem_name, char *team_name, char *submit_status,
|
inline void Submit(char problem_name, char *team_name, char *submit_status,
|
||||||
int time) {
|
int time) {
|
||||||
|
if (BackEnd::competition_status == BackEnd::kNotStarted)
|
||||||
|
throw "Competition hasn't started yet.";
|
||||||
BackEnd::Submit(problem_name, team_name, submit_status, time);
|
BackEnd::Submit(problem_name, team_name, submit_status, time);
|
||||||
}
|
}
|
||||||
inline void FlushScoreBoard() { BackEnd::FlushScoreBoard(); }
|
inline void FlushScoreBoard() {
|
||||||
|
if (BackEnd::competition_status == BackEnd::kNotStarted)
|
||||||
|
throw "Competition hasn't started yet.";
|
||||||
|
BackEnd::FlushScoreBoard();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief the definition of function FreezeScoreBoard
|
* @brief the definition of function FreezeScoreBoard
|
||||||
*/
|
*/
|
||||||
inline void FreezeScoreBoard() { ICPCManager::BackEnd::FreezeScoreBoard(); }
|
inline void FreezeScoreBoard() {
|
||||||
inline void ScrollScoreBoard() { ICPCManager::BackEnd::ScrollScoreBoard(); }
|
if (BackEnd::competition_status == BackEnd::kNotStarted)
|
||||||
|
throw "Competition hasn't started yet.";
|
||||||
|
ICPCManager::BackEnd::FreezeScoreBoard();
|
||||||
|
}
|
||||||
|
inline void ScrollScoreBoard() {
|
||||||
|
if (BackEnd::competition_status == BackEnd::kNotStarted)
|
||||||
|
throw "Competition hasn't started yet.";
|
||||||
|
ICPCManager::BackEnd::ScrollScoreBoard();
|
||||||
|
}
|
||||||
inline void QueryRanking(char *team_name) {
|
inline void QueryRanking(char *team_name) {
|
||||||
|
if (BackEnd::competition_status == BackEnd::kNotStarted)
|
||||||
|
throw "Competition hasn't started yet.";
|
||||||
ICPCManager::BackEnd::QueryRanking(team_name);
|
ICPCManager::BackEnd::QueryRanking(team_name);
|
||||||
}
|
}
|
||||||
inline void QuerySubmission(char *team_name, char problem_name,
|
inline void QuerySubmission(char *team_name, char problem_name,
|
||||||
char *submit_status) {
|
char *submit_status) {
|
||||||
|
if (BackEnd::competition_status == BackEnd::kNotStarted)
|
||||||
|
throw "Competition hasn't started yet.";
|
||||||
ICPCManager::BackEnd::QuerySubmission(team_name, problem_name, submit_status);
|
ICPCManager::BackEnd::QuerySubmission(team_name, problem_name, submit_status);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -269,47 +345,70 @@ void EndContest() {
|
|||||||
inline void Excute(const char *const command) {
|
inline void Excute(const char *const command) {
|
||||||
char command_name[1024];
|
char command_name[1024];
|
||||||
sscanf(command, "%s", command_name);
|
sscanf(command, "%s", command_name);
|
||||||
if (strcmp(command_name, "ADDTEAM") == 0) { // add a team
|
ICPCManager::BackEnd::CommandType command_type =
|
||||||
char team_name[100];
|
ICPCManager::BackEnd::CommandParser[command_name];
|
||||||
sscanf(command, "%*s%s", team_name);
|
switch (command_type) {
|
||||||
ICPCManager::API::AddTeam(team_name);
|
case ICPCManager::BackEnd::kADDTEAM: {
|
||||||
} else if (strcmp(command_name, "START") == 0) { // start the contest
|
char team_name[100];
|
||||||
int duration_time, problem_count, paramater_count;
|
sscanf(command, "%*s%s", team_name);
|
||||||
paramater_count =
|
ICPCManager::API::AddTeam(team_name);
|
||||||
sscanf(command, "%*s%*s%d%*s%d", &duration_time, &problem_count);
|
break;
|
||||||
if (paramater_count != 2) throw "Invalid paramaters.";
|
}
|
||||||
ICPCManager::API::StartCompetition(duration_time, problem_count);
|
case ICPCManager::BackEnd::kSTART: {
|
||||||
} else if (strcmp(command_name, "SUBMIT") == 0) { // submit a code
|
int duration_time, problem_count, paramater_count;
|
||||||
char problem_name;
|
paramater_count =
|
||||||
char team_name[100];
|
sscanf(command, "%*s%*s%d%*s%d", &duration_time, &problem_count);
|
||||||
char submit_status[10];
|
if (paramater_count != 2) throw "Invalid paramaters.";
|
||||||
int time;
|
ICPCManager::API::StartCompetition(duration_time, problem_count);
|
||||||
sscanf(command, "%*s%c%*s%s%*s%s%*s%d", &problem_name, team_name,
|
break;
|
||||||
submit_status, &time);
|
}
|
||||||
ICPCManager::API::Submit(problem_name, team_name, submit_status, time);
|
case ICPCManager::BackEnd::kSUBMIT: {
|
||||||
} else if (strcmp(command_name, "FLUSH") == 0) {
|
char problem_name;
|
||||||
/*flush the score_board*/
|
char team_name[100];
|
||||||
ICPCManager::API::FlushScoreBoard();
|
char submit_status[10];
|
||||||
} else if (strcmp(command_name, "FREEZE") == 0) {
|
int time;
|
||||||
/*freeze the score_board*/
|
sscanf(command, "%*s%c%*s%s%*s%s%*s%d", &problem_name, team_name,
|
||||||
ICPCManager::API::FreezeScoreBoard();
|
submit_status, &time);
|
||||||
} else if (strcmp(command_name, "SCROLL") == 0) {
|
ICPCManager::API::Submit(problem_name, team_name, submit_status, time);
|
||||||
ICPCManager::API::ScrollScoreBoard();
|
break;
|
||||||
} else if (strcmp(command_name, "QUERY_RANKING") == 0) {
|
}
|
||||||
char team_name[100];
|
case ICPCManager::BackEnd::kFLUSH: {
|
||||||
sscanf(command, "%*s%s", team_name);
|
/*flush the score_board*/
|
||||||
ICPCManager::API::QueryRanking(team_name);
|
ICPCManager::API::FlushScoreBoard();
|
||||||
} else if (strcmp(command_name, "QUERY_SUBMISSION") == 0) {
|
break;
|
||||||
char team_name[100];
|
}
|
||||||
char problem_name;
|
case ICPCManager::BackEnd::kFREEZE: {
|
||||||
char status[10];
|
/*freeze the score_board*/
|
||||||
sscanf(command, "%*s%s%*s%*s%c%*s%*s%s", team_name, &problem_name, status);
|
ICPCManager::API::FreezeScoreBoard();
|
||||||
ICPCManager::API::QuerySubmission(team_name, problem_name, status);
|
break;
|
||||||
} else if (strcmp(command_name, "END") == 0) // END
|
}
|
||||||
{
|
case ICPCManager::BackEnd::kSCROLL: {
|
||||||
ICPCManager::API::EndContest();
|
ICPCManager::API::ScrollScoreBoard();
|
||||||
} else
|
break;
|
||||||
throw "Unknown command.";
|
}
|
||||||
|
case ICPCManager::BackEnd::kQUERY_RANKING: {
|
||||||
|
char team_name[100];
|
||||||
|
sscanf(command, "%*s%s", team_name);
|
||||||
|
ICPCManager::API::QueryRanking(team_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ICPCManager::BackEnd::kQUERY_SUBMISSION: {
|
||||||
|
char team_name[100];
|
||||||
|
char problem_name;
|
||||||
|
char status[10];
|
||||||
|
sscanf(command, "%*s%s%*s%*s%c%*s%*s%s", team_name, &problem_name,
|
||||||
|
status);
|
||||||
|
ICPCManager::API::QuerySubmission(team_name, problem_name, status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ICPCManager::BackEnd::kEND: {
|
||||||
|
ICPCManager::API::EndContest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw "Unknown command.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace API
|
} // namespace API
|
||||||
} // namespace ICPCManager
|
} // namespace ICPCManager
|
||||||
|
Reference in New Issue
Block a user