File size: 8,915 Bytes
d747bc4
 
 
 
 
 
 
 
 
 
 
 
fbf85a5
032159d
fbf85a5
d747bc4
032159d
d747bc4
032159d
 
d747bc4
 
032159d
d747bc4
fbf85a5
7f5ea9e
d747bc4
 
 
 
 
 
 
 
 
7f5ea9e
d747bc4
032159d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d747bc4
9ecb8cf
 
 
 
 
 
2de3d96
 
 
 
 
 
 
522064b
 
 
 
 
 
9ecb8cf
 
 
 
d747bc4
 
032159d
d747bc4
 
fbf85a5
9ecb8cf
 
 
0b81bf2
 
 
 
 
 
 
 
 
d747bc4
032159d
 
 
0b81bf2
032159d
 
 
 
 
 
 
fbf85a5
032159d
0b81bf2
 
 
2de3d96
 
0b81bf2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d747bc4
 
f969c4d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0b81bf2
f969c4d
 
 
 
 
507acad
 
 
 
 
522064b
507acad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# Battlewords Game Requirements (specs.md)

## Overview
Battlewords is inspired by the classic Battleship game, but uses words instead of ships. The objective is to discover hidden words on a grid, earning points for strategic guessing before all letters are revealed.

## Game Board
- 12 x 12 grid.
- Six hidden words:
  - Two four-letter words
  - Two five-letter words
  - Two six-letter words
- Words are placed horizontally (left-right) or vertically (top-down), not diagonally.
- Words may touch edges or corners but do not overlap unless a future mode allows shared letters.
- Entry point is `app.py`.
- **Supports Dockerfile-based deployment for Hugging Face Spaces and other container platforms.**

## Gameplay (Common)
- Players click grid squares to reveal letters or empty spaces.
- Empty revealed squares are styled with CSS class `empty`.
- After any reveal, the app immediately reruns (`st.rerun`) to show the change.
- Use radar pulses to locate word boundaries (first and last letters).
- After revealing a letter, players may guess a word by entering it in a text box.
- Guess submission triggers an immediate rerun to reflect results.
- Only one guess per letter reveal; must uncover another letter before guessing again.
- In the default mode, a correct guess allows chaining an additional guess without another reveal.
- **The game ends when all six words are guessed or all word letters are revealed.**

## Scoring
- Each correct word guess awards points:
  - 1 point per letter in the word
  - Bonus points for each hidden letter at the time of guessing
- Score tiers:
  - Good: 34-37
  - Great: 38-41
  - Fantastic: 42+
- **Game over is triggered by either all words being guessed or all word letters being revealed.**

## POC (0.1.0) Rules
- No overlaps: words do not overlap or share letters.
- UI: basic grid, radar, and guess form.
- No keyboard interaction requirement.
- Seed is optional and not standardized.

## Beta (0.5.0) Additions
- Optional validation pass to avoid unintended adjacent partial words (content curation rule).
- Cell rendering with consistent sizing and responsive layout (desktop/mobile).
- Keyboard support for navigation and guessing (custom JS via `st.html` or a component).
- Deterministic seed support to reproduce puzzles (e.g., daily seed derived from date).

## Full (1.0.0) Rules
- No overlaps: words do not overlap or share letters.   
- Enhanced UX polish (animations, accessibility, themes).
- Persistence, leaderboards, and additional modes as specified in requirements.
- Deterministic daily mode and practice mode supported.

## New Features (v0.3.0)
- **Game ID Sharing:** Each puzzle generates a deterministic game ID based on the word list. Players can share URLs with `?game_id=ABC123` to challenge others with the same words.
- **Persistent Storage:** Game results and high scores are saved locally in `~/.battlewords/data/`.
- **High Scores:** Top scores are tracked and displayed in the sidebar, filterable by wordlist and game mode.
- **Player Name:** Optional player name is saved with results.

## New Features (v0.2.28)
- **PWA Support:** App is installable as a Progressive Web App on desktop and mobile.
  - Added `service worker` and `manifest.json`.
  - Basic offline caching of static assets.
  - INSTALL_GUIDE.md added with platform-specific install steps.
  - No gameplay logic changes.

## New Features (v0.2.24)
- **UI Improvements:** More compact layout, improved tooltip for incorrect guesses, and updated final score screen.
- **Word Difficulty:** Added a word difficulty formula and display for each game/challenge, visible in the final score and leaderboard.
- **Challenge Mode:** Enhanced leaderboard with difficulty display, improved result submission, and clearer challenge sharing.
- **Documentation:** Updated to reflect new features and UI changes.

## Storage
- Game results and high scores are stored in JSON files for privacy and offline access.
- Game ID is generated from the sorted word list for replay/sharing.

