hustoj—添加测试点下载功能

学校oj的判题系统再一次崩溃了,在测试某些程序时一直显示判题状态。从github上更新了判题程序,实现测试点下载功能的程序也就需要重新修改了。

现将需要注意的点记录如下,用作备忘。

1.修改数据库

在数据库的solution表中添加两个保存字符串的关键字:

rec:各个测试点的状态

file_path:没有ac的测试点路径,在这里我用逗号分隔各个数据的路径,网页解析的时候拆分就行了。

在源代码中不同的数值代感受测试点不同的返回结果,直接保存数字不好操作,我们可以把字符'A'加返回值的字母保存到数据库中。字符串记录各个测试点的测试情况,字符'A'表示当前测试点WT0,字符E'表示当前测试点AC。例字符串"EHHEEE"就表示为第2、第3个测试点超时,其它测试点AC。

#define OJ_WT0 0
#define OJ_WT1 1
#define OJ_CI 2
#define OJ_RI 3
#define OJ_AC 4
#define OJ_PE 5
#define OJ_WA 6
#define OJ_TL 7
#define OJ_ML 8
#define OJ_OL 9
#define OJ_RE 10
#define OJ_CE 11
#define OJ_CO 12
#define OJ_TR 13

2.修改judged_client.cc

judged_client.cc程序的功能就是不断是从数据库中读取待评测的记录,然后调用judged程序测试,然后将judged返回的结果再写入到数据库中。

2.1定义全局变量

char rec[100]; //最多只能存100个测试点的状态

char file_path[5000];

judged_client.cc可能是多线程并发的(judged程序是多线程运行的,但是不清楚judged_client.cc是不是多线程的),定义成全局变量可能会出错,不过我们学校的oj对并发容量的要求并不高,目前来说还没有问题。

2.2修改main()函数代码

先定以到以下的代码片段:

if (oi_mode) {
                  if (ACflg == OJ_AC) {
                            ++pass_rate;   

                        }
                        if (finalACflg < ACflg) {
                                finalACflg = ACflg;
                        }
                        ACflg = OJ_AC;
                }

很明显,上述代码片段是用来统计分数,pass_rate变量统计通过的数量,ACflg为测试点状态。

将程序改为如下所示:

if (oi_mode) {
                        rec[num_of_test-1]='A'+ACflg;//edit by zhc
                        if (ACflg == OJ_AC) {
                                ++pass_rate;
                        }
                        else{ //edit by zhc
                            strcat(file_path,",");
                            strcat(file_path,infile);
                         }
                        if (finalACflg < ACflg) {
                                finalACflg = ACflg;
                        }
                        ACflg = OJ_AC;
                }

2.3修改 _update_solution_mysql 函数

定位到 _update_solution_mysql 函数之后,修改写入的sql语句。

未修改的代码:

if (oi_mode) {
    sprintf(sql,
"UPDATE %s SET result=%d,time=%d,memory=%d,pass_rate=%f,judger='%s',judgetime=now() WHERE solution_id=%d",
tbname,result,time,memory,pass_rate,judger,solution_id);
	} 

修改以后的代码:

if (oi_mode) {
    sprintf(sql,
"UPDATE %s SET result=%d,time=%d,memory=%d,pass_rate=%f,judger='%s',rec='%s',file_path='%s',judgetime=now() WHERE solution_id=%d",
tbname,result,time,memory,pass_rate,judger,rec,file_path,solution_id);
	} 

 3.网页展示

最后就是读取数据库中的数据显示到网页中去了,其实在我实现测试数据下载功能中,最折腾时间的反而是将数据显示到网页上,个人建议在showsource.php的基础上显示测试数据详情。

网页显示效果如下:

judge_client.cc源码中是有记录每个测试点的完成时间的,优化的时候你们可以在solution表中添加一个字段记录每个测试点的使用时间。

总结

修改oj是一个痛并快乐着的过程,这个过程会迫使你去触及以前从未到达的领域,不断地去学习。

上述的功能虽然不是十全十美,但勉强能用,也算是摆脱了总要给学生发题目数据的困扰了。

猜你喜欢

转载自blog.csdn.net/Zerotogether/article/details/97175825