rewrite command parser

This commit is contained in:
2023-10-13 21:26:00 +08:00
parent 485e049532
commit f08249c350

View File

@ -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