Files
crossword/README.md
T
plparkandClaude Opus 5 5b2d6e10da Add German literature puzzle
셸에 독일 문학 탭을 더하고 site/german.html 을 추가했다. 9x9 41칸 14항목.

독일어 표기는 음절이 서로 겹치지 않아 격자가 성글게 나온다. 그래서 낱말 풀을
작품·작가에서 등장인물과 작품 속 핵심어까지 넓혀 교차 지점을 확보했다.
(로테, 헨젤, 카스토르프, 나르치스 같은 인물과 벌레·계약·향기 같은 핵심어)

격자는 기존 두 편과 같은 규약을 만족한다. 길이 2 이상 모든 구간이 단서가 붙은
항목과 일대일로 대응하고, 어떤 단서도 다른 항목의 정답을 그대로 담지 않는다.

탭이 셋이 되면서 아주 좁은 화면(560px 이하)에서는 상표를 접고 탭에 폭을 넘긴다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 14:03:09 +09:00

83 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# crossword
문학 가로세로 낱말풀이 — 정적 사이트. 왼쪽 탭에서 편을 골라 본 프레임에서 바로 푼다.
- 공개 주소: https://crossword.plpark.ectech.co.kr
- 내부 주소: http://192.168.0.216:31380 (NodePort)
## 수록 편
| 탭 | 경로 | 격자 | 항목 |
|---|---|---|---|
| 러시아 문학 | `/russian.html` | 9 × 9 · 40칸 | 13 |
| 영국 문학 | `/british.html` | 9 × 9 · 39칸 | 12 |
| 독일 문학 | `/german.html` | 9 × 9 · 41칸 | 14 |
각 페이지는 단독으로 열어도 동작한다. 셸(`/`)의 탭은 해시로 상태를 남기므로
`/#russian`, `/#british`, `/#german` 으로 바로 들어갈 수 있고, 탭을 다시 눌러도 풀던 내용은 유지된다.
## 구성
| 경로 | 설명 |
|---|---|
| `site/index.html` | 셸 — 왼쪽 탭(좁은 화면에서는 위쪽 탭) + 게임을 띄우는 iframe |
| `site/russian.html` | 러시아 문학 편 (머리말 + 퍼즐 데이터) |
| `site/british.html` | 영국 문학 편 (머리말 + 퍼즐 데이터) |
| `site/german.html` | 독일 문학 편 (머리말 + 퍼즐 데이터) |
| `site/assets/crossword.css` | 각 편이 공유하는 화면 양식 |
| `site/assets/crossword.js` | 각 편이 공유하는 게임 엔진 (한글 IME 입력, 검사/힌트/타이머) |
| `nginx/default.conf` | nginx 설정 (8080 리슨, `/healthz` 헬스체크) |
| `Dockerfile` | nginx:1.27-alpine 정적 서빙 이미지 |
| `k8s/deployment.yaml` | Deployment + NodePort Service (31380) |
| `Jenkinsfile` | Checkout → 이미지 빌드/푸시 → kubectl apply |
Spring Boot 등 런타임은 없음. HTML/CSS/JS 만으로 동작하는 완전 정적 사이트라
nginx 로 파일만 내려주면 끝.
## 편을 추가할 때
1. `site/<편>.html` 을 기존 편 하나를 복사해 만든다. 고칠 곳은 `<title>`,
머리말(`.eyebrow` / `h1`), 그리고 `const PUZZLE = {...}` 뿐이다.
2. `site/index.html` 의 `PAGES` 객체와 `.nav` 링크에 한 줄씩 추가한다.
`PUZZLE` 규약:
- `size` — 격자 한 변 (9)
- `grid[r][c]` — 정답 음절, 빈 칸은 `null`
- `nums[r][c]` — 칸에 찍히는 번호, 없으면 `0`. 길이 2 이상 구간의 시작 칸에
좌→우 · 위→아래 순서로 붙인다
- `entries[]` — `{num, dir:"A"|"D", r, c, answer, clue, kind}`
**가로·세로로 길이 2 이상 이어지는 모든 구간은 반드시 `entries` 에 단서와 함께
등록돼 있어야 한다.** 우연히 생긴 두 글자 구간이 남아 있으면 그 칸을 채워도
완료 판정이 나지 않는 것처럼 보이므로, 격자를 새로 짜면 이 조건을 먼저 확인한다.
단서를 쓸 때는 **다른 항목의 정답을 단서 안에 그대로 적지 않는다.** 서로가 서로를
알려 주면 두 칸이 한꺼번에 풀려 버린다.
## 배포
Jenkins 잡(`crossword`)을 돌리면 아래가 순서대로 진행된다.
1. gitea `plpark/crossword` main 브랜치 체크아웃
2. `gitea.plpark.ectech.co.kr/plpark/crossword:<BUILD_NUMBER>` 빌드 & 푸시
3. `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 빌드. 그 외 변경 필요 없음.