Correction du dernier gros bug

This commit is contained in:
feldenr
2026-02-25 18:19:45 +01:00
parent 69411ede10
commit a1eeefa755
6 changed files with 97 additions and 22 deletions
+6 -1
View File
@@ -51,7 +51,12 @@
"Bash(git config:*)",
"mcp__plugin_serena_serena__check_onboarding_performed",
"Bash(powershell:*)",
"mcp__plugin_serena_serena__execute_shell_command"
"mcp__plugin_serena_serena__execute_shell_command",
"mcp__plugin_serena_serena__list_memories",
"mcp__plugin_serena_serena__onboarding",
"mcp__plugin_serena_serena__write_memory",
"mcp__plugin_serena_serena__think_about_whether_you_are_done",
"Bash(.gradlew.bat assembleDebug)"
]
}
}
+2 -2
View File
@@ -4,10 +4,10 @@
<selectionStates>
<SelectionState runConfigName="Unnamed">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-01-16T22:28:09.607776900Z">
<DropdownSelection timestamp="2026-01-17T14:48:23.759734500Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=3B15B701VS600000" />
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\polar\.android\avd\Pixel_3a_API_34_extension_level_7_x86_64.avd" />
</handle>
</Target>
</DropdownSelection>
+71 -13
View File
@@ -50,13 +50,14 @@ Boidelo is an Android drinking game app built with Java and Gradle. The architec
- `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
- **MainActivity** (`MainActivity.java`) - Legacy entry for Boidelo Classic, being phased out
- **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:
@@ -113,12 +114,15 @@ Questions go through several transformations before display:
- 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)
@@ -137,20 +141,22 @@ Questions go through several transformations before display:
### Game Registration (GameInfo System)
Games are registered in `GameSelectionActivity.setupGamesList()` via the `GameInfo` class. Each entry includes:
- Game name (enum value)
- Display name (string resource)
- Description (string resource)
- Icon resource
- Availability flag
- 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 using `GameType` enum values.
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
3. Create `GameInfo` entry in `GameSelectionActivity.setupGamesList()`
4. Add game icon/drawable resources
5. Follow existing patterns for player management and game flow
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
@@ -158,9 +164,10 @@ Games are launched via Intent using `GameType` enum values.
- ConstraintLayout 2.2.0
- OkHttp 4.12.0
- Gson 2.11.0
- pgjdbc-ng 0.8.3 (PostgreSQL - currently unused)
- 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
@@ -170,3 +177,54 @@ Games are launched via Intent using `GameType` enum values.
- `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
+11
View File
@@ -71,6 +71,17 @@
android:exported="false"
android:screenOrientation="portrait" />
<!-- Rules Activities -->
<activity
android:name=".rules.RulesListActivity"
android:exported="false"
android:screenOrientation="portrait" />
<activity
android:name=".rules.RuleDetailActivity"
android:exported="false"
android:screenOrientation="portrait" />
<!-- Legacy Activities (to be removed) -->
<!-- Legacy activities placeholder -->
@@ -81,7 +81,7 @@ public class GameSelectionActivity extends AppCompatActivity implements GameAdap
"Découvrez les règles des jeux d'ambiance populaires",
R.drawable.ic_rules,
GameInfo.GameType.RULES,
false // Coming soon
true // Available now!
));
}
@@ -117,9 +117,7 @@ public class GameSelectionActivity extends AppCompatActivity implements GameAdap
startActivity(new Intent(this, com.example.boidelov3.games.papelito.PapelitoSetupActivity.class));
break;
case RULES:
// À implémenter: RulesListActivity
android.widget.Toast.makeText(this, "Règles de jeux - Bientôt disponible!",
android.widget.Toast.LENGTH_SHORT).show();
startActivity(new Intent(this, com.example.boidelov3.rules.RulesListActivity.class));
break;
}
}
+5 -2
View File
@@ -5,6 +5,9 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/accent"
android:pathData="M18,2H6C4.9,2 4,2.9 4,4v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zM6,4h5v8l-2.5,-1.5L6,12V4z" />
android:fillColor="@color/text_on_primary"
android:pathData="M14,2H6C4.9,2 4,2.9 4,4v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V8L14,2zM6,20V4h7v5h5v11H6z"/>
<path
android:fillColor="@color/text_on_primary"
android:pathData="M8,12h8v2H8zM8,16h8v2H8zM8,8h5v2H8z"/>
</vector>