--- tags: Note --- # Domjudge: 如何出互動題 \* 請將下文的problem置換成題目名稱 ## 一、互動題是什麼 互動題是一種較特殊的題目類型,裁判程式與答題程式以標準輸入/輸出互動,通常由答題程式根據互動提供的線索來推測出正確輸出。 ## 二、需求檔案 1. **problem_run.zip** - **build**: 編譯**runjury_problem.c**的script - **run**: 裁判機執行**runjury**(**runjury_problem.c**編譯後的執行檔)的script - **runjury_problem.c**: 裁判用程式的程式碼 2. **problem_cmp.zip** - **build**: 編譯**check_problem.c**的script - **run**: 裁判機執行**check_problem**(**check_problem.c**編譯後的執行檔)的script - **check_problem.c**: 比較用程式的程式碼 3. 測資(以下為建議內容,依題目需求而定) - **輸入檔案**: 與答題程式互動所需的提示資料 - **解答檔案**: 對照答案(判定結果)所需資料 以上都可以在 ```DOMjudge Jury interface/Executables/``` 找到範例題目的範本```boolfind_run, boolfind_cmp```,這篇說明的程式碼也是用此範本改的 <br><br><br><br><br><br><br><br><br><br><br><br> ## 三、評判流程  <br> 1. 編譯並執行答題程式 - 編譯失敗: <span style="color: Red">**COMPILER-ERROR**</span> 3. **runjury**讀取測資輸入檔並且與答題程式互動,產生**progout**檔案 - 讀取**測資輸入檔案**(`argv[1]`) - `talk()`函式: 互動 - 從 `stdout` 輸出提示給答題程式 - 從 `stdin` 讀取答題程式的回應 - 將欲比對的資訊或答案的錯誤訊息(格式錯誤等等)輸出至**progout**(`argv[2]`) - 若途中有程式執行上的錯誤(開檔失敗等等) $\rightarrow$ `exit(1)` $\rightarrow$ <span style="Color: Red">Internal Error</span> - 此階段執行過久: <span style="color: Red">**TIMELIMIT**</span> \*故回應越快越好 4. **check_problem**讀取測資輸入、測資解答、**runjury**產生的**progout**檔案,並比對解答 - 讀取**測資輸入檔案**(`argv[1]`)、**測資解答檔案**(`argv[2]`) - 從 `stdin` 讀取**progout**內容 - 比對解答 - 若為錯誤訊息或解答有誤: 輸出訊息至 `stdout` - 比對正確則讓程式正常結束 - 無論結果是WA或AC都要`return 0` - 途中有程式執行上的錯誤(開檔失敗等等) $\rightarrow$ `return 1` $\rightarrow$ <span style="Color: Red">Internal Error</span> 5. 根據**judgemessage.txt**有無內容來決定評判結果 - 有內容(**check_problem**有從`stdout`輸出過東西): <span style="color:Red">**WRONG-ANSWER**</span> - 沒內容: <span style="color: Green">**CORRECT**</span> - **judgemessage.txt**的內容會寫在Jury的`Diff output`欄位,也會用來跟測資解答比較 ## 四、 上傳至DOMjudge \*待補: 如何打包上傳 1. 更新及測試 - 將**problem_run**的**build**中,Source file的部分改成`runjury_problem.c` - 試著在同一層目錄下使用 `$ ./build` 並確定能正確編譯 - 將**problem_cmp**的**build**中,Source file的部分改成`check_problem.c`、命名改為`check_problem` - 將**problem_cmp**的**run**中,環境變數`CHECK_PROGRAM`的部分改成`"${SCRIPTPATH}/check_problem"` - 試著在同一層目錄下使用 `$ ./build` 並確定能正確編譯 - \*待補: 編譯沒成功會怎樣 3. 上傳執行檔 - \*壓縮要用Linux指令(Windows會有檔案權限問題) - **problem_run.zip** - `$ zip -r problem_run.zip run build runjury_problem.c` - **problem_cmp.zip** - `$ zip -r problem_cmp.zip run build check_problem.c` - 在 `DOMjudge Jury interface/Executables` 上傳兩個zip檔 - **problem_run.zip**: Type run - **problem_cmp.zip**: Type compare 4. 新增問題 - 在 `DOMjudge Jury interface/Problems` 新增問題 - 設定Time limit, 上傳測資, etc - `run script`: **problem_run** - `compare script`: **problem_cmp** 5. 測試題目 <br> ## 五、範例: Boolean Switch Search(bool_find) \*括號內為以此檔案為範本修改時的建議 - 題目概述: - 目標: 給定一個$01$數列,解答目標是輸出後面接有$0$的$1$的位置 - 互動 - 裁判程式給定測試數 - 每筆測試先提供數列長度 $n$,再根據使用者的輸出回答該位置是 $true(1)$ 或是 $false(0)$ ,或是接受答案 - 答題程式收到測試數後,在每筆測試拿到數列長度 - 輸出 `READ x` ,從裁判程式拿到位置 $x$ 是 $true(1)$ 或是 $false(0)$ - 輸出 `OUTPUT x` ,裁判程式接受答案後開始下一個測試 - 測資內容 - **輸入檔案**: 依序為測試數、各筆測試內容(依序包含數列長度及各個位置的 $0/1$ 值) - **解答檔案**(本題未使用): `OUTPUT 1` - **runjury_boolfind.c**  事前檢查(基本上這裡可以不用改) ---  從測資讀取及開始互動 這裡是先讀取測試數後,分次讀取數列內容及互動 (根據題目調整,讀入輸入檔案後呼叫`talk()`函式) ---  互動函式: 輸出數列長度給答題程式後進入無窮迴圈,比對答題程式給出的回答後做適當回應,內容有錯誤就輸出訊息到**progout**後跳出迴圈,繼續下一筆 (根據題目調整,先將事前要給答題程式的輸出完,用無窮迴圈讀取回答,內容有錯誤就輸出訊息到**progout**後跳出迴圈) (圖中48行只是模擬用的,基本上函式內可以整個重寫) (建議此處做格式上的檢查,內容交給**problem_cmp**比對) ---  後續處理: 關閉檔案、將答題程式多餘的輸出 (這裡基本上不用改)<br> - **check_boolfind.c**  事前檢查(基本上這裡可以不用改) ---  檢查答案部分 (根據題目調整,內容有錯誤將訊息輸出到`stdout`) (若答案有錯也可以輸出錯誤答案到`stdout`,Jury那會有比對結果)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up