Files
crossword/README.md
T
plparkandClaude Opus 5 c36468843d Add Japanese literature puzzle
셸에 일본 문학 탭을 더하고 site/japanese.html 을 추가했다. 9x9 44칸 14항목으로
네 편 중 가장 촘촘하다. 첫 열에 《나는 고양이로소이다》 아홉 자가 통째로 들어간다.

일본어 한글 표기는 음절이 잘 겹쳐(낱말 143개에 음절 166종) 독일 편처럼 풀을
억지로 넓히지 않아도 교차가 넉넉히 나왔다.

격자 품질 검사에 항목 간 포함 관계 검사를 더했다. 한 정답이 다른 정답에 통째로
들어가는 짝(소세키 / 나쓰메소세키)은 한 격자에 같이 두지 않는다.

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

89 lines
4.1 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 |
| 일본 문학 | `/japanese.html` | 9 × 9 · 44칸 | 14 |
각 페이지는 단독으로 열어도 동작한다. 셸(`/`)의 탭은 해시로 상태를 남기므로
`/#russian`, `/#british`, `/#german`, `/#japanese` 로 바로 들어갈 수 있고, 탭을 다시 눌러도 풀던 내용은 유지된다.
## 구성
| 경로 | 설명 |
|---|---|
| `site/index.html` | 셸 — 왼쪽 탭(좁은 화면에서는 위쪽 탭) + 게임을 띄우는 iframe |
| `site/russian.html` | 러시아 문학 편 (머리말 + 퍼즐 데이터) |
| `site/british.html` | 영국 문학 편 (머리말 + 퍼즐 데이터) |
| `site/german.html` | 독일 문학 편 (머리말 + 퍼즐 데이터) |
| `site/japanese.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 빌드. 그 외 변경 필요 없음.