231 lines
8.5 KiB
Markdown
231 lines
8.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Build Commands
|
|
|
|
### Build the Project
|
|
```bash
|
|
# On Windows (using gradlew.bat)
|
|
.\gradlew.bat build
|
|
|
|
# On Linux/Mac (using gradlew)
|
|
./gradlew build
|
|
```
|
|
|
|
### Build and Install Debug APK
|
|
```bash
|
|
# On Windows
|
|
.\gradlew.bat assembleDebug
|
|
|
|
# Install to connected device
|
|
adb install -r app\build\outputs\apk\debug\app-debug.apk
|
|
```
|
|
|
|
### Run Tests
|
|
```bash
|
|
# Unit tests only
|
|
.\gradlew.bat test
|
|
|
|
# Android instrumented tests (requires connected device/emulator)
|
|
.\gradlew.bat connectedAndroidTest
|
|
|
|
# Run specific test class
|
|
.\gradlew.bat test --tests com.example.boidelov3.game.GameEngineTest
|
|
```
|
|
|
|
### Clean Build
|
|
```bash
|
|
.\gradlew.bat clean
|
|
```
|
|
|
|
## Project Architecture
|
|
|
|
### High-Level Structure
|
|
Boidelo is an Android drinking game app built with Java and Gradle. The architecture has evolved from a single-game app to a multi-game platform with a central hub.
|
|
|
|
**Package Structure:**
|
|
- `com.example.boidelov3` - Root package
|
|
- `com.example.boidelov3.hub` - Game selection hub (main entry point)
|
|
- `com.example.boidelov3.games.boideloclassic` - Original Boidelo game
|
|
- `com.example.boidelov3.games.game89` - 89++ card game
|
|
- `com.example.boidelov3.games.papelito` - Undercover party game
|
|
- `com.example.boidelov3.rules` - Rules viewer for popular party games
|
|
- `com.example.boidelov3.data` - Data models and repositories
|
|
- `com.example.boidelov3.game` - GameEngine (pure Java game logic)
|
|
- `com.example.boidelov3.utils` - Utilities (sound, error handling, security)
|
|
|
|
### Entry Points
|
|
- **GameSelectionActivity** (`hub/GameSelectionActivity.java`) - Main hub, displays available games via RecyclerView. This is the LAUNCHER activity in AndroidManifest.xml.
|
|
- **Legacy Activities** (`Jeux.java`, `JeuxParametres.java`, `EndGameActivity.java`) - Being phased out, do not use for new development
|
|
|
|
### Game Flow Pattern
|
|
Each game follows this flow:
|
|
1. **Setup Activity** - Player configuration (e.g., `BoideloClassicSetupActivity`, `Game89SetupActivity`)
|
|
2. **Parameters Activity** - Game settings (e.g., `BoideloClassicParamsActivity`)
|
|
3. **Game Activity** - Main gameplay (e.g., `BoideloClassicGameActivity`, `Game89GameActivity`)
|
|
4. **End Game Activity** - Results and statistics
|
|
|
|
### Core Architecture Components
|
|
|
|
**Data Layer:**
|
|
- `QuestionRepository` - Loads questions from JSON assets, manages SharedPreferences
|
|
- `Result<T, E>` - Type-safe error handling wrapper (pattern: `Result.success(value)` or `Result.error(error)`)
|
|
- `PlayerStats` - Tracks drinks consumed/distributed per player
|
|
- `Question` - Rich model with variants, manches (rounds), distribution flags
|
|
- `QuestionCategory` - Categorization with styling (colors, icons)
|
|
|
|
**Business Logic:**
|
|
- `GameEngine` - Pure Java game logic, isolated from Android framework for testability
|
|
- `OpenAIService` - AI-powered question generation via ChatGPT API
|
|
- `ChatGPTTask` - Async task for AI question generation
|
|
|
|
**UI Patterns:**
|
|
- Material Design 3 components
|
|
- RecyclerView for game selection
|
|
- Dynamic player input (add/remove fields)
|
|
- Haptic feedback and sound effects
|
|
|
|
### Question Processing Pipeline
|
|
Questions go through several transformations before display:
|
|
1. Load from `assets/questions.json` (150+ questions)
|
|
2. Replace player placeholders (`<J1>`, `<J2>`, `<J3>`)
|
|
3. Process variants (`<variante>`)
|
|
4. Handle manches (round challenges with countdown)
|
|
5. Add drink count and verb conjugation
|
|
6. Apply category-based styling
|
|
|
|
### Persistence
|
|
- **SharedPreferences** - Player names, settings, asked questions tracking, statistics
|
|
- **JSON Assets** - Pre-loaded question database
|
|
- **BuildConfig** - API keys (stored in `local.properties`, not version-controlled)
|
|
|
|
### Security Configuration
|
|
- API keys stored in `local.properties` (excluded from git)
|
|
- `SecureConfig` utility for secure access
|
|
- Database credentials in BuildConfig are intentionally empty (use backend API)
|
|
|
|
### Testing Infrastructure
|
|
- Unit tests in `app/src/test/java/com/example/boidelov3/`
|
|
- `GameEngineTest` - 15 tests for game logic
|
|
- `ResultTest` - Error handling wrapper tests
|
|
- `QuestionCategoryTest` - Category validation tests
|
|
- `PlayerStatsTest` - Player statistics tracking tests
|
|
- Game-specific tests in subpackages (e.g., `games/papelito/`, `games/game89/`)
|
|
- JUnit 4 framework
|
|
- Mockito 5.7.0 for mocking
|
|
- Robolectric 4.11.1 for Android framework testing
|
|
|
|
**Test Patterns:**
|
|
- Each game has comprehensive test coverage (15+ tests per game)
|
|
- Tests cover: setup/teardown, edge cases, state transitions, player management, win conditions
|
|
- Defensive copy testing for collections
|
|
|
|
**Known Issue:** Gradle 8.13 has a bug with unit tests from command line. If tests fail, run from Android Studio or use JDK 17-21.
|
|
|
|
### Important Files
|
|
- `app/build.gradle` - Dependencies, build config, BuildConfig fields
|
|
- `local.properties` - Local SDK path and API keys (not in git)
|
|
- `assets/questions.json` - Question database
|
|
|
|
### Resource Management Conventions
|
|
**Layout Naming:** `activity_<game>_<screen>.xml`
|
|
- `activity_<game>_setup.xml` - Player configuration
|
|
- `activity_<game>_game.xml` - Main game screen
|
|
- `activity_<game>_result.xml` - Results screen
|
|
- `dialog_<game>_<purpose>.xml` - Custom dialogs
|
|
|
|
**String Resources:** Internationalized strings in `res/values/strings.xml`, organized by game with clear prefixes (e.g., `papelito_`, `boidelo_`, `game89_`)
|
|
|
|
**Drawables:** Game icons follow `ic_<gamename>.xml` pattern in `res/drawable/`
|
|
|
|
### Game Registration (GameInfo System)
|
|
Games are registered in `GameSelectionActivity.setupGamesList()` via the `GameInfo` class. Each entry includes:
|
|
- Game name (hardcoded string)
|
|
- Description (hardcoded string)
|
|
- Icon resource (drawable resource ID)
|
|
- GameType enum value (BOIDELO_CLASSIC, GAME_89, UNDERCOVER, RULES)
|
|
- Availability flag (boolean)
|
|
|
|
Games are launched via Intent in `GameSelectionActivity.onItemClick()` using switch statement on `GameType` enum values.
|
|
|
|
### Adding a New Game
|
|
1. Create package under `com.example.boidelov3.games.<gamename>`
|
|
2. Implement setup, parameters, and game activities (follow Game Flow Pattern)
|
|
3. Add GameType enum value to `GameInfo.GameType`
|
|
4. Create `GameInfo` entry in `GameSelectionActivity.setupGamesList()`
|
|
5. Add case in `GameSelectionActivity.onItemClick()` switch statement
|
|
6. Add activities to AndroidManifest.xml with `android:screenOrientation="portrait"`
|
|
7. Add game icon/drawable resource following `ic_<gamename>.xml` pattern
|
|
|
|
### Dependencies
|
|
- AndroidX AppCompat 1.7.0
|
|
- Material Design 1.12.0
|
|
- ConstraintLayout 2.2.0
|
|
- OkHttp 4.12.0
|
|
- Gson 2.11.0
|
|
- pgjdbc-ng 0.8.3 (PostgreSQL - currently unused, backend recommended)
|
|
- JUnit 4.13.2
|
|
- Mockito 5.7.0
|
|
- Robolectric 4.11.1
|
|
- AndroidX Test JUnit 1.2.1
|
|
- Espresso 3.6.1
|
|
|
|
### Build Configuration
|
|
- `minSdk`: 24 (Android 7.0+)
|
|
- `targetSdk`: 35
|
|
- `compileSdk`: 35
|
|
- Java 8 compatibility
|
|
- Namespace: `com.example.boidelov3`
|
|
- All game activities use `android:screenOrientation="portrait"` in AndroidManifest.xml
|
|
- Game activities handle config changes with `android:configChanges="orientation|screenSize"`
|
|
|
|
---
|
|
|
|
## Code Style and Conventions
|
|
|
|
### Language Usage
|
|
- **Business logic terms in French:** `gorgees`, `manches`, `caliente` (domain-specific)
|
|
- **Technical terms in English:** `allPlayers`, `questionsWithManches`
|
|
- **UI text in French** (user-facing)
|
|
|
|
### Constants Management
|
|
All SharedPreferences keys are centralized in `PreferencesKeys.java`:
|
|
```java
|
|
// File names: PREFS_NAME_*
|
|
// Keys: KEY_*
|
|
// Dynamic keys: use getPlayerKey(int playerNumber)
|
|
```
|
|
|
|
Replace hardcoded strings throughout the codebase with these constants.
|
|
|
|
### Result<T, E> Pattern
|
|
Type-safe error handling wrapper used throughout:
|
|
```java
|
|
Result<String, Exception> result = repository.loadQuestions();
|
|
if (result.isSuccess()) {
|
|
String data = result.getData();
|
|
} else {
|
|
Exception error = result.getError();
|
|
}
|
|
```
|
|
|
|
### Resource Naming
|
|
- **Layouts:** `activity_<game>_<screen>.xml`, `dialog_<game>_<purpose>.xml`
|
|
- **Drawables:** `ic_<gamename>.xml` pattern
|
|
- **Strings:** Prefix by game (e.g., `papelito_`, `boidelo_`, `game89_`)
|
|
|
|
### Material Design
|
|
- Use `@color/primary` (#9395D3), `@color/accent` (#B3B7EE)
|
|
- Custom styles: `BoideloButton`, `BoideloTitle`, `BoideloCard`
|
|
- MaterialCardView with rounded corners (16-24dp) and elevation (4-8dp)
|
|
|
|
---
|
|
|
|
## Additional Documentation
|
|
|
|
- `README_ARCHITECTURE.md` - Detailed architecture documentation (French)
|
|
- `STANDARDISATION_ET_TESTS.md` - Standardization work and test coverage (French)
|
|
- `SECURITY_RECOMMENDATIONS.md` - Security guidelines and best practices
|
|
- `PAPELITO_LAYOUTS.md` - Papelito game layout documentation
|