diff --git a/.gitignore b/.gitignore index dcb6b35..8916c4c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,6 @@ # 기본적으로 output 디렉토리 전체 무시 output/ -# 예외 처리: 2단계 하위 폴더의 .xlsx 파일은 추적 -!output/*/ -!output/*/*.xlsx - sample/ .DS_Store diff --git a/01_copyFiles.py b/01_copyFiles.py index 414ef35..7eeae4a 100644 --- a/01_copyFiles.py +++ b/01_copyFiles.py @@ -2,6 +2,7 @@ import os import shutil import unicodedata +""" def copy_dic_subdirs(source_root, target_root_b, target_root_c): for root, dirs, files in os.walk(source_root): for dir_name in dirs: @@ -26,6 +27,7 @@ def copy_dic_subdirs(source_root, target_root_b, target_root_c): else: print(f"Skipping {dir_name} under {parent_dir}, as it doesn't match '2교시' or '3교시'.") +""" def copy_ent_files(source_root, target_root): # 대상 디렉토리가 없으면 생성 @@ -44,10 +46,11 @@ def copy_ent_files(source_root, target_root): print(f"Copied {source_file_path} to {target_file_path}") # 사용법 -source_directory = r"D:\project\data\CAT_제2507회 정기\채점의뢰" # 원본 디렉토리 경로 -target_directory = r"./ent/2507_CAT_3_A" -target_directory_a = r"./output/A" # '1교시'의 타겟 경로 -target_directory_b = r"./output/B" # '2교시'의 타겟 경로 -target_directory_c = r"./output/C" # '3교시'의 타겟 경로 + +source_directory = r"D:\project\data\CAS_제2508회 정기\답안파일\(전체답안)1교시2교시나눔\B형" # 원본 디렉토리 경로 +target_directory = r".\ent\2508_CAS_2_B" +# target_directory_a = r"./output/A" # '1교시'의 타겟 경로 +# target_directory_b = r"./output/B" # '2교시'의 타겟 경로 +# target_directory_c = r"./output/C" # '3교시'의 타겟 경로 copy_ent_files(source_directory, target_directory) diff --git a/02_extract_project_json.py b/02_extract_project_json.py index 944ef30..0c1223d 100644 --- a/02_extract_project_json.py +++ b/02_extract_project_json.py @@ -50,7 +50,9 @@ def process_ent_files(ent_dir, output_dir): # 실행 예 if __name__ == "__main__": - test_name = "2507_CAT_3_A" - ent_dir = f".\\ent\\{test_name}" - output_dir = f".\\output\\{test_name}" - process_ent_files(ent_dir, output_dir) + # test_names = ["2507_CAT_3_A"] + test_names = ["2508_CAS_2_A","2508_CAS_2_B"] + for test_name in test_names: + ent_dir = f".\\ent\\{test_name}" + output_dir = f".\\output\\{test_name}" + process_ent_files(ent_dir, output_dir) diff --git a/250901_2508_CAS_2_A_채점결과.xlsx b/250901_2508_CAS_2_A_채점결과.xlsx new file mode 100644 index 0000000..66e1e67 Binary files /dev/null and b/250901_2508_CAS_2_A_채점결과.xlsx differ diff --git a/250901_2508_CAS_2_B_채점결과.xlsx b/250901_2508_CAS_2_B_채점결과.xlsx new file mode 100644 index 0000000..b77f47f Binary files /dev/null and b/250901_2508_CAS_2_B_채점결과.xlsx differ diff --git a/__pycache__/script_utils.cpython-312.pyc b/__pycache__/script_utils.cpython-312.pyc new file mode 100644 index 0000000..db8f8e9 Binary files /dev/null and b/__pycache__/script_utils.cpython-312.pyc differ diff --git a/correct/2508_CAS_2_A.json b/correct/2508_CAS_2_A.json new file mode 100644 index 0000000..e618583 --- /dev/null +++ b/correct/2508_CAS_2_A.json @@ -0,0 +1,774 @@ +{ + "1-1": { + "type": "scene", + "ele": "$..objects[?(@.name=='우주')]", + "points": 1.7, + "desc": "문제 1/장면 1/[배경] 이름 설정 1/이름을 '우주'로 변경하기", + "sort": 11 + }, + "1-2": { + "type": "scene", + "ele": "$..objects[?(@.name=='우주정거장')]", + "points": 1.5, + "desc": "문제 1/장면 2/[배경] 이름 설정 2/이름 변경 없음", + "sort": 12 + }, + "1-3": { + "type": "scene", + "ele": "$..objects[?(@.name=='에너지원')]", + "points": 1.7, + "desc": "문제 1/물약(빨강)/[개체] 이름 설정 1/이름을 '에너지원'으로 변경하기", + "sort": 13 + }, + "1-4": { + "type": "scene", + "ele": "$..objects[?(@.name=='운석')]", + "points": 1.7, + "desc": "문제 1/검은 돌멩이/[개체] 이름 설정 2/이름을 '운석'으로 변경하기", + "sort": 14 + }, + "1-5": { + "type": "scene", + "ele": "$..objects[?(@.name=='행성')]", + "points": 1.7, + "desc": "문제 1/행성(5)/[개체] 이름 설정 3/이름을 '행성'으로 변경하기", + "sort": 15 + }, + "1-6": { + "type": "scene", + "ele": "$..objects[?(@.name=='우주선')]", + "points": 1.7, + "desc": "문제 1/우주선 탄 엔트리봇/[개체] 이름 설정 4/이름을 '우주선'으로 변경하기", + "sort": 16 + }, + "1-0": { + "ele": "$..variables[?(@.name=='연료')]", + "points": 1.38, + "desc": "문제 2/에너지원/변수 1/'연료' 변수 만들기 (변수 기본값은 '100', '모든 오브젝트에 사용' 설정하기)", + "type": "scene", + "sort": 101 + }, + "2-0": { + "ele": "$..variables[?(@.name=='점수')]", + "points": 1.38, + "desc": "문제 2/에너지원/변수 2/'점수' 변수 만들기 (변수 기본값은 '0', '모든 오브젝트에 사용' 설정하기)", + "type": "scene", + "sort": 102 + }, + "3-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'에너지원')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.38, + "desc": "문제 2/에너지원/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "50", + "points": 1.38, + "desc": "문제 2/에너지원/[시작]의 세부 동작/크기를 '50' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.38, + "desc": "문제 2/에너지원/반복/계속 반복하기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].type", + "answer": "hide", + "points": 1.38, + "desc": "문제 2/에너지원/[반복]의 세부 동작 1/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][1].type", + "$[0][2].statements[0][1].params[0].params[1].params[0]", + "$[0][2].statements[0][1].params[0].params[3].params[0]", + "$[0][2].statements[0][1].params[1].params[1].params[0]", + "$[0][2].statements[0][1].params[1].params[3].params[0]" + ], + "answer": [ + "locate_xy", + "-200", + "200", + "-100", + "100" + ], + "points": 1.38, + "desc": "문제 2/에너지원/[반복]의 세부 동작 2/x: '-200 부터 200 사이의 무작위 수' y: '-100 부터 100 사이의 무작위 수' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][2].type", + "$[0][2].statements[0][2].params[0].type", + "$[0][2].statements[0][2].params[0].params[1].params[0]", + "$[0][2].statements[0][2].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "1", + "2" + ], + "points": 1.38, + "desc": "문제 2/에너지원/[반복]의 세부 동작 3/'1 부터 2 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][3].type", + "answer": "show", + "points": 1.38, + "desc": "문제 2/에너지원/[반복]의 세부 동작 4/모양 보이기" + }, + { + "ele": [ + "$[0][2].statements[0][4].type", + "$[0][2].statements[0][4].params[0].params[0]" + ], + "answer": [ + "wait_second", + "1" + ], + "points": 1.38, + "desc": "문제 2/에너지원/[반복]의 세부 동작 5/'1' 초 기다리기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][5].type", + "$[0][2].statements[0][5].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.38, + "desc": "문제 2/에너지원/만일/만일 '우주선' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][5].statements[0][0].type", + "$[0][2].statements[0][5].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "10" + ], + "points": 1.38, + "desc": "문제 2/에너지원/[만일]의 세부 동작 1/'점수' 에 '10' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][5].statements[0][1].type", + "$[0][2].statements[0][5].statements[0][1].params[1].params[0]" + ], + "answer": [ + "change_variable", + "50" + ], + "points": 1.38, + "desc": "문제 2/에너지원/[만일]의 세부 동작 2/'연료' 에 '50' 만큼 더하기", + "type": "list" + } + ], + "sort": 105 + }, + "4-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'운석|검은 돌멩')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.38, + "desc": "문제 2/운석/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "30", + "points": 1.38, + "desc": "문제 2/운석/[시작]의 세부 동작/크기를 '30' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.38, + "desc": "문제 2/운석/반복/계속 반복하기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].type", + "answer": "hide", + "points": 1.38, + "desc": "문제 2/운석/[반복]의 세부 동작 1/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][1].type", + "$[0][2].statements[0][1].params[0].params[1].params[0]", + "$[0][2].statements[0][1].params[0].params[3].params[0]", + "$[0][2].statements[0][1].params[1].params[1].params[0]", + "$[0][2].statements[0][1].params[1].params[3].params[0]" + ], + "answer": [ + "locate_xy", + "-200", + "200", + "-100", + "100" + ], + "points": 1.38, + "desc": "문제 2/운석/[반복]의 세부 동작 2/x: '-200 부터 200 사이의 무작위 수' y: '-100 부터 100 사이의 무작위 수' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][2].type", + "$[0][2].statements[0][2].params[0].type", + "$[0][2].statements[0][2].params[0].params[1].params[0]", + "$[0][2].statements[0][2].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0", + "3" + ], + "points": 1.38, + "desc": "문제 2/운석/[반복]의 세부 동작 3/'0 부터 3 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][3].type", + "answer": "show", + "points": 1.38, + "desc": "문제 2/운석/[반복]의 세부 동작 4/모양 보이기" + }, + { + "ele": [ + "$[0][2].statements[0][4].type", + "$[0][2].statements[0][4].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.5" + ], + "points": 1.38, + "desc": "문제 2/운석/[반복]의 세부 동작 5/'0.5' 초 기다리기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][5].type", + "$[0][2].statements[0][5].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.38, + "desc": "문제 2/운석/만일/만일 '우주선' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][5].statements[0][0].type", + "$[0][2].statements[0][5].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-5" + ], + "points": 1.38, + "desc": "문제 2/운석/[만일]의 세부 동작/'점수' 에 '-5' 만큼 더하기", + "type": "list" + } + ], + "sort": 115 + }, + "5-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'행성')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.38, + "desc": "문제 2/행성/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[0][1].type", + "$[0][1].params[0].params[0]", + "$[0][1].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "150", + "80" + ], + "points": 1.38, + "desc": "문제 2/행성/[시작]의 세부 동작/x: '150' y: '80' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.38, + "desc": "문제 2/행성/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.38, + "desc": "문제 2/행성/만일/만일 '우주선' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "50" + ], + "points": 1.38, + "desc": "문제 2/행성/[만일]의 세부 동작 1/'연료' 에 '50' 만큼 더하기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][1].type", + "answer": "hide", + "points": 1.38, + "desc": "문제 2/행성/[만일]의 세부 동작 2/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][1].type", + "$[0][2].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "1" + ], + "points": 1.38, + "desc": "문제 2/행성/[반복]의 세부 동작 1/'1' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][2].type", + "answer": "show", + "points": 1.38, + "desc": "문제 2/행성/[반복]의 세부 동작 2/모양 보이기" + } + ], + "sort": 125 + }, + "32-0": { + "ele": "$.messages[?(@.name=='탐사 성공')]", + "points": 1.38, + "desc": "문제 2/우주선/신호/'탐사 성공' 신호 만들기", + "type": "scene", + "sort": 132 + }, + "6-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'우주선')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.38, + "desc": "문제 2/우주선/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[0][1].type", + "$[0][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.38, + "desc": "문제 2/우주선/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][0].type", + "$[0][1].statements[0][0].params[0].type", + "$[0][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "37" + ], + "points": 1.38, + "desc": "문제 2/우주선/만일 1/만일 '왼쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][0].statements[0][0].type", + "$[0][1].statements[0][0].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_x", + "-5" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 1]의 세부 동작 1/x 좌표를 '-5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][0].statements[0][1].type", + "$[0][1].statements[0][0].statements[0][1].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 1]의 세부 동작 2/'연료' 에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][1].type", + "$[0][1].statements[0][1].params[0].type", + "$[0][1].statements[0][1].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "39" + ], + "points": 1.38, + "desc": "문제 2/우주선/만일 2/만일 '오른쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][1].statements[0][0].type", + "$[0][1].statements[0][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_x", + "5" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 2]의 세부 동작 1/x 좌표를 '5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][1].statements[0][1].type", + "$[0][1].statements[0][1].statements[0][1].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 2]의 세부 동작 2/'연료' 에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][2].type", + "$[0][1].statements[0][2].params[0].type", + "$[0][1].statements[0][2].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "38" + ], + "points": 1.38, + "desc": "문제 2/우주선/만일 3/만일 '위쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][2].statements[0][0].type", + "$[0][1].statements[0][2].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "5" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 3]의 세부 동작 1/y 좌표를 '5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][2].statements[0][1].type", + "$[0][1].statements[0][2].statements[0][1].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 3]의 세부 동작 2/'연료' 에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][3].type", + "$[0][1].statements[0][3].params[0].type", + "$[0][1].statements[0][3].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "40" + ], + "points": 1.38, + "desc": "문제 2/우주선/만일 4/만일 '아래쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][3].statements[0][0].type", + "$[0][1].statements[0][3].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "-5" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 4]의 세부 동작 1/y 좌표를 '-5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][3].statements[0][1].type", + "$[0][1].statements[0][3].statements[0][1].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 4]의 세부 동작 2/'연료' 에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][1].statements[0][4].type", + "$[0][1].statements[0][4].params[0].type" + ], + "answer": [ + "_if", + "boolean_and_or" + ], + "points": 1.38, + "desc": "문제 2/우주선/만일 5/만일 '점수' 값 ≥ '30' '그리고' '연료' 값 > '0'", + "type": "list" + }, + { + "ele": "$[0][1].statements[0][4].statements[0][0].params[*].params", + "answer": [ + "탐사성공!", + "1" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 5]의 세부 동작 1/'탐사성공!' 을 '1' 초 동안 '말하기'" + }, + { + "ele": "$[0][1].statements[0][4].statements[0][1].type", + "answer": "message_cast", + "points": 1.38, + "desc": "문제 2/우주선/[만일 5]의 세부 동작 2/'탐사 성공' 신호 보내기" + }, + { + "ele": [ + "$[0][1].statements[0][5].type", + "$[0][1].statements[0][5].params[0].type", + "$[0][1].statements[0][5].params[0].params[0].type", + "$[0][1].statements[0][5].params[0].params[1]", + "$[0][1].statements[0][5].params[0].params[2].params[0]" + ], + "answer": [ + "_if", + "boolean_basic_operator", + "get_variable", + "LESS_OR_EQUAL", + "0" + ], + "points": 1.38, + "desc": "문제 2/우주선/만일 6/만일 '연료' 값 ≤ '0' 이라면", + "type": "list" + }, + { + "ele": "$[0][1].statements[0][5].statements[0][0].params[*].params", + "answer": [ + "미션실패", + "2" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 6]의 세부 동작 1/'미션실패' 를 '2' 초 동안 '말하기'" + }, + { + "ele": [ + "$[0][1].statements[0][5].statements[0][1].type", + "$[0][1].statements[0][5].statements[0][1].params[0]" + ], + "answer": [ + "stop_object", + "all" + ], + "points": 1.38, + "desc": "문제 2/우주선/[만일 6]의 세부 동작 2/'모든' 코드 멈추기", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_message_cast", + "points": 1.38, + "desc": "문제 2/우주선/탐사 성공/'탐사 성공' 신호를 받았을 때 " + }, + { + "ele": "$[1][1].type", + "answer": "start_neighbor_scene", + "points": 1.38, + "desc": "문제 2/우주선/[탐사 성공]의 세부 동작/'다음' 장면 시작하기" + } + ], + "sort": 133 + }, + "7-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'우주정거장')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_scene_start", + "points": 1.38, + "desc": "문제 2/우주정거장/장면/장면이 시작되었을 때" + }, + { + "ele": "$[0][1].type", + "answer": "hide_variable", + "points": 1.38, + "desc": "문제 2/우주정거장/[장면 2]의 세부 동작 1/변수 '연료' 숨기기" + }, + { + "ele": "$[0][2].type", + "answer": "hide_variable", + "points": 1.38, + "desc": "문제 2/우주정거장/[장면 2]의 세부 동작 2/변수 '점수' 숨기기" + }, + { + "ele": [ + "$[0][3].type", + "$[0][3].params[0].params[0]", + "$[0][3].params[1]" + ], + "answer": [ + "dialog", + "탐사 완료!", + "speak" + ], + "points": 1.38, + "desc": "문제 2/우주정거장/[장면 2]의 세부 동작 3/'탐사 완료!' 를 '말하기'", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_object_click", + "points": 2, + "desc": "문제 3/우주정거장/오브젝트/오브젝트를 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]", + "$[1][1].params[1].params[0]" + ], + "answer": [ + "add_effect_amount", + "color", + "50" + ], + "points": 2, + "desc": "문제 3/우주정거장/[오브젝트]의 세부 동작 1/'색깔' 효과를 '50' 만큼 주기", + "type": "list" + }, + { + "ele": [ + "$[1][2].type", + "$[1][2].params[0].params[0]", + "$[1][2].params[1]" + ], + "answer": [ + "dialog", + "처음부터 다시 실행합니다.", + "speak" + ], + "points": 2, + "desc": "문제 3/우주정거장/[오브젝트]의 세부 동작 2/'처음부터 다시 실행합니다.' 를 '말하기'", + "type": "list" + }, + { + "ele": [ + "$[1][3].type", + "$[1][3].params[0].params[0]" + ], + "answer": [ + "wait_second", + "2" + ], + "points": 2, + "desc": "문제 3/우주정거장/[오브젝트]의 세부 동작 3/'2' 초 기다리기", + "type": "list" + }, + { + "ele": "$[1][4].type", + "answer": "restart_project", + "points": 2, + "desc": "문제 3/우주정거장/[오브젝트]의 세부 동작 4/처음부터 다시 실행하기" + } + ], + "sort": 156 + } +} \ No newline at end of file diff --git a/correct/2508_CAS_2_B.json b/correct/2508_CAS_2_B.json new file mode 100644 index 0000000..2cc2547 --- /dev/null +++ b/correct/2508_CAS_2_B.json @@ -0,0 +1,825 @@ +{ + "1-1": { + "type": "scene", + "ele": "$..objects[?(@.name=='체육관')]", + "points": 1.7, + "desc": "문제 1/장면 1/[배경] 이름 설정 1/이름을 '체육관'으로 변경하기", + "sort": 11 + }, + "1-2": { + "type": "scene", + "ele": "$..objects[?(@.name=='복도')]", + "points": 1.7, + "desc": "문제 1/장면 2/[배경] 이름 설정 2/이름을 '복도'로 변경하기", + "sort": 12 + }, + "1-3": { + "type": "scene", + "ele": "$..objects[?(@.name=='곰인형')]", + "points": 1.6, + "desc": "문제 1/곰인형/[개체] 이름 설정 1/이름 변경 없음", + "sort": 13 + }, + "1-4": { + "type": "scene", + "ele": "$..objects[?(@.name=='풍선')]", + "points": 1.6, + "desc": "문제 1/풍선/[개체] 이름 설정 2/이름 변경 없음", + "sort": 14 + }, + "1-5": { + "type": "scene", + "ele": "$..objects[?(@.name=='다트 날개')]", + "points": 1.7, + "desc": "문제 1/빛나는 효과/[개체] 이름 설정 3/이름을 '다트 날개'로 변경하기", + "sort": 15 + }, + "1-6": { + "type": "scene", + "ele": "$..objects[?(@.name=='다트')]", + "points": 1.7, + "desc": "문제 1/룰렛 화살표/[개체] 이름 설정 4/이름을 '다트'로 변경하기", + "sort": 16 + }, + "1-0": { + "ele": "$..variables[?(@.name=='다트 개수')]", + "points": 1.29, + "desc": "문제 2/곰인형/변수 1/'다트 개수' 변수 만들기 (변수 기본값은 '0', '모든 오브젝트에 사용' 설정하기)", + "type": "scene", + "sort": 101 + }, + "2-0": { + "ele": "$..variables[?(@.name=='점수')]", + "points": 1.29, + "desc": "문제 2/곰인형/변수 2/'점수' 변수 만들기 (변수 기본값은 '0', '모든 오브젝트에 사용' 설정하기)", + "type": "scene", + "sort": 102 + }, + "3-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'곰인형')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.29, + "desc": "문제 2/곰인형/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[0][1].type", + "$[0][1].params[0].params[0]", + "$[0][1].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "180", + "-70" + ], + "points": 1.29, + "desc": "문제 2/곰인형/[시작]의 세부 동작 1/x: '180' y: '-70' 위치로 이동하기", + "type": "list" + }, + { + "ele": "$[0][2].params[0].params[0]", + "answer": "25", + "points": 1.29, + "desc": "문제 2/곰인형/[시작]의 세부 동작 2/크기를 '25' 로 정하기" + }, + { + "ele": "$[0][3].type", + "answer": "hide", + "points": 1.29, + "desc": "문제 2/곰인형/[시작]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][4].type", + "$[0][4].params[0].params[0]" + ], + "answer": [ + "repeat_basic", + "3" + ], + "points": 1.29, + "desc": "문제 2/곰인형/반복/'3' 번 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][4].statements[0][0].type", + "$[0][4].statements[0][0].params[0]" + ], + "answer": [ + "create_clone", + "self" + ], + "points": 1.29, + "desc": "문제 2/곰인형/[반복]의 세부 동작 1/'자신' 의 복제본 만들기", + "type": "list" + }, + { + "ele": [ + "$[0][4].statements[0][1].type", + "$[0][4].statements[0][1].params[0].params[0]" + ], + "answer": [ + "move_y", + "70" + ], + "points": 1.29, + "desc": "문제 2/곰인형/[반복]의 세부 동작 2/y 좌표를 '70' 만큼 바꾸기", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_clone_start", + "points": 1.29, + "desc": "문제 2/곰인형/복제본/복제본이 처음 생성되었을 때" + }, + { + "ele": "$[1][1].type", + "answer": "show", + "points": 1.29, + "desc": "문제 2/곰인형/[복제본]의 세부 동작/모양 보이기" + }, + { + "ele": [ + "$[1][2].type", + "$[1][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.29, + "desc": "문제 2/곰인형/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][2].statements[0][0].type", + "$[1][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.29, + "desc": "문제 2/곰인형/만일/만일 '다트'에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][2].statements[0][0].statements[0][0].type", + "$[1][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-5" + ], + "points": 1.29, + "desc": "문제 2/곰인형/[만일]의 세부 동작 1/'점수' 에 '-5' 만큼 더하기", + "type": "list" + }, + { + "ele": "$[1][2].statements[0][0].statements[0][1].type", + "answer": "delete_clone", + "points": 1.29, + "desc": "문제 2/곰인형/[만일]의 세부 동작 2/이 복제본 삭제하기" + } + ], + "sort": 105 + }, + "4-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'풍선')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.29, + "desc": "문제 2/풍선/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[0][1].type", + "$[0][1].params[0].params[0]", + "$[0][1].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "130", + "-100" + ], + "points": 1.29, + "desc": "문제 2/풍선/[시작]의 세부 동작 1/x: '130' y: '-100' 위치로 이동하기", + "type": "list" + }, + { + "ele": "$[0][2].params[0].params[0]", + "answer": "30", + "points": 1.29, + "desc": "문제 2/풍선/[시작]의 세부 동작 2/크기를 '30' 으로 정하기" + }, + { + "ele": "$[0][3].type", + "answer": "hide", + "points": 1.29, + "desc": "문제 2/풍선/[시작]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][4].type", + "$[0][4].params[0].params[0]" + ], + "answer": [ + "repeat_basic", + "6" + ], + "points": 1.29, + "desc": "문제 2/풍선/반복/'6' 번 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][4].statements[0][0].type", + "$[0][4].statements[0][0].params[0]" + ], + "answer": [ + "create_clone", + "self" + ], + "points": 1.29, + "desc": "문제 2/풍선/[반복]의 세부 동작 1/'자신' 의 복제본 만들기", + "type": "list" + }, + { + "ele": [ + "$[0][4].statements[0][1].type", + "$[0][4].statements[0][1].params[0].params[0]" + ], + "answer": [ + "move_y", + "40" + ], + "points": 1.29, + "desc": "문제 2/풍선/[반복]의 세부 동작 2/y 좌표를 '40' 만큼 바꾸기", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_clone_start", + "points": 1.29, + "desc": "문제 2/풍선/복제본/복제본이 처음 생성되었을 때" + }, + { + "ele": "$[1][1].type", + "answer": "show", + "points": 1.29, + "desc": "문제 2/풍선/[복제본]의 세부 동작/모양 보이기" + }, + { + "ele": [ + "$[1][2].type", + "$[1][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.29, + "desc": "문제 2/풍선/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][2].statements[0][0].type", + "$[1][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.29, + "desc": "문제 2/풍선/만일/만일 '다트' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][2].statements[0][0].statements[0][0].type", + "$[1][2].statements[0][0].statements[0][0].params[0].type" + ], + "answer": [ + "change_to_some_shape", + "get_pictures" + ], + "points": 1.29, + "desc": "문제 2/풍선/[만일]의 세부 동작 1/'풍선_터짐' 모양으로 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][2].statements[0][0].statements[0][1].type", + "$[1][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.5" + ], + "points": 1.29, + "desc": "문제 2/풍선/[만일]의 세부 동작 2/'0.5' 초 기다리기", + "type": "list" + }, + { + "ele": [ + "$[1][2].statements[0][0].statements[0][2].type", + "$[1][2].statements[0][0].statements[0][2].params[1].params[0]" + ], + "answer": [ + "change_variable", + "10" + ], + "points": 1.29, + "desc": "문제 2/풍선/[만일]의 세부 동작 3/'점수' 에 '10' 만큼 더하기", + "type": "list" + }, + { + "ele": "$[1][2].statements[0][0].statements[0][3].type", + "answer": "delete_clone", + "points": 1.29, + "desc": "문제 2/풍선/[만일]의 세부 동작 4/이 복제본 삭제하기" + } + ], + "sort": 117 + }, + "5-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'다트 날개|빛나는 효')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.29, + "desc": "문제 2/다트 날개/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "50", + "points": 1.29, + "desc": "문제 2/다트 날개/[시작]의 세부 동작/크기를 '50' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.29, + "desc": "문제 2/다트 날개/반복/계속 반복하기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].type", + "answer": "locate", + "points": 1.29, + "desc": "문제 2/다트 날개/[반복]의 세부 동작 1/'다트' 위치로 이동하기" + }, + { + "ele": [ + "$[0][2].statements[0][1].type", + "$[0][2].statements[0][1].params[0].params[0]" + ], + "answer": [ + "move_x", + "-20" + ], + "points": 1.29, + "desc": "문제 2/다트 날개/[반복]의 세부 동작 2/x 좌표를 '-20' 만큼 바꾸기", + "type": "list" + } + ], + "sort": 132 + }, + "6-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'다트|룰렛 화살')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.29, + "desc": "문제 2/다트/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[0][1].type", + "$[0][1].params[1].params[0]" + ], + "answer": [ + "set_variable", + "10" + ], + "points": 1.29, + "desc": "문제 2/다트/[시작]의 세부 동작 1/'다트 개수' 를 '10' 으로 정하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0].params[0]", + "$[0][2].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "-180", + "-20" + ], + "points": 1.29, + "desc": "문제 2/다트/[시작]의 세부 동작 2/x: '-180' y: '-20' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[0][3].type", + "$[0][3].params[0].params[0]" + ], + "answer": [ + "rotate_absolute", + "90" + ], + "points": 1.29, + "desc": "문제 2/다트/[시작]의 세부 동작 3/방향을 '90°' 로 정하기", + "type": "list" + }, + { + "ele": "$[0][4].params[0].params[0]", + "answer": "40", + "points": 1.29, + "desc": "문제 2/다트/[시작]의 세부 동작 4/크기를 '40' 으로 정하기" + }, + { + "ele": [ + "$[0][5].type", + "$[0][5].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.29, + "desc": "문제 2/다트/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][5].statements[0][0].type", + "$[0][5].statements[0][0].params[0].type", + "$[0][5].statements[0][0].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "38" + ], + "points": 1.29, + "desc": "문제 2/다트/만일 1/만일 '위쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][5].statements[0][0].statements[0][0].type", + "$[0][5].statements[0][0].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "3" + ], + "points": 1.29, + "desc": "문제 2/다트/[만일 1]의 세부 동작/y 좌표를 '3' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[0][5].statements[0][1].type", + "$[0][5].statements[0][1].params[0].type", + "$[0][5].statements[0][1].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "40" + ], + "points": 1.29, + "desc": "문제 2/다트/만일 2/만일 '아래쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][5].statements[0][1].statements[0][0].type", + "$[0][5].statements[0][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "-3" + ], + "points": 1.29, + "desc": "문제 2/다트/[만일 2]의 세부 동작/y 좌표를 '-3' 만큼 바꾸기", + "type": "list" + }, + { + "ele": "$[1][0].params", + "answer": [ + null, + "32" + ], + "points": 1.29, + "desc": "문제 2/다트/스페이스/'스페이스' 키를 눌렀을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0].type", + "$[1][1].params[0].params[0].type", + "$[1][1].params[0].params[1]", + "$[1][1].params[0].params[2].params[0]" + ], + "answer": [ + "if_else", + "boolean_basic_operator", + "get_variable", + "GREATER_OR_EQUAL", + "50" + ], + "points": 1.29, + "desc": "문제 2/다트/만일/만일 '점수' 값 ≥ '50' 이라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0]" + ], + "answer": [ + "stop_object", + "all" + ], + "points": 1.29, + "desc": "문제 2/다트/[만일]의 세부 동작/'모든' 코드 멈추기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][0].type", + "$[1][1].statements[1][0].params[0].params[0]", + "$[1][1].statements[1][0].params[1].params[0]", + "$[1][1].statements[1][0].params[2].params[0]" + ], + "answer": [ + "locate_xy_time", + "1", + "330", + null + ], + "points": 1.29, + "desc": "문제 2/다트/[아니면]의 세부 동작 1/'1' 초 동안 x: '330' y: '자신의 y 좌푯값' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][1].type", + "$[1][1].statements[1][1].params[0].params[0]", + "$[1][1].statements[1][1].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "-180", + "-20" + ], + "points": 1.29, + "desc": "문제 2/다트/[아니면]의 세부 동작 2/x: '-180' y: '-20' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][2].type", + "$[1][1].statements[1][2].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.29, + "desc": "문제 2/다트/[아니면]의 세부 동작 3/'다트 개수' 에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][3].type", + "$[1][1].statements[1][3].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.1" + ], + "points": 1.29, + "desc": "문제 2/다트/[아니면]의 세부 동작 4/'0.1' 초 기다리기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][4].type", + "$[1][1].statements[1][4].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.29, + "desc": "문제 2/다트/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][4].statements[0][0].type", + "$[1][1].statements[1][4].statements[0][0].params[0].type", + "$[1][1].statements[1][4].statements[0][0].params[0].params[0].params[0].type", + "$[1][1].statements[1][4].statements[0][0].params[0].params[0].params[1]", + "$[1][1].statements[1][4].statements[0][0].params[0].params[0].params[2].params[0]", + "$[1][1].statements[1][4].statements[0][0].params[0].params[1]", + "$[1][1].statements[1][4].statements[0][0].params[0].params[2].type", + "$[1][1].statements[1][4].statements[0][0].params[0].params[2].params[0].type", + "$[1][1].statements[1][4].statements[0][0].params[0].params[2].params[1]", + "$[1][1].statements[1][4].statements[0][0].params[0].params[2].params[2].params[0]" + ], + "answer": [ + "_if", + "boolean_and_or", + "get_variable", + "EQUAL", + "0", + "AND", + "boolean_basic_operator", + "get_variable", + "LESS", + "50" + ], + "points": 1.31, + "desc": "문제 2/다트/만일 1/만일 '다트 개수' 값 = '0' '그리고' '점수 값' < '50' 이라면", + "type": "list" + }, + { + "ele": "$[1][1].statements[1][4].statements[0][0].statements[0][0].type", + "answer": "start_neighbor_scene", + "points": 1.29, + "desc": "문제 2/다트/[만일 1]의 세부 동작/'다음' 장면 시작하기" + }, + { + "ele": [ + "$[1][1].statements[1][4].statements[0][1].type", + "$[1][1].statements[1][4].statements[0][1].params[0].type", + "$[1][1].statements[1][4].statements[0][1].params[0].params[0].type", + "$[1][1].statements[1][4].statements[0][1].params[0].params[1]", + "$[1][1].statements[1][4].statements[0][1].params[0].params[2].params[0]" + ], + "answer": [ + "_if", + "boolean_basic_operator", + "get_variable", + "GREATER_OR_EQUAL", + "50" + ], + "points": 1.29, + "desc": "문제 2/다트/만일 2/만일 '점수' 값 ≥ '50' 이라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][4].statements[0][1].statements[0][0].type", + "$[1][1].statements[1][4].statements[0][1].statements[0][0].params[0].params[0]", + "$[1][1].statements[1][4].statements[0][1].statements[0][0].params[1]" + ], + "answer": [ + "dialog", + "미션 성공!", + "speak" + ], + "points": 1.29, + "desc": "문제 2/다트/[만일 2]의 세부 동작 1/'미션 성공!' 을 '말하기'", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[1][4].statements[0][1].statements[0][1].type", + "$[1][1].statements[1][4].statements[0][1].statements[0][1].params[0]" + ], + "answer": [ + "stop_object", + "all" + ], + "points": 1.29, + "desc": "문제 2/다트/[만일 2]의 세부 동작 2/'모든' 코드 멈추기", + "type": "list" + } + ], + "sort": 137 + }, + "7-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'복도|장면 ')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_scene_start", + "points": 1.29, + "desc": "문제 2/복도/장면/장면이 시작되었을 때" + }, + { + "ele": "$[0][1].type", + "answer": "hide_variable", + "points": 1.29, + "desc": "문제 2/복도/[장면 2]의 세부 동작 1/변수 '다트 개수' 숨기기" + }, + { + "ele": "$[0][2].type", + "answer": "hide_variable", + "points": 1.29, + "desc": "문제 2/복도/[장면 2]의 세부 동작 2/변수 '점수' 숨기기" + }, + { + "ele": [ + "$[0][3].type", + "$[0][3].params[0].params[0]", + "$[0][3].params[1]" + ], + "answer": [ + "dialog", + "미션 실패!", + "speak" + ], + "points": 1.29, + "desc": "문제 2/복도/[장면 2]의 세부 동작 3/'미션 실패!' 를 '말하기'", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_object_click", + "points": 2, + "desc": "문제 3/복도/오브젝트/오브젝트를 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]", + "$[1][1].params[1].params[0]" + ], + "answer": [ + "add_effect_amount", + "color", + "60" + ], + "points": 2, + "desc": "문제 3/복도/[오브젝트]의 세부 동작 1/'색깔' 효과를 '60' 만큼 주기", + "type": "list" + }, + { + "ele": [ + "$[1][2].type", + "$[1][2].params[0].params[0]", + "$[1][2].params[1]" + ], + "answer": [ + "dialog", + "처음부터 다시 실행합니다.", + "speak" + ], + "points": 2, + "desc": "문제 3/복도/[오브젝트]의 세부 동작 2/'처음부터 다시 실행합니다.' 를 '말하기'", + "type": "list" + }, + { + "ele": [ + "$[1][3].type", + "$[1][3].params[0].params[0]" + ], + "answer": [ + "wait_second", + "2" + ], + "points": 2, + "desc": "문제 3/복도/[오브젝트]의 세부 동작 3/'2' 초 기다리기", + "type": "list" + }, + { + "ele": "$[1][4].type", + "answer": "restart_project", + "points": 2, + "desc": "문제 3/복도/[오브젝트]의 세부 동작 4/처음부터 다시 실행하기" + } + ], + "sort": 160 + } +} \ No newline at end of file diff --git a/correct/_2508_CAS_2_A.json b/correct/_2508_CAS_2_A.json new file mode 100644 index 0000000..86b9a67 --- /dev/null +++ b/correct/_2508_CAS_2_A.json @@ -0,0 +1,877 @@ +{ + "1-1": { + "type": "scene", + "ele": "$..objects[?(@.name=='우주')]", + "points": 1.8, + "desc": "장면 1/[배경] 이름 설정 1/이름을 ‘우주’로 변경하기", + "sort": 11 + }, + "1-2": { + "type": "scene", + "ele": "$..objects[?(@.name=='우주정거장')]", + "points": 1.8, + "desc": "장면 2/[배경] 이름 설정 2/이름 변경 없음", + "sort": 12 + }, + "1-3": { + "type": "scene", + "ele": "$..objects[?(@.name=='에너지원')]", + "points": 1.6, + "desc": "물약(빨강)/[개체] 이름 설정 1/이름을 ‘에너지원’으로 변경하기", + "sort": 13 + }, + "1-4": { + "type": "scene", + "ele": "$..objects[?(@.name=='운석')]", + "points": 1.6, + "desc": "검은 돌멩이/[개체] 이름 설정 2/이름을 ‘운석’으로 변경하기", + "sort": 14 + }, + "1-5": { + "type": "scene", + "ele": "$..objects[?(@.name=='행성')]", + "points": 1.6, + "desc": "행성(5)/[개체] 이름 설정 3/이름을 ‘행성’으로 변경하기", + "sort": 15 + }, + "1-6": { + "type": "scene", + "ele": "$..objects[?(@.name=='우주선')]", + "points": 1.6, + "desc": "우주선 탄 엔트리봇/[개체] 이름 설정 4/이름을 ‘우주선’으로 변경하기", + "sort": 16 + }, + "1-7": { + "type": "scene", + "ele": "$..variables[?(@.name=='연료')]", + "points": 1, + "desc": "문제 2/에너지원/변수 1/‘연료’변수 만들기 (변수 기본값은 ‘100’, ‘모든 오브젝트에 사용’ 설정하기)", + "sort": 101 + }, + "1-8": { + "type": "scene", + "ele": "$..variables[?(@.name=='점수')]", + "points": 1, + "desc": "문제 2/에너지원/변수 2/‘점수’ 변수 만들기 (변수 기본값은 ‘0’, ‘모든 오브젝트에 사용’ 설정하기)", + "sort": 102 + }, + "2-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'에너지원')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/에너지원/시작/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "50", + "points": 1.2, + "desc": "문제 2/에너지원/[시작]의 세부 동작/크기를 ‘50’ 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/에너지원/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0]" + ], + "answer": [ + "hide", + null + ], + "points": 1.2, + "desc": "문제 2/에너지원/[반복]의 세부 동작 1/모양 숨기기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "1" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 1/'물고기 수'에 '1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][1].type", + "$[0][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.01" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 2/'0.01' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][2].type", + "answer": "hide", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][3].type", + "$[0][2].statements[0][0].statements[0][3].params[0].type", + "$[0][2].statements[0][0].statements[0][3].params[0].params[1].params[0]", + "$[0][2].statements[0][0].statements[0][3].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0.5", + "3" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 4/'0.5 부터 3 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][4].type", + "answer": "show", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 5/모양 보이기" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/빨간 물고기/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_direction", + null + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[반복]의 세부 동작 1/이동 방향으로 '1 부터 2 사이의 무작위 수' 만큼 움직이기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[1].params[0]", + "$[1][1].statements[0][1].params[0].params[3].params[0]" + ], + "answer": [ + "direction_relative", + "calc_rand", + "-1", + "1" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[반복]의 세부 동작 2/이동 방향을 '-1 부터 1 사이의 무작위 수' 만큼 회전하기", + "type": "list" + }, + { + "ele": "$[1][1].statements[0][2].type", + "answer": "bounce_wall", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[반복]의 세부 동작 3/화면 끝에 닿으면 튕기기" + } + ], + "sort": 102, + "list": [ + "set_scale_size", + "repeat_inf" + ] + }, + "3-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'노란 물고기|물고')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/노란 물고기/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "30", + "points": 1.2, + "desc": "문제 2/노란 물고기/[시작1]의 세부 동작 1/크기를 '30' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/만일/만일 '상어' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "2" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 1/물고기 수'에 '2' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][1].type", + "$[0][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.01" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 2/'0.01' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][2].type", + "answer": "hide", + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][3].type", + "$[0][2].statements[0][0].statements[0][3].params[0].type", + "$[0][2].statements[0][0].statements[0][3].params[0].params[1].params[0]", + "$[0][2].statements[0][0].statements[0][3].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0.5", + "1.5" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 4/'0.5' 부터 '1.5' 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][4].type", + "answer": "show", + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 5/모양 보이기" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/노란 물고기/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_direction", + null + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[반복]의 세부 동작 1/이동 방향으로 '1 부터 2 사이의 무작위 수' 만큼 움직이기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[1].params[0]", + "$[1][1].statements[0][1].params[0].params[3].params[0]" + ], + "answer": [ + "direction_relative", + "calc_rand", + "-1", + "1" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[반복]의 세부 동작 2/이동 방향을 '-1 부터 1 사이의 무작위 수' 만큼 회전하기", + "type": "list" + }, + { + "ele": "$[1][1].statements[0][2].type", + "answer": "bounce_wall", + "points": 1.2, + "desc": "문제 2/노란 물고기/[반복]의 세부 동작 3/화면 끝에 닿으면 튕기기" + } + ], + "sort": 117, + "list": [ + "set_scale_size", + "repeat_inf" + ] + }, + "4-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'쓰레기')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/쓰레기/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "30", + "points": 1.2, + "desc": "문제 2/쓰레기/[시작1]의 세부 동작 1/크기를 '30' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/쓰레기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/만일/만일 '상어' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 1/물고기 수'에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][1].type", + "$[0][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.01" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 2/'0.01' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][2].type", + "answer": "hide", + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][3].type", + "$[0][2].statements[0][0].statements[0][3].params[0].type", + "$[0][2].statements[0][0].statements[0][3].params[0].params[1].params[0]", + "$[0][2].statements[0][0].statements[0][3].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0.5", + "3" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 4/'0.5 부터 3 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][4].type", + "answer": "show", + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 5/모양 보이기" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/쓰레기/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/쓰레기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_direction", + null + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[반복]의 세부 동작 1/이동 방향으로 '1 부터 2 사이의 무작위 수' 만큼 움직이기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[1].params[0]", + "$[1][1].statements[0][1].params[0].params[3].params[0]" + ], + "answer": [ + "direction_relative", + "calc_rand", + "-1", + "1" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[반복]의 세부 동작 2/이동 방향을 '-1 부터 1 사이의 무작위 수' 만큼 회전하기", + "type": "list" + }, + { + "ele": "$[1][1].statements[0][2].type", + "answer": "bounce_wall", + "points": 1.2, + "desc": "문제 2/쓰레기/[반복]의 세부 동작 3/화면 끝에 닿으면 튕기기" + } + ], + "sort": 131, + "list": [ + "set_scale_size", + "repeat_inf" + ] + }, + "44-0": { + "ele": "$.messages[?(@.name=='성공')]", + "points": 1, + "desc": "문제 2/상어/신호/'성공'신호 만들기", + "type": "scene", + "sort": 144 + }, + "5-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'상어')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/상어/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "50", + "points": 1.2, + "desc": "문제 2/상어/[시작]의 세부 동작 1/크기를 '50' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0].params[0]", + "$[0][2].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "-100", + "0" + ], + "points": 1.2, + "desc": "문제 2/상어/[시작]의 세부 동작 2/x: '-100' y: '0' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[0][3].type", + "$[0][3].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/상어/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][3].statements[0][0].type", + "$[0][3].statements[0][0].params[0].type", + "$[0][3].statements[0][0].params[0].params[0].type", + "$[0][3].statements[0][0].params[0].params[1]", + "$[0][3].statements[0][0].params[0].params[2].params[0]" + ], + "answer": [ + "_if", + "boolean_basic_operator", + "get_variable", + "GREATER", + "10" + ], + "points": 1.2, + "desc": "문제 2/상어/만일/만일 '물고기 수' 값 > '10' 이라면", + "type": "list" + }, + { + "ele": "$[0][3].statements[0][0].statements[0][0].type", + "answer": "message_cast", + "points": 1.2, + "desc": "문제 2/상어/[만일]의 세부 동작 1/성공' 신호보내기" + }, + { + "ele": [ + "$[0][3].statements[0][0].statements[0][1].type", + "$[0][3].statements[0][0].statements[0][1].params[0]" + ], + "answer": [ + "stop_object", + "thisOnly" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일]의 세부 동작 2/자신의' 코드 멈추기", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/상어/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/상어/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "37" + ], + "points": 1.2, + "desc": "문제 2/상어/만일1/만일 '왼쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].statements[0][0].type", + "$[1][1].statements[0][0].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_x", + "-5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일1]의 세부 동작 1/x 좌표를 '-5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "39" + ], + "points": 1.2, + "desc": "문제 2/상어/만일2/만일 '오른쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].statements[0][0].type", + "$[1][1].statements[0][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_x", + "5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일2]의 세부 동작 1/x 좌표를 '5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][2].type", + "$[1][1].statements[0][2].params[0].type", + "$[1][1].statements[0][2].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "38" + ], + "points": 1.2, + "desc": "문제 2/상어/만일3/만일 '위쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][2].statements[0][0].type", + "$[1][1].statements[0][2].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일3]의 세부 동작 1/y 좌표를 '5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][3].type", + "$[1][1].statements[0][3].params[0].type", + "$[1][1].statements[0][3].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "40" + ], + "points": 1.2, + "desc": "문제 2/상어/만일4/만일 '아래쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][3].statements[0][0].type", + "$[1][1].statements[0][3].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "-5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일4]의 세부 동작 1/y 좌표를 '-5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": "$[2][0].type", + "answer": "when_message_cast", + "points": 1.2, + "desc": "문제 2/상어/신호/'성공' 신호를 받았을 때 " + }, + { + "ele": "$[2][1].params[*].params", + "answer": [ + "배부르다!", + "1" + ], + "points": 1.2, + "desc": "문제 2/상어/[신호]의 세부 동작 1/'배부르다!' 를 '1'초 동안 '말하기'" + }, + { + "ele": "$[2][2].type", + "answer": "start_neighbor_scene", + "points": 1.2, + "desc": "문제 2/상어/[신호]의 세부 동작 2/'다음' 장면 시작하기" + } + ], + "sort": 145, + "list": [ + "set_scale_size", + "repeat_inf", + "dialog_time" + ] + }, + "6-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'바다2|바닷속\\(3\\)1')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_scene_start", + "points": 1.2, + "desc": "문제 2/바다2/장면 2/장면이 시작되었을 때" + }, + { + "ele": "$[0][1].type", + "answer": "hide_variable", + "points": 1.2, + "desc": "문제 2/바다2/[장면 2]의 세부 동작 1/변수 '물고기 수' 숨기기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0].params[0]", + "$[0][2].params[1]" + ], + "answer": [ + "dialog", + "미션성공!", + "speak" + ], + "points": 1.2, + "desc": "문제 2/바다2/[장면 2]의 세부 동작 2/'미션성공!' 을 '말하기'", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_object_click", + "points": 2, + "desc": "문제 3/바다2/오브젝트/오브젝트를 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]", + "$[1][1].params[1].params[0]" + ], + "answer": [ + "add_effect_amount", + "color", + "30" + ], + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 1/'색깔' 효과를 '30' 만큼 주기", + "type": "list" + }, + { + "ele": [ + "$[1][2].type", + "$[1][2].params[0].params[0]", + "$[1][2].params[1]" + ], + "answer": [ + "dialog", + "처음부터 다시 실행!", + "speak" + ], + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 2/'처음부터 다시 실행!' 을 '말하기'", + "type": "list" + }, + { + "ele": [ + "$[1][3].type", + "$[1][3].params[0].params[0]" + ], + "answer": [ + "wait_second", + "2" + ], + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 3/'2' 초 기다리기", + "type": "list" + }, + { + "ele": "$[1][4].type", + "answer": "restart_project", + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 4/처음부터 다시 실행하기" + } + ], + "sort": 166, + "list": [ + "hide_variable", + "add_effect_amount" + ] + } +} \ No newline at end of file diff --git a/correct/_2508_CAS_2_B.json b/correct/_2508_CAS_2_B.json new file mode 100644 index 0000000..0e44a46 --- /dev/null +++ b/correct/_2508_CAS_2_B.json @@ -0,0 +1,870 @@ +{ + "1-1": { + "type": "scene", + "ele": "$..objects[?(@.name=='바다1')]", + "points": 1.8, + "desc": "문제 1/장면 1/[배경] 이름 설정 1/이름을 '바다1'로 변경하기", + "sort": 11 + }, + "1-2": { + "type": "scene", + "ele": "$..objects[?(@.name=='바다2')]", + "points": 1.8, + "desc": "문제 1/장면 2/[배경] 이름 설정 2/이름을 '바다2'로 변경하기", + "sort": 12 + }, + "1-3": { + "type": "scene", + "ele": "$..objects[?(@.name=='빨간 물고기')]", + "points": 1.6, + "desc": "문제 1/빨간 물고기/[개체] 이름 설정 1/이름 변경 없음", + "sort": 13 + }, + "1-4": { + "type": "scene", + "ele": "$..objects[?(@.name=='노란 물고기')]", + "points": 1.6, + "desc": "문제 1/물고기/[개체] 이름 설정 2/이름을 '노란 물고기'로 변경하기", + "sort": 14 + }, + "1-5": { + "type": "scene", + "ele": "$..objects[?(@.name=='쓰레기')]", + "points": 1.6, + "desc": "문제 1/쓰레기/[개체] 이름 설정 3/이름 변경 없음", + "sort": 15 + }, + "1-6": { + "type": "scene", + "ele": "$..objects[?(@.name=='상어')]", + "points": 1.6, + "desc": "문제 1/상어(1)/[개체] 이름 설정 4/이름을 '상어'로 변경하기", + "sort": 16 + }, + "1-7": { + "type": "scene", + "ele": "$..variables[?(@.name=='물고기 수')]", + "points": 1, + "desc": "문제 2/빨간 물고기/변수/'물고기 수' 변수 만들기", + "sort": 101 + }, + "2-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'빨간 물고기')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/빨간 물고기/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "30", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[시작1]의 세부 동작 1/크기를 '30' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/만일/만일 '상어' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "1" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 1/'물고기 수'에 '1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][1].type", + "$[0][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.01" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 2/'0.01' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][2].type", + "answer": "hide", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][3].type", + "$[0][2].statements[0][0].statements[0][3].params[0].type", + "$[0][2].statements[0][0].statements[0][3].params[0].params[1].params[0]", + "$[0][2].statements[0][0].statements[0][3].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0.5", + "3" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 4/'0.5 부터 3 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][4].type", + "answer": "show", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[만일]의 세부 동작 5/모양 보이기" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/빨간 물고기/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_direction", + null + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[반복]의 세부 동작 1/이동 방향으로 '1 부터 2 사이의 무작위 수' 만큼 움직이기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[1].params[0]", + "$[1][1].statements[0][1].params[0].params[3].params[0]" + ], + "answer": [ + "direction_relative", + "calc_rand", + "-1", + "1" + ], + "points": 1.2, + "desc": "문제 2/빨간 물고기/[반복]의 세부 동작 2/이동 방향을 '-1 부터 1 사이의 무작위 수' 만큼 회전하기", + "type": "list" + }, + { + "ele": "$[1][1].statements[0][2].type", + "answer": "bounce_wall", + "points": 1.2, + "desc": "문제 2/빨간 물고기/[반복]의 세부 동작 3/화면 끝에 닿으면 튕기기" + } + ], + "sort": 102, + "list": [ + "set_scale_size", + "repeat_inf" + ] + }, + "3-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'노란 물고기|물고')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/노란 물고기/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "30", + "points": 1.2, + "desc": "문제 2/노란 물고기/[시작1]의 세부 동작 1/크기를 '30' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/만일/만일 '상어' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "2" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 1/물고기 수'에 '2' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][1].type", + "$[0][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.01" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 2/'0.01' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][2].type", + "answer": "hide", + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][3].type", + "$[0][2].statements[0][0].statements[0][3].params[0].type", + "$[0][2].statements[0][0].statements[0][3].params[0].params[1].params[0]", + "$[0][2].statements[0][0].statements[0][3].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0.5", + "1.5" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 4/'0.5' 부터 '1.5' 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][4].type", + "answer": "show", + "points": 1.2, + "desc": "문제 2/노란 물고기/[만일]의 세부 동작 5/모양 보이기" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/노란 물고기/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_direction", + null + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[반복]의 세부 동작 1/이동 방향으로 '1 부터 2 사이의 무작위 수' 만큼 움직이기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[1].params[0]", + "$[1][1].statements[0][1].params[0].params[3].params[0]" + ], + "answer": [ + "direction_relative", + "calc_rand", + "-1", + "1" + ], + "points": 1.2, + "desc": "문제 2/노란 물고기/[반복]의 세부 동작 2/이동 방향을 '-1 부터 1 사이의 무작위 수' 만큼 회전하기", + "type": "list" + }, + { + "ele": "$[1][1].statements[0][2].type", + "answer": "bounce_wall", + "points": 1.2, + "desc": "문제 2/노란 물고기/[반복]의 세부 동작 3/화면 끝에 닿으면 튕기기" + } + ], + "sort": 117, + "list": [ + "set_scale_size", + "repeat_inf" + ] + }, + "4-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'쓰레기')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/쓰레기/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "30", + "points": 1.2, + "desc": "문제 2/쓰레기/[시작1]의 세부 동작 1/크기를 '30' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/쓰레기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].type", + "$[0][2].statements[0][0].params[0].type" + ], + "answer": [ + "_if", + "reach_something" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/만일/만일 '상어' 에 닿았는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][0].type", + "$[0][2].statements[0][0].statements[0][0].params[1].params[0]" + ], + "answer": [ + "change_variable", + "-1" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 1/물고기 수'에 '-1' 만큼 더하기", + "type": "list" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][1].type", + "$[0][2].statements[0][0].statements[0][1].params[0].params[0]" + ], + "answer": [ + "wait_second", + "0.01" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 2/'0.01' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][2].type", + "answer": "hide", + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 3/모양 숨기기" + }, + { + "ele": [ + "$[0][2].statements[0][0].statements[0][3].type", + "$[0][2].statements[0][0].statements[0][3].params[0].type", + "$[0][2].statements[0][0].statements[0][3].params[0].params[1].params[0]", + "$[0][2].statements[0][0].statements[0][3].params[0].params[3].params[0]" + ], + "answer": [ + "wait_second", + "calc_rand", + "0.5", + "3" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 4/'0.5 부터 3 사이의 무작위 수' 초 기다리기", + "type": "list" + }, + { + "ele": "$[0][2].statements[0][0].statements[0][4].type", + "answer": "show", + "points": 1.2, + "desc": "문제 2/쓰레기/[만일]의 세부 동작 5/모양 보이기" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/쓰레기/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/쓰레기/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_direction", + null + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[반복]의 세부 동작 1/이동 방향으로 '1 부터 2 사이의 무작위 수' 만큼 움직이기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[1].params[0]", + "$[1][1].statements[0][1].params[0].params[3].params[0]" + ], + "answer": [ + "direction_relative", + "calc_rand", + "-1", + "1" + ], + "points": 1.2, + "desc": "문제 2/쓰레기/[반복]의 세부 동작 2/이동 방향을 '-1 부터 1 사이의 무작위 수' 만큼 회전하기", + "type": "list" + }, + { + "ele": "$[1][1].statements[0][2].type", + "answer": "bounce_wall", + "points": 1.2, + "desc": "문제 2/쓰레기/[반복]의 세부 동작 3/화면 끝에 닿으면 튕기기" + } + ], + "sort": 131, + "list": [ + "set_scale_size", + "repeat_inf" + ] + }, + "44-0": { + "ele": "$.messages[?(@.name=='성공')]", + "points": 1, + "desc": "문제 2/상어/신호/'성공'신호 만들기", + "type": "scene", + "sort": 144 + }, + "5-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'상어')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/상어/시작1/시작하기 버튼을 클릭했을 때" + }, + { + "ele": "$[0][1].params[0].params[0]", + "answer": "50", + "points": 1.2, + "desc": "문제 2/상어/[시작]의 세부 동작 1/크기를 '50' 으로 정하기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0].params[0]", + "$[0][2].params[1].params[0]" + ], + "answer": [ + "locate_xy", + "-100", + "0" + ], + "points": 1.2, + "desc": "문제 2/상어/[시작]의 세부 동작 2/x: '-100' y: '0' 위치로 이동하기", + "type": "list" + }, + { + "ele": [ + "$[0][3].type", + "$[0][3].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/상어/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[0][3].statements[0][0].type", + "$[0][3].statements[0][0].params[0].type", + "$[0][3].statements[0][0].params[0].params[0].type", + "$[0][3].statements[0][0].params[0].params[1]", + "$[0][3].statements[0][0].params[0].params[2].params[0]" + ], + "answer": [ + "_if", + "boolean_basic_operator", + "get_variable", + "GREATER", + "10" + ], + "points": 1.2, + "desc": "문제 2/상어/만일/만일 '물고기 수' 값 > '10' 이라면", + "type": "list" + }, + { + "ele": "$[0][3].statements[0][0].statements[0][0].type", + "answer": "message_cast", + "points": 1.2, + "desc": "문제 2/상어/[만일]의 세부 동작 1/성공' 신호보내기" + }, + { + "ele": [ + "$[0][3].statements[0][0].statements[0][1].type", + "$[0][3].statements[0][0].statements[0][1].params[0]" + ], + "answer": [ + "stop_object", + "thisOnly" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일]의 세부 동작 2/자신의' 코드 멈추기", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_run_button_click", + "points": 1.2, + "desc": "문제 2/상어/시작2/시작하기 버튼을 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]" + ], + "answer": [ + "repeat_inf", + null + ], + "points": 1.2, + "desc": "문제 2/상어/반복/계속 반복하기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].type", + "$[1][1].statements[0][0].params[0].type", + "$[1][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "37" + ], + "points": 1.2, + "desc": "문제 2/상어/만일1/만일 '왼쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][0].statements[0][0].type", + "$[1][1].statements[0][0].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_x", + "-5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일1]의 세부 동작 1/x 좌표를 '-5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].type", + "$[1][1].statements[0][1].params[0].type", + "$[1][1].statements[0][1].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "39" + ], + "points": 1.2, + "desc": "문제 2/상어/만일2/만일 '오른쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][1].statements[0][0].type", + "$[1][1].statements[0][1].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_x", + "5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일2]의 세부 동작 1/x 좌표를 '5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][2].type", + "$[1][1].statements[0][2].params[0].type", + "$[1][1].statements[0][2].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "38" + ], + "points": 1.2, + "desc": "문제 2/상어/만일3/만일 '위쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][2].statements[0][0].type", + "$[1][1].statements[0][2].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일3]의 세부 동작 1/y 좌표를 '5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][3].type", + "$[1][1].statements[0][3].params[0].type", + "$[1][1].statements[0][3].params[0].params[0]" + ], + "answer": [ + "_if", + "is_press_some_key", + "40" + ], + "points": 1.2, + "desc": "문제 2/상어/만일4/만일 '아래쪽 화살표' 키가 눌러져 있는가? 라면", + "type": "list" + }, + { + "ele": [ + "$[1][1].statements[0][3].statements[0][0].type", + "$[1][1].statements[0][3].statements[0][0].params[0].params[0]" + ], + "answer": [ + "move_y", + "-5" + ], + "points": 1.2, + "desc": "문제 2/상어/[만일4]의 세부 동작 1/y 좌표를 '-5' 만큼 바꾸기", + "type": "list" + }, + { + "ele": "$[2][0].type", + "answer": "when_message_cast", + "points": 1.2, + "desc": "문제 2/상어/신호/'성공' 신호를 받았을 때 " + }, + { + "ele": "$[2][1].params[*].params", + "answer": [ + "배부르다!", + "1" + ], + "points": 1.2, + "desc": "문제 2/상어/[신호]의 세부 동작 1/'배부르다!' 를 '1'초 동안 '말하기'" + }, + { + "ele": "$[2][2].type", + "answer": "start_neighbor_scene", + "points": 1.2, + "desc": "문제 2/상어/[신호]의 세부 동작 2/'다음' 장면 시작하기" + } + ], + "sort": 145, + "list": [ + "set_scale_size", + "repeat_inf", + "dialog_time" + ] + }, + "6-0": { + "type": "script", + "ele": "$.objects[?(@.name=~'바다2|바닷속\\(3\\)1')].script", + "blocks": [ + { + "ele": "$[0][0].type", + "answer": "when_scene_start", + "points": 1.2, + "desc": "문제 2/바다2/장면 2/장면이 시작되었을 때" + }, + { + "ele": "$[0][1].type", + "answer": "hide_variable", + "points": 1.2, + "desc": "문제 2/바다2/[장면 2]의 세부 동작 1/변수 '물고기 수' 숨기기" + }, + { + "ele": [ + "$[0][2].type", + "$[0][2].params[0].params[0]", + "$[0][2].params[1]" + ], + "answer": [ + "dialog", + "미션성공!", + "speak" + ], + "points": 1.2, + "desc": "문제 2/바다2/[장면 2]의 세부 동작 2/'미션성공!' 을 '말하기'", + "type": "list" + }, + { + "ele": "$[1][0].type", + "answer": "when_object_click", + "points": 2, + "desc": "문제 3/바다2/오브젝트/오브젝트를 클릭했을 때" + }, + { + "ele": [ + "$[1][1].type", + "$[1][1].params[0]", + "$[1][1].params[1].params[0]" + ], + "answer": [ + "add_effect_amount", + "color", + "30" + ], + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 1/'색깔' 효과를 '30' 만큼 주기", + "type": "list" + }, + { + "ele": [ + "$[1][2].type", + "$[1][2].params[0].params[0]", + "$[1][2].params[1]" + ], + "answer": [ + "dialog", + "처음부터 다시 실행!", + "speak" + ], + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 2/'처음부터 다시 실행!' 을 '말하기'", + "type": "list" + }, + { + "ele": [ + "$[1][3].type", + "$[1][3].params[0].params[0]" + ], + "answer": [ + "wait_second", + "2" + ], + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 3/'2' 초 기다리기", + "type": "list" + }, + { + "ele": "$[1][4].type", + "answer": "restart_project", + "points": 2, + "desc": "문제 3/바다2/[오브젝트]의 세부 동작 4/처음부터 다시 실행하기" + } + ], + "sort": 166, + "list": [ + "hide_variable", + "add_effect_amount" + ] + } +} \ No newline at end of file diff --git a/logs/cat.log b/logs/cat.log index 0bb2e61..66990b1 100644 --- a/logs/cat.log +++ b/logs/cat.log @@ -10,3 +10,19 @@ Traceback (most recent call last): points.insert(0, student_id) ^^^^^^^^^^ UnboundLocalError: cannot access local variable 'student_id' where it is not associated with a value +[2025-09-01 15:17:33] [ERROR] [main:299] 🚫Error processing ./output/2508_CAS_2_A/2508_CAS_2_A_정답\project.json: unsupported operand type(s) for +=: 'int' and 'NoneType' +Traceback (most recent call last): + File "D:\project\Entry\Entry-Scoring\main.py", line 294, in main + points = process_project(project_data, scoring_data) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\project\Entry\Entry-Scoring\main.py", line 162, in process_project + total_points += question_points +TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType' +[2025-09-01 15:17:34] [ERROR] [main:299] 🚫Error processing ./output/2508_CAS_2_B/2508_CAS_2_B_정답\project.json: unsupported operand type(s) for +=: 'int' and 'NoneType' +Traceback (most recent call last): + File "D:\project\Entry\Entry-Scoring\main.py", line 294, in main + points = process_project(project_data, scoring_data) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "D:\project\Entry\Entry-Scoring\main.py", line 162, in process_project + total_points += question_points +TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType' diff --git a/main.py b/main.py index 2221e45..6cd3afb 100644 --- a/main.py +++ b/main.py @@ -10,6 +10,8 @@ import logging from logging_config import setup_logging # logging 설정을 위한 import import traceback +from script_utils import extract_and_format_scripts # 스크립트 추출 함수 import + setup_logging() # logging 설정 호출 # JSON 파일 읽기 @@ -90,7 +92,7 @@ def swap_script(origin): elif block_type == "when_some_key_pressed": # params[1]에서 키 값 확인 (49, 50, 51) 아스키코드 값이므로 필요하면 추가 가능 key_value = block[0].get("params")[1] - if key_value in ["49", "50", "51"]: + if key_value in ["32","49","50","51"]: key_press_blocks.append((key_value, block)) elif block_type == "when_clone_start": clone_start_block = block @@ -135,100 +137,6 @@ def convert_to_str(value): return [convert_to_str(v) for v in value] return str(value) -# def process_project(project_data, scoring_data): - total_points = 0 - point_list = [] - - for key, question_info in scoring_data.items(): - element_path = question_info.get('ele') - type = question_info.get('type') - block_list = question_info.get('blocks') - answer = question_info.get('answer') - points = question_info.get('points') - - print(f"example: {key}") - if type == "scene": - found_elements = find_element(project_data, element_path) - if found_elements: - print(f"🟨 Elements found for {element_path}") - # scene type의 경우 문자열 변환 - found_elements = [convert_to_str(x) for x in found_elements] - if found_elements == answer: - total_points += points - point_list.append(points) - - elif found_elements and answer == None: - total_points += points - point_list.append(points) - print(f"{element_path} found ") - else: - point_list.append(0) - print(f"{found_elements} not found") - else: - print(f"🟥 Element '{element_path}' not found") - point_list.append(0) - - # 스크립트 타입의 경우 - # 스크립트 블록을 찾고, 블록 내의 요소를 확인 - # 블록 내의 요소를 확인하고, 정답과 비교하여 점수 계산 - if type == "script": - script_raw = find_script_element(project_data, element_path) - - if script_raw == None: - script_data = None - else: - script_data = json.loads(script_raw) - script_data = swap_script(script_data) - - block_index = 1 - for block in block_list: - block_type = block.get('type') - - if script_data == None: - print(f"{key}-{block_index}: Script Not exist") - point_list.append("확인 필요") - continue - - elif block_type == "list": - block_elements = find_list_element(script_data, block.get('ele')) - else: - block_elements = find_element(script_data, block.get('ele')) - - answer = block.get('answer', None) - - if block_elements and isinstance(answer, list): - # 리스트의 모든 요소를 문자열로 변환 - flat_matches = [convert_to_str(x) for x in list(chain.from_iterable(block_elements))] - else: - if not block_elements: - flat_matches = None - else: - # 단일 값을 문자열로 변환 - flat_matches = convert_to_str(block_elements[0]) - - if block_elements: - # answer도 문자열로 변환하여 비교 - str_answer = convert_to_str(answer) if answer is not None else None - if answer is not None and str_answer != flat_matches: - print(f"{key}-{block_index}: {str_answer} != {flat_matches}") - point_list.append(0) - elif answer is not None and str_answer == flat_matches: - print(f"{key}-{block_index}: {str_answer} == {flat_matches}") - total_points += block.get('points') - point_list.append(block.get('points')) - elif answer is None and block_elements: - total_points += block.get('points') - point_list.append(block.get('points')) - print(f"{key}-{block_index}: exist ele: {block_elements}") - else: - print(f"No elements found for {block.get('ele')}") - point_list.append(0) - - block_index = block_index + 1 - - point_list.append(total_points) - return point_list - def process_project(project_data, scoring_data): total_points = 0 score_list = [] @@ -264,8 +172,8 @@ def process_project(project_data, scoring_data): # ✅ SCRIPT TYPE 처리 elif question_type == "script": script_raw = find_script_element(project_data, element_path) - script_data_1 = json.loads(script_raw) if script_raw else None - script_data = swap_script(script_data_1) if script_data_1 else None + script_json = json.loads(script_raw) if script_raw else None + script_data = swap_script(script_json) if script_json else None block_index = 1 for block in block_list: @@ -321,82 +229,88 @@ def normalize_path(path): """한글 경로명을 NFC 방식으로 정규화""" return unicodedata.normalize('NFC', path) - + def main(): - # 파일 경로 설정 - project_json_path = './output/2507_CAT_3_A/' - # project_json_path = './output/00_test/' - scoring_json_path = './correct/2507_CAT_3_A.json' - - scoring_data = read_json(scoring_json_path) - student_score_list = [] - - # 컬럼명 생성 - columns = ['학생명'] - idx = 1 - for key in scoring_data.keys(): - if scoring_data[key].get('type') == 'scene': - columns.append(f'{idx}') - idx = idx + 1 - elif scoring_data[key].get('type') == 'script': - for i in range(len(scoring_data[key].get('blocks', []))): - columns.append(f'{idx}') - idx = idx + 1 - - columns.append('총점') - - # os.walk 결과를 리스트로 변환하고 정렬 - walk_results = [] - for root, dirs, files in os.walk(project_json_path): - # 디렉토리명 정규화 - normalized_root = normalize_path(root) - normalized_dirs = [normalize_path(d) for d in dirs] - normalized_files = [normalize_path(f) for f in files] - - normalized_dirs.sort() # 정규화된 디렉토리 정렬 - walk_results.append((normalized_root, normalized_dirs, normalized_files)) - - # 정렬된 결과를 바탕으로 처리 - for root, dirs, files in sorted(walk_results): - for file in sorted(files): # 파일도 정렬 - if file == 'project.json': - full_path = os.path.join(root, file) - print(f"\nProcessing: {full_path}") - try: - # 디렉토리 패스 내에 학생 이름만 뽑아서 엑셀 컬럼 명으로 추가 - # output/cas-000040-이지원/temp/project.json - # student_id = normalize_path(full_path.split('/')[3]) - match = re.search(r'(\d{6}[-_][^\\/]+)[\\/]', full_path) - if match: - student_id = match.group(1) - else: - if '정답' in full_path: - student_id = '정답' - else: - student_id = '000000' - - # project.json 파일 내용 - project_data = read_json(full_path) - points = process_project(project_data, scoring_data) - points.insert(0, student_id) - student_score_list.append(points) - print(f"Total Points for {points}") - except Exception as e: - # print(traceback.format_exc()) - logging.exception(f"🚫Error processing {full_path}: {str(e)}") - continue - - # DataFrame 생성 및 엑셀 저장 - df = pd.DataFrame(student_score_list, columns=columns).transpose() - df.columns = df.iloc[0] - df = df[1:] - timestamp = datetime.now().strftime("%y%m%d") + test_mode = False # 테스트 모드 설정 + # test_mode = True # 테스트 모드 설정 + exam_round = "2508" + exam_names = ["CAS_2_A", "CAS_2_B"] # 여러 시험명을 리스트로 설정 + excel_list = [] - excel_path = f'{project_json_path}/{timestamp}_results.xlsx' - - df.to_excel(excel_path, index=False) - print(f"\nResults saved to {excel_path}") - + for exam_name in exam_names: + scoring_json_path = f'./correct/{exam_round}_{exam_name}.json' + project_json_path = f'./output/{"00_test" if test_mode else exam_round+"_"+exam_name}/' + excel_path = f'{timestamp}_{exam_round}_{exam_name}_{"TEST" if test_mode else "채점결과"}.xlsx' + + scoring_data = read_json(scoring_json_path) + student_score_list = [] + + # 컬럼명 생성 + columns = ['학생명'] + idx = 1 + for key in scoring_data.keys(): + if scoring_data[key].get('type') == 'scene': + columns.append(f'{idx}') + idx = idx + 1 + elif scoring_data[key].get('type') == 'script': + for i in range(len(scoring_data[key].get('blocks', []))): + columns.append(f'{idx}') + idx = idx + 1 + + columns.append('총점') + + # os.walk 결과를 리스트로 변환하고 정렬 + walk_results = [] + for root, dirs, files in os.walk(project_json_path): + # 디렉토리명 정규화 + normalized_root = normalize_path(root) + normalized_dirs = [normalize_path(d) for d in dirs] + normalized_files = [normalize_path(f) for f in files] + + normalized_dirs.sort() # 정규화된 디렉토리 정렬 + walk_results.append((normalized_root, normalized_dirs, normalized_files)) + + # 정렬된 결과를 바탕으로 처리 + for root, dirs, files in sorted(walk_results): + for file in sorted(files): # 파일도 정렬 + if file == 'project.json': + full_path = os.path.join(root, file) + print(f"\nProcessing: {full_path}") + try: + # 디렉토리 패스 내에 학생 이름만 뽑아서 엑셀 컬럼 명으로 추가 + match = re.search(r'(\d{6}[-_][^\\/]+)[\\/]', full_path) + if match: + student_id = match.group(1) + else: + if '정답' in full_path: + student_id = '정답' + else: + student_id = '000000' + + # project.json 파일 내용 + project_data = read_json(full_path) + if project_data: + extract_and_format_scripts(project_data, root) + points = process_project(project_data, scoring_data) + points.insert(0, student_id) + student_score_list.append(points) + print(f"Total Points for {points}") + except Exception as e: + logging.exception(f"🚫Error processing {full_path}: {str(e)}") + continue + + # DataFrame 생성 및 엑셀 저장 + df = pd.DataFrame(student_score_list, columns=columns).transpose() + df.columns = df.iloc[0] + df = df[1:] + + df.to_excel(excel_path, index=False) + + excel_list.append(excel_path) + + if excel_list: + print(f"\nResults saved to {excel_list}") + if __name__ == "__main__": main() \ No newline at end of file diff --git a/script_utils.py b/script_utils.py new file mode 100644 index 0000000..fb772c2 --- /dev/null +++ b/script_utils.py @@ -0,0 +1,78 @@ +import os +import json + +def extract_and_format_scripts(project_data, output_directory="script_outputs"): + """ + 읽어온 project_data에서 각 객체의 스크립트를 추출하여 + 별도의 포맷팅된 JSON 파일로 저장합니다. + + :param project_data: read_json을 통해 읽어온 딕셔너리 데이터 + :param output_directory: 결과 파일을 저장할 폴더 이름 + """ + if not project_data: + print("오류: 유효한 프로젝트 데이터가 없습니다.") + return + + # 결과물을 저장할 폴더 생성 (없으면) + if not os.path.exists(output_directory): + os.makedirs(output_directory) + print(f"'{output_directory}' 폴더를 생성했습니다.") + + objects_list = project_data.get("objects", []) + + for obj in objects_list: + object_name = obj.get("name") + script_string = obj.get("script") + + # 객체 이름과 스크립트 문자열이 모두 유효한 경우에만 처리 + if object_name and script_string: + try: + # 1. 스크립트 문자열을 파이썬 객체(리스트)로 파싱 + script_data = json.loads(script_string) + + # 2. 저장할 파일 경로 설정 + file_name = f"{object_name}.json" + output_path = os.path.join(output_directory, file_name) + + # 3. 보기 좋은 형태의 JSON 파일로 저장 + with open(output_path, 'w', encoding='utf-8') as f: + json.dump(script_data, f, indent=2, ensure_ascii=False) + + print(f"성공: '{output_path}' 파일이 생성되었습니다.") + + except json.JSONDecodeError: + print(f"주의: '{object_name}'의 스크립트는 비어있거나 파싱할 수 없어 건너뜁니다.") + except Exception as e: + print(f"오류: '{object_name}' 스크립트 처리 중 예외 발생 - {e}") + + +def read_json(file_path): + """ JSON 파일을 읽어 Python dict 로 반환 """ + if not os.path.exists(file_path): + print(f"오류: 파일 '{file_path}' 을(를) 찾을 수 없습니다.") + return None + try: + with open(file_path, "r", encoding="utf-8") as f: + return json.load(f) + except Exception as e: + print(f"JSON 읽기 오류: {e}") + return None + +def main(): + # base_dir을 코드 내에서 직접 지정 + base_dir = r".\output\2508_CAS_2_B" # 원하는 최상위 디렉토리 경로로 수정하세요 + + # 하위 디렉토리 순회 + for root, dirs, files in os.walk(base_dir): + if "project.json" in files: + json_path = os.path.join(root, "project.json") + output_directory = root # project.json이 있는 동일한 경로 + + print(f"▶ Processing: {json_path}") + project_data = read_json(json_path) + if project_data: + extract_and_format_scripts(project_data, output_directory) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/시험자료/2507/250801_2507_CAT_3_A_채점결과.xlsx b/시험자료/2507/250801_2507_CAT_3_A_채점결과.xlsx new file mode 100644 index 0000000..e217d3a Binary files /dev/null and b/시험자료/2507/250801_2507_CAT_3_A_채점결과.xlsx differ diff --git a/시험자료/2507/250804_2507_CAT_3_A_채점결과.xlsx b/시험자료/2507/250804_2507_CAT_3_A_채점결과.xlsx new file mode 100644 index 0000000..dde2718 Binary files /dev/null and b/시험자료/2507/250804_2507_CAT_3_A_채점결과.xlsx differ diff --git a/시험자료/2507/250805_2507_CAT_3_A_채점결과.xlsx b/시험자료/2507/250805_2507_CAT_3_A_채점결과.xlsx new file mode 100644 index 0000000..9b43449 Binary files /dev/null and b/시험자료/2507/250805_2507_CAT_3_A_채점결과.xlsx differ