Add missing providers (locale, theme, genFilter, caughtCount), all 6 pages, full widget inventory, core/l10n layers, and game mechanics (hints, skips, shiny, bonuses, bilingual input, gen filter). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
Application Architecture
Overview
L'application suit une Clean Architecture allégée en trois couches, avec une règle de dépendance stricte : les dépendances pointent vers l'intérieur. Le state management est assuré par Riverpod (providers manuels).
Couches
core (transversal)
AppConstants: toutes les constantes métier en un seul endroit (vies, points, shiny odds, plages de générations, clés SharedPreferences, URL API).logger: wrapper minimal autour dedart:developer.
domain (Dart pur)
- Entités :
Pokemon, immuable, sans dépendance Flutter/DB/API. - Repository (interface) :
PokemonRepositorydéfinit le contrat d'accès aux données. - Jeu :
GameState(état immuable) etGameEngine(règles pures, testables).GameEnginegère : soumission de réponse, vies, hints, skips, score, Shiny, bonus périodiques.GameStatus:loading | playing | roundWon | gameOver.GuessResult:correct | wrong | gameOver | invalid.
data
- DTO :
PokemonDtocentralise tout le parsing JSON (API Tyradex + SQLite).fromTyradexJson(),fromDb(),toDb().
- Datasources :
PokemonLocalDataSource— SQLite via sqflite ; absent (null) sur le web.PokemonRemoteDataSource— HTTP vers Tyradex + PokéAPI (genus anglais).
- Repository (impl) :
PokemonRepositoryImplapplique « DB locale d'abord, sinon API + cache ».
l10n
Internationalisation complète FR / EN via flutter_localizations + intl.
Fichiers générés : app_localizations.dart, app_localizations_fr.dart, app_localizations_en.dart.
La langue active est persistée dans SharedPreferences (AppConstants.prefsLocale).
presentation
Providers (Riverpod)
| Provider | Type | Rôle |
|---|---|---|
pokemonRepositoryProvider |
Provider |
DI du repository |
pokedexProvider |
AsyncNotifier<List<Pokemon>> |
Chargement + cache du Pokédex |
gameProvider |
Notifier<GameState> |
État de la partie en cours |
selectedTabProvider |
StateProvider<int> |
Onglet de navigation courant |
localeProvider |
Notifier<Locale> |
Langue active (FR/EN) + persistance |
themeProvider |
Notifier<AppPalette> |
Palette de couleurs active (5 thèmes) + persistance |
genFilterProvider |
Notifier<Set<int>> |
Générations sélectionnées pour le jeu + persistance |
caughtCountProvider |
Provider<int> |
Nombre de Pokémon capturés (dérivé de pokedexProvider) |
Pages
| Fichier | Rôle |
|---|---|
main_page.dart |
Hub de navigation par onglets (Jeu / Pokédex / Système) |
guess_page.dart |
Écran principal du jeu (silhouette, input, lives, score) |
game_over_page.dart |
Écran de fin de partie avec stats de session |
pokemon_list.dart |
Pokédex : liste filtrée + recherche par nom |
pokemon_detail.dart |
Fiche détaillée : stats, type, genus, toggle normal/shiny |
system_page.dart |
Paramètres (langue, palette) et statistiques globales |
Widgets notables
- Réutilisables :
PokemonImage,PokemonTile,PokemonTypeWidget,ScanlineOverlay. - guess/ :
GuessSilhouette,GuessInputSection,LivesRow,ScoreBoard,GenFilterSection. - detail/ :
PokemonDetailTop,PokemonStatsPanel. - game_over/ :
GameOverHeader,GameOverStats,GameOverActions,HingeDivider. - list/ :
PokedexListHeader,PokedexCountBar. - system/ :
LanguagePicker,PalettePicker,SectionTitle,SystemHeader,SystemStats.
Thème
type_colors.dart : couleur et libellé localisé par type Pokémon.
Flux de données
UI (Consumer) → Notifier → GameEngine (règles) + Repository (données)
→ DataSource (SQLite / HTTP) → DTO → Entity
Riverpod re-render automatiquement les consommateurs concernés. Plus de bus d'événements global ni d'accès inter-pages via l'arbre de widgets.
Mécaniques de jeu (résumé)
- Vies : 3 au départ ; une vie perdue par mauvaise réponse ; game over à 0.
- Hints : 3 au départ ; révèle partiellement le nom ; +1 tous les 5 bonnes réponses consécutives.
- Skips : 3 au départ ; passe au Pokémon suivant sans pénalité ; +1 tous les 10 bonnes réponses.
- Score : +10 pts normal, +20 pts shiny ; meilleur score persisté via SharedPreferences.
- Shiny : 1 chance sur 10 (
AppConstants.shinyOdds). - Filtre de génération : le joueur choisit parmi Gen I–IX ; persisté entre les sessions.
- Acceptation bilingue : le nom FR ou EN est accepté quelle que soit la langue de l'UI.
Tests
test/domain/game_engine_test.dart: règles du jeu.test/data/pokemon_dto_test.dart: parsing JSON ↔ DB.test/data/pokemon_repository_test.dart: logique du repository (datasources factices).test/widget_test.dart: smoke test de démarrage de l'app.