Five stages of holding the line; this one lets you attack. An enemy eagle sits at the top behind steel, and a player shell that reaches it ends the stage at once for 1000 - enemy shells cannot touch it, so the stage cannot clear itself. Reaching it needs the mirrors. A shell entering one turns 90 degrees, capped at five turns and stepped one cell past the mirror so it cannot re-enter the same one. The eagle's only opening is a bullet-only shaft at column 8, walled in steel and fed by a "/" mirror below it, so only a shot travelling right along row 6 banks up into it; shooting left or from underneath deflects away. Mirrors block tanks and cannot be broken, and they block the enemies' line of sight so they do not waste shots. The clear/win paths were one block inside afterKill; they are now clearStage(bonus, note) so the snipe and the last kill share them. Checked headlessly: the snipe lands and pays 1000, the shaft saw 0 tank samples against 639 bullet samples, 6 idle runs left the enemy eagle standing, and closing r11's centre brought the base through 6 of 10 idle runs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
crossword
문학 가로세로 낱말풀이 — 정적 사이트. 왼쪽 탭에서 편을 골라 본 프레임에서 바로 푼다. 낱말풀이 목록 아래 휴게실 구획에는 곁들이로 탱크게임을 두었다.
- 공개 주소: https://crossword.plpark.ectech.co.kr
- 내부 주소: http://192.168.0.216:31380 (NodePort)
수록 편
| 탭 | 경로 | 격자 | 항목 |
|---|---|---|---|
| 한국 문학 | /korean.html |
9 × 9 · 41칸 | 15 |
| 러시아 문학 | /russian.html |
9 × 9 · 40칸 | 13 |
| 영국 문학 | /british.html |
9 × 9 · 39칸 | 12 |
| 프랑스 문학 | /french.html |
9 × 9 · 40칸 | 15 |
| 독일 문학 | /german.html |
9 × 9 · 41칸 | 14 |
| 일본 문학 | /japanese.html |
9 × 9 · 44칸 | 14 |
기본으로 열리는 탭은 한국 문학이다. 각 페이지는 단독으로 열어도 동작한다. 셸(/)의 탭은 해시로 상태를 남기므로
/#korean, /#russian, /#british, /#french, /#german, /#japanese, /#tank 로 바로 들어갈 수 있고, 탭을 다시 눌러도 풀던 내용은 유지된다.
휴게실 탱크게임의 단계별 진입은 /#tank1, /#tank2, /#tank3 이다.
휴게실
| 탭 | 경로 | 단계 | 적 | 특징 |
|---|---|---|---|---|
| 탱크게임 | /tank.html |
1단계 요새 | 4대 (동시 3) | 벽돌 밀도 25%, 넓은 기동 공간 |
| ↳ | /tank.html#2 |
2단계 미로 | 6대 (동시 4) | 밀도 43%, 1칸 폭 통로가 얽힌 미로 |
| ↳ | /tank.html#3 |
3단계 강철 회랑 | 8대 (동시 4) | 강철 31칸, 기지 외곽 2중 + 좁은 진입로 |
| ↳ | /tank.html#4 |
4단계 참호 | 10대 (동시 4) | 물길 + 보급 상자(시간 정지 / 기지 강화) |
| ↳ | /tank.html#5 |
5단계 최후 방어선 | 12대 (동시 5) | 숲(은폐) + 화력 강화 상자 + 지휘 탱크 |
| ↳ | /tank.html#6 |
6단계 거울 요새 | 12대 (동시 4) | 반사판(포탄 90° 꺾임) + 적 본진 습격 |
방향키 이동, 스페이스 발사. 한 단계를 돌파하면 다음 단계로 이어지고, 점수와 남은 탱크를 그대로 가져간다. 단계를 거치지 않고 바로 들어가는 방법은 셋이다.
- 왼쪽 탭의
휴게실 > 탱크게임아래 단계 칩 (셸 주소로는/#tank2…/#tank6) - 게임 화면 오른쪽 아래의 단계 버튼, 또는
1~6키 - 주소 직접 입력 —
/tank.html#6,/tank.html?stage=6(범위를 벗어난 값은 1단계)
특수 요소
3단계까지는 지형만 달라지지만 4단계부터는 규칙이 하나씩 붙는다. 단계에 들어갈 때
시작 화면 세 번째 줄과 오른쪽 특수 요소 칸에 그 단계에 걸린 규칙이 나오고, 앞
단계를 돌파한 화면에서는 다음 단계의 규칙을 미리 알려 준다.
| 요소 | 동작 | 쓰인 단계 |
|---|---|---|
물길 W |
탱크는 건널 수 없고 포탄은 넘어간다. 건너려면 도선(ford)으로 돌아야 한다 | 4 |
숲 F |
탱크도 포탄도 지나가지만 잎이 탱크를 덮어 가린다. 매복이 된다 | 5 |
| 보급 상자 | 일정 주기로 빈 칸에 하나 놓인다. 밟으면 효과 + 50점 | 4, 5 |
| ↳ 시간 정지 | 적 전원이 3초간 멈춘다 (포탄은 계속 난다) | 4, 5 |
| ↳ 기지 강화 | 기지 외곽 5칸이 10초간 강철이 된다. 끝나면 벽돌로 돌아오며 부서졌던 칸도 메워진다 | 4, 5 |
| ↳ 화력 강화 | 10초간 동시 3발 + 탄속 1.35배 | 5 |
| 지휘 탱크 | 편성 마지막에 나오는 대장. 체력 3, 빠르고 연사가 잦다. 격파 300점 | 5, 6 |
반사판 / \ |
포탄이 맞으면 90° 꺾인다. 탱크는 못 지나가고 부술 수도 없다. 한 포탄이 5번까지 꺾인다 | 6 |
적 본진 X |
위쪽 강철 안에 갇힌 적 독수리. 아군 포탄으로 부수면 적을 다 잡지 않아도 즉시 클리어(+1000점). 적 포탄은 제 본진을 부수지 못한다 | 6 |
효과가 걸린 동안에는 화면 왼쪽 위에 남은 시간이 배지로 표시된다.
6단계 저격 경로
적 본진 (8,2) 위·좌·우는 강철이고, 아래 (8,3)~(8,5) 는 좌우가 강철로 막힌
탄도 전용 갱도다. 그 아래 (8,6) 에 반사판 / 이 있어, 6행을 따라 오른쪽으로
쏜 포탄만 위로 꺾여 갱도를 타고 본진에 닿는다. 왼쪽으로 쏘면 아래로, 아래에서 위로
쏘면 오른쪽으로 꺾이므로 각을 맞춰야 한다. 아군 출발점 (5,13) 에서 6열을 따라 위로
올라가면 사격 위치가 나온다.
낱말풀이와 공유하는 자산이 없는 단독 페이지다. 캔버스와 WebAudio 만 쓰므로 자산 해시
스탬프(아래 캐시 항목)의 영향도 받지 않는다. iframe 안에서는 화면을 한 번 클릭해
포커스를 준 뒤 키를 눌러야 한다. 셸이 iframe 의 조각(#2)만 바꿀 때는 문서가 다시
읽히지 않으므로, 게임 쪽에서 hashchange 를 받아 단계를 바꾼다.
구성
| 경로 | 설명 |
|---|---|
site/index.html |
셸 — 왼쪽 탭(좁은 화면에서는 위쪽 탭) + 게임을 띄우는 iframe |
site/korean.html |
한국 문학 편 (머리말 + 퍼즐 데이터) — 기본 탭 |
site/russian.html |
러시아 문학 편 (머리말 + 퍼즐 데이터) |
site/british.html |
영국 문학 편 (머리말 + 퍼즐 데이터) |
site/french.html |
프랑스 문학 편 (머리말 + 퍼즐 데이터) |
site/german.html |
독일 문학 편 (머리말 + 퍼즐 데이터) |
site/japanese.html |
일본 문학 편 (머리말 + 퍼즐 데이터) |
site/tank.html |
휴게실 · 탱크게임 (단독 페이지 — 캔버스 + WebAudio) |
site/assets/crossword.css |
각 편이 공유하는 화면 양식 |
site/assets/crossword.js |
각 편이 공유하는 게임 엔진 (한글 IME 입력, 검사/힌트/타이머) |
nginx/default.conf |
nginx 설정 (8080 리슨, /healthz 헬스체크) |
Dockerfile |
자산 URL 에 내용 해시를 박는 단계 + nginx:1.27-alpine 정적 서빙 |
k8s/deployment.yaml |
Deployment + NodePort Service (31380) |
Jenkinsfile |
Checkout → 이미지 빌드/푸시 → kubectl apply |
Spring Boot 등 런타임은 없음. HTML/CSS/JS 만으로 동작하는 완전 정적 사이트라 nginx 로 파일만 내려주면 끝.
편을 추가할 때
site/<편>.html을 기존 편 하나를 복사해 만든다. 고칠 곳은<title>, 머리말(.eyebrow/h1), 그리고const PUZZLE = {...}뿐이다.site/index.html의PAGES객체와.nav링크에 한 줄씩 추가한다.
PUZZLE 규약:
size— 격자 한 변 (9)grid[r][c]— 정답 음절, 빈 칸은nullnums[r][c]— 칸에 찍히는 번호, 없으면0. 길이 2 이상 구간의 시작 칸에 좌→우 · 위→아래 순서로 붙인다entries[]—{num, dir:"A"|"D", r, c, answer, clue, kind}
가로·세로로 길이 2 이상 이어지는 모든 구간은 반드시 entries 에 단서와 함께
등록돼 있어야 한다. 우연히 생긴 두 글자 구간이 남아 있으면 그 칸을 채워도
완료 판정이 나지 않는 것처럼 보이므로, 격자를 새로 짜면 이 조건을 먼저 확인한다.
단서를 쓸 때는 다른 항목의 정답을 단서 안에 그대로 적지 않는다. 서로가 서로를
알려 주면 두 칸이 한꺼번에 풀려 버린다. 한 정답이 다른 정답에 통째로 들어가는 짝
(소세키 / 나쓰메소세키) 도 한 격자에 같이 두지 않는다.
낱말 풀은 작품과 작가만으로는 성글다. 특히 원어 표기의 음절이 서로 겹치지 않는 편(독일 편)에서는 등장인물과 작품 속 핵심어까지 넣어야 교차 지점이 생긴다.
캐시
프록시(NPM)가 js / css 응답에 제 캐시 헤더를 덧붙인다. 원본 nginx 가
no-cache 를 줘도 덮어써지므로, 브라우저가 옛 자산을 계속 쓰는 일을 막기 위해
이미지 빌드 때 자산 URL 에 내용 해시를 박는다.
Dockerfile의stamp단계가crossword.css+crossword.js의 sha256 앞 열 자리를 뽑아 각 페이지의 링크를assets/crossword.js?v=<해시>로 바꾼다- 자산 내용이 바뀌면 해시가 바뀌고 URL 도 바뀌므로 캐시가 저절로 무효화된다
- 저장소의 HTML 은 해시 없는 상태로 두면 된다. 손으로 붙일 필요 없다
- HTML 자체는 프록시가 캐시하지 않으므로 새 해시가 바로 전달된다
배포
Jenkins 잡(crossword)을 돌리면 아래가 순서대로 진행된다.
- gitea
plpark/crosswordmain 브랜치 체크아웃 gitea.plpark.ectech.co.kr/plpark/crossword:<BUILD_NUMBER>빌드 & 푸시plpark-int-ns네임스페이스에 apply, rollout 대기
Jenkins credentials 는 기존 loggen/pilot1 과 동일하게
gitea-registry(usernamePassword), rancher-kubeconfig(file) 를 사용한다.
프록시 (NPM)
https://npm.ectech.co.kr 에서 Proxy Host 추가:
- Domain Names:
crossword.plpark.ectech.co.kr - Scheme:
http - Forward Hostname / IP:
192.168.0.216 - Forward Port:
31380 - Block Common Exploits / Websockets Support: ON
- SSL: Let's Encrypt 발급 + Force SSL + HTTP/2
콘텐츠 수정
site/ 아래만 고치고 커밋 → Jenkins 빌드. 그 외 변경 필요 없음.