#include #include #include #include #include #include using namespace std; const int EXIT_AC = 42; const int EXIT_WA = 43; std::ifstream input, judgeans; FILE * judgemessage = NULL; void wrong_answer (const char * err, ...) { va_list pvar; va_start(pvar, err); fprintf(judgemessage, "Wrong answer\n"); vfprintf(judgemessage, err, pvar); fprintf(judgemessage, "\n"); exit(EXIT_WA); } void judge_error (const char * err, ...) { va_list pvar; va_start(pvar, err); // If judgemessage hasn't been set up yet, write error to stderr if (!judgemessage) judgemessage = stderr; vfprintf(judgemessage, err, pvar); fprintf(judgemessage, "\n"); assert(!"Judge Error"); } template void openfile (Stream & stream, const char * file, const char * whoami) { stream.open(file); if (stream.fail()) judge_error("%s: failed to open %s\n", whoami, file); } FILE * openfeedback (const char * feedbackdir, const char * feedback, const char * whoami) { std::string path = std::string(feedbackdir) + "/" + std::string(feedback); FILE * res = fopen(path.c_str(), "w"); if (!res) judge_error("%s: failed to open %s for writing", whoami, path.c_str()); return res; } const char * USAGE = "Usage: %s judge_in judge_ans feedback_file [options] < team_out"; #include using namespace std; typedef long long int ll; typedef pair pii; bool R(){return true;} template bool R(T & x, Args & ... args){return cin >> x && R(args...);} void init_io(){ios::sync_with_stdio(false);cin.tie(0);} #define PB push_back #define FOR(prom, a, b) for(int prom = (a); prom < (b); prom++) #define FORDE(prom, a, b) for(int prom = (a); prom >= (b); prom--) #define ALL(vec) (vec).begin(), (vec).end() #define MM(co, cim) memset((co), (cim), sizeof((co))) #define DEB(x) cerr << ">>> " << #x << " : " << x << endl; #define INF 1000000007 #define INFLL 4000000000000000007LL int n; char piece, b[114][114]; void read_input (void) { if (!(input >> n >> piece)) judge_error("Could not read input"); FOR(i, 0, n) FOR(j, 0, n) if (!(input >> b[i][j])) judge_error("Could not read input"); } bool positive_answer; void check_result (void) { string judgeres, teamres; //read judge result if (!getline(judgeans, judgeres)) judge_error("Could not read judge result"); //read team result if (!getline(cin, teamres)) wrong_answer("Could not read team result - empty file"); if (judgeres != teamres) wrong_answer("Result mismatch JUDGE: %s != TEAM: %s", judgeres.c_str(), teamres.c_str()); positive_answer = (judgeres == "YES"); } int from_x, from_y, to_x, to_y, live_pieces; void check_move (void) { if (from_x < 0 || from_x >= n || from_y < 0 || from_y >= n) wrong_answer("FROM position (%d, %d) is out of bounds", from_x + 1, from_y + 1); if (to_x < 0 || to_x >= n || to_y < 0 || to_y >= n) wrong_answer("TO position (%d, %d) is out of bounds", to_x + 1, to_y + 1); if (from_x == to_x && from_y == to_y) wrong_answer("Piece cannot take itself at position (%d, %d)", from_x + 1, from_y + 1); if (b[from_x][from_y] != piece) wrong_answer("There is no piece at FROM position (%d, %d)", from_x + 1, from_y + 1); if (b[to_x][to_y] != piece) wrong_answer("There is no piece at TO position (%d, %d)", to_x + 1, to_y + 1); int diff_x = to_x - from_x; int diff_y = to_y - from_y; bool valid_piece_move = false; switch (piece) { case 'K': valid_piece_move = (diff_x >= -1 && diff_x <= 1 && diff_y >= -1 && diff_y <= 1); break; case 'Q': valid_piece_move = (!diff_x || !diff_y || abs(diff_x) == abs(diff_y)); break; case 'R': valid_piece_move = (!diff_x || !diff_y); break; case 'B': valid_piece_move = (abs(diff_x) == abs(diff_y)); break; case 'N': valid_piece_move = ((abs(diff_x) == 2 && abs(diff_y) == 1) || (abs(diff_x) == 1 && abs(diff_y) == 2)); break; } if (!valid_piece_move) wrong_answer("Move (%d, %d) -> (%d, %d) is not a valid chess move for piece %c", from_x + 1, from_y + 1, to_x + 1, to_y + 1, piece); } void do_move (void) { b[from_x][from_y] = '.'; --live_pieces; } void check_answer (void) { live_pieces = 0; FOR(i, 0, n) FOR(j, 0, n) if (b[i][j] == piece) ++live_pieces; while (live_pieces > 1) { if (!(cin >> from_x >> from_y >> to_x >> to_y)) wrong_answer("Could not read movement data, but there are still %d live pieces", live_pieces); --from_x;--from_y;--to_x;--to_y; check_move(); do_move(); } } int main (int argc, char * argv[]) { judgemessage = openfeedback(argv[3], "judgemessage.txt", argv[0]); if (argc < 4) judge_error(USAGE, argv[0]); openfile(input, argv[1], argv[0]); openfile(judgeans, argv[2], argv[0]); //read input read_input(); //check team result (e.g. YES/NO, or size of solution on a single line) check_result(); if (positive_answer) { //check answer constructed by team check_answer(); } char c; if (cin >> c) wrong_answer("Garbage at the end of file"); exit(EXIT_AC); }