Windows平台的简易OJ系统,支持SPJ(Special Judge)。
- 支持多个G++版本 (C++14/17/20/23)
- 支持SPJ (testlib.h)
- 并发评测
- Web前端界面
- 安装Python依赖:
cd backend
pip install -r requirements.txt-
解压compilers文件夹中的compilers.zip
-
配置编译器路径:
- 修改
backend/config.py中的COMPILERS配置 - 根据实际安装路径修改各版本g++的path
- 也可以通过Web界面的"编译器配置"页面设置
- 修改
cd backend
python main.py-
POST /api/problems- 上传题目- 参数:
problem_id: 题目IDtitle: 标题time_limit: 时间限制(ms)memory_limit: 空间限制(MB)testcases: ZIP文件(包含.in和.out)checker: checker.cpp (可选)
- 返回:
{ "success": true, "problem_id": "A", "test_case_count": 10, "has_checker": true }
- 参数:
-
GET /api/problems- 获取题目列表- 返回:
[ { "id": "A", "title": "A+B Problem", "time_limit": 1000, "memory_limit": 256, "test_case_count": 10, "has_checker": false } ]
- 返回:
-
GET /api/problems/{id}- 获取题目详情- 返回:
{ "id": "A", "title": "A+B Problem", "time_limit": 1000, "memory_limit": 256, "test_case_count": 10, "has_checker": false }
- 返回:
-
DELETE /api/problems/{id}- 删除题目- 返回:
{ "success": true }
- 返回:
-
POST /api/submit- 提交代码(异步)- 参数:
problem_id: 题目IDcode: 源代码language: c++14/c++17/c++20/c++23
- 返回:
{ "submission_id": 123, "status": "Pending" } - 说明: 提交后立即返回,需要轮询
GET /api/submissions/{id}获取评测结果
- 参数:
-
POST /api/submit/sync- 提交代码(同步)- 参数:
problem_id: 题目IDcode: 源代码language: c++14/c++17/c++20/c++23
- 返回:
{ "id": 123, "problem_id": "A", "language": "c++17", "status": "Accepted", "time_used": 15, "memory_used": 0, "score": 100, "message": "Passed 10/10 test cases", "failed_case": 0, "created_at": "2025-01-23T12:34:56" } - 说明: 等待评测完成后返回完整结果,适合单次提交测试。
failed_case为失败的测试点编号(从1开始),0表示全部通过
- 参数:
-
GET /api/submissions/{id}- 获取评测结果- 返回:
{ "id": 123, "problem_id": "A", "language": "c++17", "status": "Accepted", "time_used": 15, "memory_used": 0, "score": 100, "message": "Passed 10/10 test cases", "failed_case": 0, "created_at": "2025-01-23T12:34:56" } failed_case字段说明: 失败的测试点编号(从1开始),0表示全部通过- 可能的status值:
Pending- 等待评测Judging- 评测中Accepted- 通过Wrong Answer- 答案错误Time Limit Exceeded- 超时Memory Limit Exceeded- 内存超限Runtime Error- 运行时错误Compile Error- 编译错误System Error- 系统错误
- 返回:
-
GET /api/submissions- 获取提交列表- 参数(可选):
problem_id: 筛选指定题目limit: 返回数量限制(默认50)
- 返回:
[ { "id": 123, "problem_id": "A", "language": "c++17", "status": "Accepted", "time_used": 15, "score": 100, "created_at": "2025-01-23T12:34:56" } ]
- 参数(可选):
POST /api/hack- 使用自定义输入测试代码problem_id: 题目IDcode: 待测试的用户代码language: c++14/c++17/c++20/c++23input_data: 自定义输入数据std_code: 标准程序代码(可选,用于生成期望输出)
返回:
{
"status": "Accepted", // 评测结果
"time_used": 15, // 运行时间(ms)
"output": "User Output:\n..." // 用户输出和对比信息
}可能的status值:
Accepted- 输出正确Wrong Answer- 输出错误(与std或checker判定不符)Time Limit Exceeded- 超时Runtime Error- 运行时错误Compile Error- 用户代码编译错误System Error- 系统错误(std编译失败、checker错误等)
使用示例:
# 只运行代码,查看输出
curl -X POST http://localhost:8000/api/hack \
-F "problem_id=A" \
-F "language=c++17" \
-F "input_data=1 2" \
-F "code=#include<iostream>
int main(){int a,b;std::cin>>a>>b;std::cout<<a+b;}"
# 提供std代码进行对比
curl -X POST http://localhost:8000/api/hack \
-F "problem_id=A" \
-F "language=c++17" \
-F "input_data=1 2" \
-F "code=..." \
-F "std_code=..."工作流程:
- 编译用户代码(失败返回CE)
- 编译std代码(如果提供,失败返回SE)
- 编译checker(如果题目有SPJ)
- 运行用户代码(TLE/RE则直接返回)
- 运行std代码生成期望输出
- 使用checker或直接比较判断结果
GET /api/languages- 获取支持的语言POST /api/config/compiler- 设置编译器路径
AC- AcceptedWA- Wrong AnswerTLE- Time Limit ExceededMLE- Memory Limit ExceededRE- Runtime ErrorCE- Compile ErrorSE- System Error
ZIP文件包含:
1.in,1.out2.in,2.out- ...
使用testlib.h编写checker.cpp:
#include "testlib.h"
int main(int argc, char* argv[]) {
registerTestlibCmd(argc, argv);
// inf: 输入文件
// ouf: 用户输出
// ans: 标准答案
int expected = ans.readInt();
int actual = ouf.readInt();
if (expected == actual) {
quitf(_ok, "Correct");
} else {
quitf(_wa, "Expected %d, got %d", expected, actual);
}
}