경기 대진과 악기 파트가 한 번의 회전으로 정해진다 — 모둠 랜덤 추첨기 & 기록 시트 완전 정복
🏃 체육 경쟁 활동(피구, 이어달리기 토너먼트)과 음악 기악 합주(리코더·실로폰 파트 분담)에서 공정한 순서 추첨이 필요할 때가 있습니다. 단일 HTML 추첨기가 대진표(경기 순서)와 악기 파트를 랜덤으로 정하고, 결과는 CSV 내보내기로 로컬 파일에 기록됩니다(자동 외부 전송 없음 — 학급 시트 옮겨 적기는 교사 수동).
공정하고 투명한 모둠 운영은 학생 간 갈등을 예방하고, 전자칠판 앞에서 울리는 추첨 사운드가 수업 시작의 신호가 됩니다. 서버·설치 없이 단일 HTML 더블클릭으로 완결되며, 실명 칸은 없습니다(번호·닉네임).
📖 한 줄 정의
심기 모드(데이터 임베딩): API 데이터를 미리 받아 HTML 파일 안 상수로 박아두는 방식(앱 실행 중 외부 통신 0).
학내망 원칙: 학교 배포 웹앱은 개인정보 수집·저장·전송 없음(외부 CDN·API 호출 0, 단일 파일) — 학생은 학내망에서 교사 PC 서버에 접속.
1. 3대 핵심 분석 비교표
| 무엇이 바뀌었나요? / 영역 | 초보자를 위한 쉬운 설명 | 이렇게 한번 써보세요! |
|---|---|---|
| 경기 대진표 추첨 | 모둠 번호를 셔플(shuffle, 섞기) 알고리즘으로 섞어 토너먼트 대진표를 만듭니다. 이전 경기에서 직접 맞붙은 모둠은 자동으로 피해 배정됩니다. | 피구·이어달리기 모드를 골라 각각 대진표 생성. |
| 악기 파트 분담 | 리코더·실로폰·우치·타악 파트를 모둠 구성원에게 랜덤 배분합니다. 직전 합주 때 맡았던 파트는 자동 제외해 공정성을 높입니다. | '파트 추첨' 버튼으로 모둠별 악기 배치표 확인. |
| 결과 기록 | 경기 결과와 합주 체크리스트는 CSV 내보내기로 로컬 파일에 누적됩니다 — 자동 외부 전송 없음(학급 시트 관리는 교사 수동). | 주간 기록 CSV 내보내기 → 교사가 학급 시트에 붙여넣기. |
| 개인정보 설계 | 실명 입력·저장 칸 없음 — 번호·닉네임만 다룹니다. 모든 데이터는 학내망 안에서 완결됩니다. | 모둠 닉네임을 파일 상단 상수로 심기(외부 통신 0). |
2. 핵심 아키텍처 해설
① 셔플(shuffle, 섞기) 알고리즘
function shuffle(list) {
const a = list.slice();
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const t = a[i]; a[i] = a[j]; a[j] = t;
}
return a;
}
const bracket = shuffle([1, 2, 3, 4]); // 예: [3, 1, 4, 2]
마지막 칸부터 하나씩 뽑아 앞쪽과 자리를 바꾸는 방식 — 모든 순서가 나올 확률이 같아 공정합니다. 뽑기·제비뽑기의 디지털 버전입니다.
② 악기 파트 배분
const PARTS = ["리코더", "실로폰", "우치", "타악"];
function assignParts(group) {
const last = group.lastParts || [];
const pool = PARTS.filter(function (p) {
return last.indexOf(p) === -1;
});
const picked = shuffle(pool.length >= PARTS.length ? PARTS : pool.concat(PARTS));
return picked.slice(0, group.members.length);
}
직전 합주에 맡았던 파트를 후보에서 빼고, 남은 파트를 셔플로 배분합니다. 구성원이 파트보다 많으면 여럿이 한 파트를 나눠 맡습니다.
③ 경기 결과·체크리스트 기록
function recordRow(kind, round, a, b, result) {
return kind + "," + round + "," + a + "," + b + "," + result;
}
// CSV 내보내기 버튼으로 로컬 파일 저장 — 자동 외부 전송 없음
경기 결과(승·패)와 합주 체크리스트(연습 완료 여부)는 한 줄씩 누적되고, 'CSV 내보내기'로 로컬 파일이 만들어집니다. 학급 시트로 옮기는 것은 교사의 수동 관리 — 앱은 외부로 아무것도 보내지 않습니다.
④ 운영 체크리스트
- 추첨 결과는 전자칠판에 큰 글씨로 표기 — 모둠이 스스로 확인하며 불만이 대화로 바뀝니다.
- '다시 돌리기'는 학급 회의 안건으로 — 추첨의 재현은 규칙 논의의 시작점입니다.
- 새 모둠 닉네임이 생기면 파일 상단 상수를 갱신(심기 루틴)합니다.
3. 따라하기 3단계
- 제미나이 전용 에러 제로 프롬프트를 복사해 Gemini에 붙여넣습니다.
- AI가 던지는 역질문 3가지(경기 종류, 합주 파트 구성, 기록 서식)에 답하면 단일 HTML 코드가 완성됩니다.
- 코드를
draw.html로 저장 후 더블클릭 — 체육 시간엔 대진 추첨, 음악 시간엔 파트 추첨으로 전환합니다.
제미나이 전용 에러 제로 프롬프트
[🚨 에러 방지 기본 안전장치]
1. 결과물은 외부 라이브러리·폰트·이미지 없이 단일 HTML 파일로 완성한다 — 더블클릭 즉시 실행(서버·설치·회원가입·외부 클라우드·구글 시트 API 금지).
2. 모둠·학생 표기는 번호·닉네임만 다룬다(실명 입력·저장 금지) — 파일 상단 EMBED_GROUPS 상수로 심기(학내망 배포용 외부 통신 0).
3. 셔플은 마지막 칸부터 교환하는 방식(모든 순서가 같은 확률)으로 직접 구현한다.
4. 공정 규칙: 직전 경기에서 맞붙은 모둠 피하기, 직전 합주 파트 제외 — 제외 로직은 화면에 표시해 투명하게.
5. 경기 결과·합주 체크리스트는 CSV 내보내기로 로컬 파일 저장 — 자동 외부 전송 없음(학급 시트는 교사 수동).
6. 전자칠판 대형 터치 대응: 추첨 버튼 88px 이상, 대진표 큰 글씨. 추첨 사운드는 Web Audio API 합성('웅-딩').
7. // TODO, /* 생략 */ 금지 — 끝까지 완성한다.
[❓ 역질문 유도]
코드를 바로 만들지 말고, 아래 3가지를 먼저 질문한 뒤 내 답변으로 설계를 확정한다.
Q1. 경기 종류는? (피구 토너먼트 / 이어달리기 릴레이 순서 / 둘 다)
Q2. 합주 파트는? (리코더·실로폰·우치·타악 / 우리 학교 악기 구성)
Q3. 기록 CSV 서식은? (종류,회차,모둠A,모둠B,결과 기본)🎯 에디터 한줄평
'누구랑 경기하지?'라는 문제가 회전 한 번으로 끝나는 순간, 수업 앞 5분이 통째로 돌아옵니다. 핵심은 제외 규칙이 화면에 보이는 설계입니다 — 규칙이 보이면 불만은 논쟁이 아니라 제안이 됩니다("이번엔 2연전 금지도 넣자!"). 체육과 음악이 같은 추첨기를 공유하는 순간, '공정'은 교과를 넘나드는 우리 반의 공용 언어가 됩니다.
📚 기술·교육 참고 링크
- MDN — Web Audio API : 추첨 사운드 합성 원리
- 교육과정 연계: 체육(경쟁 활동 대진), 음악(기악 합주 파트), 실과(SW 활용) 단원으로 확장