## UI Elements
- 12x12 grid
- Radar screen (shows last letter locations); y-axis inverted so (0,0) is top-left
- Text box for word guesses
- Score display (shows word, base points, bonus points, total score)
- Guess status indicator (Correct/Try Again)
- Game ID display and share button in game over dialog.
- High score expander in sidebar.
- Player name input in sidebar.
- Checkbox: "Show Challenge Share Links" (v0.2.27, default OFF)
  - When OFF:
    - Challenge Mode header hides the Share Challenge link
    - Game Over dialog still supports submitting/creating challenges, but does not display the generated share URL
  - Persisted in session state and preserved across "New Game"

## New Features (v0.2.27)
- Added "Show Challenge Share Links" visibility toggle for Challenge Mode sharing UI
- Purely a UI change; gameplay logic and storage behavior unchanged

## Word List
- External list at `battlewords/words/wordlist.txt`.
- Loaded by `battlewords.word_loader.load_word_list()` with caching.
- Filtered to uppercase A�Z, lengths in {4,5,6}; falls back if < 25 per length.

## Generator
- Centralized word loader.
- No duplicate word texts are selected.

## Entry Point
- The Streamlit entry point is `app.py`.
- **A `Dockerfile` can be used for containerized deployment (recommended for Hugging Face Spaces).**

## Deployment Requirements

### Basic Deployment (Offline Mode)
No special configuration needed. The app will run with all core gameplay features.  
Optional: Install as PWA from the browser menu (Add to Home Screen/Install app).

### Challenge Mode Deployment (Remote Storage)
Requires HuggingFace Hub integration for challenge sharing and leaderboards.

**Required Environment Variables:**
```bash
HF_API_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxx  # or HF_TOKEN (write access required)
HF_REPO_ID=YourUsername/YourRepo       # Target HF dataset repository
SPACE_NAME=YourUsername/BattleWords    # Your HF Space name for URL generation
```

**Optional Environment Variables:**
```bash
CRYPTO_PK=                             # Reserved for future challenge signing
```

**Setup Steps:**
1. Create a HuggingFace account at https://huggingface.co
2. Create a dataset repository (e.g., `YourUsername/BattleWordsStorage`)
3. Generate an access token with `write` permissions:
   - Go to https://huggingface.co/settings/tokens
   - Click "New token"
   - Select "Write" access
   - Copy the token (starts with `hf_`)
4. Create a `.env` file in project root with the variables above
5. For Hugging Face Spaces deployment, add these as Space secrets

**Repository Structure (automatically created):**
```
HF_REPO_ID/
├── shortener.json                     # Short URL mappings (sid -> full URL)
└── games/
    └── {uid}/
        └── settings.json              # Challenge data with users array
```

**Data Privacy:**
- Challenge Mode stores: word lists, scores, times, game modes, player names
- No PII beyond optional player name (defaults to "Anonymous")
- Players control URL visibility via "Show Challenge Share Links" setting
- App functions fully offline when HF credentials not configured

**Deployment Platforms:**
- Local development: Run with `streamlit run app.py`
- Docker: Use provided `Dockerfile`
- Hugging Face Spaces: Dockerfile deployment (recommended)
- Any Python 3.10+ hosting with Streamlit support

## Copyright
BattlewordsTM. All Rights Reserved. All content, trademarks and logos are copyrighted by the owner.

## v0.2.20: Remote Storage and Shortened game_id URL

Game Sharing
- Each puzzle can be shared via a link containing a `game_id` querystring (short id / sid)
- `game_id` resolves to a settings JSON on the storage server (HF repo)
- JSON fields:
  - word_list (list of 6 uppercase words)
  - score (int), time (int seconds) [metadata only]
  - game_mode (e.g., classic, too easy)
  - grid_size (e.g., 12)
  - puzzle_options (e.g., { spacer, may_overlap })
- On load with `game_id`, fetch and apply: word_list, game_mode, grid_size, puzzle_options

High Scores
- Repository maintains `highscores/highscores.json` for top scores
- Local highscores remain supported for offline use

UI/UX
- Show the current `game_id` (sid) and a �Share Challenge� link
- When loading with a `game_id`, indicate the puzzle is a shared challenge

Security/Privacy
- Only game configuration and scores are stored; no personal data is required
- `game_id` is a short reference; full URL is stored in a repo JSON shortener index

## Challenge Mode & Leaderboard

- When loading a shared challenge via `game_id`, the leaderboard displays all user results for that challenge.
- **Sorting:** The leaderboard is sorted by highest score (descending), then by fastest time (ascending).
- **Difficulty:** Each result now displays a computed word list difficulty value.
- Results are stored remotely in a Hugging Face dataset repo and updated via the app.