commit 95010539841e284c2a1820e453921df52de2b85e Author: roman Date: Wed Dec 31 11:44:04 2025 +0100 Changement d'interface graphique diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..745dd68 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,9 @@ +{ + "permissions": { + "allow": [ + "Bash(tree:*)", + "Bash(./gradlew:*)", + "Bash(dir:*)" + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..97023b3 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +BoideloV3 \ No newline at end of file diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..9c96b2b --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..0897082 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..718044b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/ANALYSE_CODE.md b/ANALYSE_CODE.md new file mode 100644 index 0000000..3411324 --- /dev/null +++ b/ANALYSE_CODE.md @@ -0,0 +1,418 @@ +# Analyse Complète du Code - BoideloV3 + +## 📋 Table des Matières + +1. [Présentation du Projet](#présentation-du-projet) +2. [Structure du Projet](#structure-du-projet) +3. [Fichiers Principaux](#fichiers-principaux) +4. [Fonctionnalités](#fonctionnalités) +5. [Technologies et Dépendances](#technologies-et-dépendances) +6. [Architecture](#architecture) +7. [Composants et Leurs Relations](#composants-et-leurs-relations) +8. [Configuration](#configuration) + +--- + +## 🎮 Présentation du Projet + +**BoideloV3** est une application Android de jeu d'alcool (similaire à "King's Cup" ou "Never Have I Ever"). L'application permet à un groupe de joueurs de répondre à des questions aléatoires avec des consommations de boissons associées. + +### Caractéristiques Principales + +- **Jeu multijoueur** (minimum 3 joueurs, sans maximum) +- **115 questions préchargées** depuis un fichier JSON +- **Interface en français** avec Material Design 3 +- **Intégration OpenAI** (en développement) +- **Connexion PostgreSQL** (prête) +- **Interface moderne et responsive** + +--- + +## 📁 Structure du Projet + +``` +C:\Users\polar\Documents\boidelo\ +├── .gradle/ # Cache de construction Gradle +├── .idea/ # Configuration IntelliJ IDEA +├── app/ +│ ├── build.gradle # Configuration de build app-level +│ ├── libs/ # Librairies JAR externes +│ │ ├── postgresql-42.2.27.jre7.jar +│ │ └── postgresql-42.6.0.jar +│ └── src/ +│ └── main/ +│ ├── AndroidManifest.xml +│ ├── assets/ +│ │ ├── question.json # Base de données questions (115 questions) +│ │ └── questionOLD.json +│ ├── java/com/example/boidelov3/ +│ │ ├── MainActivity.java +│ │ ├── Jeux.java # Activité principale du jeu +│ │ ├── Jeuxold.java # Implémentation héritée +│ │ ├── JeuxParametres.java # Paramètres du jeu +│ │ ├── ChatGPTTask.java # Intégration OpenAI (commenté) +│ │ ├── DatabaseConnection.java # Connexion PostgreSQL +│ │ ├── Question.java # Modèle de données Question +│ │ └── Questions.java # Conteneur de questions +│ └── res/ +│ ├── anim/ # Animations +│ ├── drawable/ # Icônes et graphiques +│ ├── layout/ # Layouts UI (4 fichiers XML) +│ ├── mipmap-*/ # Icônes pour différentes densités +│ ├── values/ # Chaînes, couleurs, thèmes +│ ├── values-night/ # Ressources mode nuit +│ └── xml/ # Fichiers de configuration XML +├── build.gradle # Configuration de build projet-level +├── gradle.properties # Propriétés Gradle +├── settings.gradle # Paramètres du projet +├── gradlew, gradlew.bat # Exécutables Gradle wrapper +└── .gitignore # Fichier Git ignore +``` + +--- + +## 📄 Fichiers Principaux + +### Activités Principales + +#### `MainActivity.java` +**Point d'entrée principal** de l'application. + +**Responsabilités :** +- Gestion de la saisie des noms de joueurs +- Validation du minimum de 3 joueurs +- Génération dynamique de l'interface utilisateur +- Persistence des noms avec SharedPreferences + +#### `Jeux.java` +**Cœur du jeu**, gère l'affichage des questions et les mécaniques de jeu. + +**Responsabilités :** +- Chargement des questions depuis le JSON +- Sélection aléatoire sans répétition +- Gestion des tours de joueurs +- Feedback visuel avec arrière-plans colorés +- Remplacement dynamique des variantes + +#### `JeuxParametres.java` +**Écran de configuration** des paramètres du jeu. + +**Responsabilités :** +- Configuration du nombre de questions +- Gestion des comptes de boissons +- Configuration de l'API OpenAI +- Lancement de l'activité Jeux + +#### `Jeuxold.java` +**Version héritée** du jeu avec questions hardcodées (non utilisée activement). + +### Modèles de Données + +#### `Question.java` +**Modèle de données** pour une question individuelle. + +**Propriétés :** +```java +public class Question { + private int id; // Identifiant unique + private String question; // Texte de la question + private int boire; // Nombre de boissons + private boolean donner; // Flag de distribution + private boolean recevoir; // Flag de réception + private List variantes; // Variantes de la question + private int manches; // Nombre de manches + private String stop; // Message d'arrêt +} +``` + +#### `Questions.java` +**Classe conteneur** pour la liste de questions. + +### Intégrations + +#### `ChatGPTTask.java` +**Intégration OpenAI** pour la génération de questions avec ChatGPT. + +**Statut :** Commenté / En développement + +**Fonctionnalités prévues :** +- Génération dynamique de questions +- Appel API à OpenAI +- Traitement des réponses + +#### `DatabaseConnection.java` +**Gestionnaire de connexion** à la base de données PostgreSQL. + +**Configuration :** +- Hôte : 82.65.214.214 +- Port : 5432 +- Base de données : boidelo +- Utilisateur : android + +--- + +## ⚡ Fonctionnalités + +### Gestion des Joueurs + +- **Entrée dynamique** des noms de joueurs +- **Minimum 3 joueurs** requis pour commencer +- **Support illimité** de nombre de joueurs +- **Persistance** avec SharedPreferences + +### Système de Questions + +- **115 questions préchargées** depuis JSON +- **Sélection aléatoire** sans répétition +- **Variantes** avec remplacement dynamique de contenu +- **Questions à manches** avec mécanique de compte à rebours + +### Mécaniques de Jeu + +- **Ajustement dynamique** du nombre de boissons +- **Randomisation** des joueurs pour les questions +- **Feedback visuel** avec arrière-plans colorés +- **Catégorisation** (distribution/réception) + +### Fonctionnalités Avancées + +- **Intégration OpenAI ChatGPT** (stade de développement) +- **Connectivité PostgreSQL** (prête) +- **Paramètres personnalisables** +- **Défis multi-manches** + +### Interface Utilisateur + +- **Trois activités principales** : Main, Jeux, Paramètres +- **Interface Material Design 3** +- **Localisation en français** +- **Layout responsive avec ConstraintLayout** + +--- + +## 🛠 Technologies et Dépendances + +### Technologies Principales + +| Technologie | Version | Usage | +|-------------|---------|-------| +| **Android SDK** | 33 (compile) | Développement Android natif | +| **Java** | - | Langage principal | +| **Gradle** | 8.2 | Automatisation de build | + +### Bibliothèques Principales + +```gradle +dependencies { + // Cœur Android + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + + // Réseau + implementation 'com.squareup.okhttp3:okhttp:4.9.1' + + // Base de données + implementation 'com.impossibl.pgjdbc-ng:pgjdbc-ng:0.8.3' + + // Traitement JSON + implementation 'com.google.code.gson:gson:2.8.8' + + // Tests + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} +``` + +### Librairies Externes + +| Librairie | Version | Utilisation | +|-----------|---------|-------------| +| **OkHttp** | 4.9.1 | Client HTTP pour appels API | +| **PostgreSQL JDBC** | 42.6.0 | Connectivité base de données | +| **Gson** | 2.8.8 | Sérialisation/désérialisation JSON | + +--- + +## 🏗 Architecture + +### Pattern MVC (Model-View-Controller) + +``` +┌─────────────────────────────────────────────────┐ +│ Model │ +│ • Question.java │ +│ • Questions.java │ +└─────────────────────────────────────────────────┘ + ↑ + │ + ↓ +┌─────────────────────────────────────────────────┐ +│ Controller │ +│ • MainActivity.java │ +│ • Jeux.java │ +│ • JeuxParametres.java │ +└─────────────────────────────────────────────────┘ + ↑ + │ + ↓ +┌─────────────────────────────────────────────────┐ +│ View │ +│ • XML Layouts │ +│ • Resources (drawable, strings, colors) │ +└─────────────────────────────────────────────────┘ +``` + +### Architecture Basée sur les Activités + +``` +MainActivity +├── Gère l'entrée des joueurs +├── Valide le minimum de 3 joueurs +└── Lance JeuxParametres + +JeuxParametres +├── Configure les paramètres du jeu +├── Gère la configuration de l'API OpenAI +└── Lance l'activité Jeux + +Jeux +├── Charge les questions depuis JSON +├── Gère l'état du jeu +├── Affiche les questions aléatoires +└── Gère les interactions des joueurs +``` + +### Persistence des Données + +| Méthode | Usage | +|---------|-------| +| **SharedPreferences** | Noms des joueurs et paramètres du jeu | +| **JSON Assets** | Base de données des questions | +| **PostgreSQL** | Base de données externe (planifié) | + +### Opérations Asynchrones + +| Type | Implémentation | +|------|----------------| +| **AsyncTask** | Opérations de base de données (héritage) | +| **OkHttp Callbacks** | Opérations réseau | + +--- + +## 🔗 Composants et Leurs Relations + +``` +┌────────────────────────────────────────────────────────────┐ +│ MainActivity │ +│ - Saisie des noms de joueurs │ +│ - Validation (min. 3 joueurs) │ +│ - Génération UI dynamique │ +└────────────────────┬───────────────────────────────────────┘ + │ + ▼ +┌────────────────────────────────────────────────────────────┐ +│ JeuxParametres │ +│ - Configuration du jeu │ +│ - Setup API OpenAI │ +│ - Lance Jeux │ +└────────────────────┬───────────────────────────────────────┘ + │ + ▼ +┌────────────────────────────────────────────────────────────┐ +│ Jeux │ +│ - Charge questions depuis JSON │ +│ - Gère l'état du jeu │ +│ - Affiche questions aléatoires │ +│ - Gère interactions joueurs │ +└────────────────────┬───────────────────────────────────────┘ + │ + ▼ +┌────────────────────────────────────────────────────────────┐ +│ Question Model │ +│ - Stocke les données de question │ +│ - Gère variantes et manches │ +│ - Fournit les mécaniques de jeu │ +└────────────────────────────────────────────────────────────┘ +``` + +--- + +## ⚙️ Configuration + +### Configuration de Build + +| Propriété | Valeur | +|-----------|--------| +| **Compile SDK** | 33 | +| **Min SDK** | 24 | +| **Target SDK** | 33 | +| **Version Code** | 1 | +| **Version Name** | "1.0" | +| **Package** | com.example.boidelov3 | + +### Configuration de l'Application + +| Fichier | Description | +|---------|-------------| +| **AndroidManifest.xml** | Permissions Internet, 4 activités déclarées | +| **gradle.properties** | AndroidX activé, 2GB RAM allouée | +| **settings.gradle** | Nom du projet : "BoideloV3" | + +### Configuration Base de Données + +``` +Hôte : 82.65.214.214 +Port : 5432 +Base de données : boidelo +Utilisateur : android +``` + +### Dépendances Externes + +| Service | Statut | +|---------|--------| +| **PostgreSQL Database** | Prêt | +| **OpenAI API** | En développement | + +--- + +## 📊 Observations Clés + +1. **Localisation Française** - L'application est entièrement localisée en français + +2. **Jeu d'Alcool** - Conçu pour des jeux sociaux à base de boissons avec questions + +3. **Évolution de Version** - V3 indique plusieurs itérations, avec code héritage préservé + +4. **Pratiques Android Modernes** - Utilise AndroidX, Material Design 3, outils de build modernes + +5. **Intégration Base de Données** - Prêt pour JSON local et PostgreSQL distant + +6. **Intégration IA** - Support OpenAI planifié mais pas entièrement implémenté + +7. **Architecture Évolutive** - Supporte joueurs et questions illimités + +--- + +## 🔮 Statut des Fonctionnalités + +| Fonctionnalité | Statut | +|----------------|--------| +| Jeu multijoueur | ✅ Terminé | +| Questions JSON | ✅ Terminé | +| Interface UI | ✅ Terminé | +| PostgreSQL | 🔧 Prêt | +| OpenAI ChatGPT | 🚧 En développement | +| Tests unitaires | 🔧 Configuré | + +--- + +## 📝 Conclusion + +Le codebase représente une **application Android de jeu d'alcool bien structurée** avec des patterns d'architecture modernes, prête pour la production mais avec certaines fonctionnalités encore en développement. L'architecture est propre, modulaire et facilement extensible pour de futures améliorations. + +--- + +*Document généré automatiquement - 2025* diff --git a/Icone.png b/Icone.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/Icone.png differ diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..885025e --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,43 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.example.boidelov3' + compileSdk 33 + packagingOptions { resources.excludes.add("META-INF/*") } // This line is added to avoid the error: Duplicate files copied in APK META-INF/LICENSE.txt + defaultConfig { + applicationId "com.example.boidelov3" + minSdk 24 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + implementation 'com.squareup.okhttp3:okhttp:4.9.1' + implementation 'com.impossibl.pgjdbc-ng:pgjdbc-ng:0.8.3' + implementation 'com.google.code.gson:gson:2.8.8' + +} \ No newline at end of file diff --git a/app/libs/postgresql-42.2.27.jre7.jar b/app/libs/postgresql-42.2.27.jre7.jar new file mode 100644 index 0000000..c4c4591 Binary files /dev/null and b/app/libs/postgresql-42.2.27.jre7.jar differ diff --git a/app/libs/postgresql-42.6.0.jar b/app/libs/postgresql-42.6.0.jar new file mode 100644 index 0000000..02f902a Binary files /dev/null and b/app/libs/postgresql-42.6.0.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..792ee66 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/question.json b/app/src/main/assets/question.json new file mode 100644 index 0000000..5bd1338 --- /dev/null +++ b/app/src/main/assets/question.json @@ -0,0 +1,853 @@ + +{ + "version": "2", + "questions": [ + { + "id": 1, + "question": "Celles/Ceux qui ont habité dans plus de 3 villes diferentes", + "gorger": 3, + "distribution": true, + "recois": true + + }, + { + "id": 2, + "question": "Ceux qui ont dansé aujourd'hui", + "gorger": 1, + "distribution": true, + "recois": true + }, + { + "id": 3, + "question": "si tu n'as pas ton veritable nom sur insta", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 4, + "question": "si tu a des photos sur insta", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 5, + "question": "Les joueurs de Counter Strike ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 5, + "question": "La dernière personne à avoir vomi en soirée ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 6, + "question": "Toutes celles (ou ceux) qui ont du verni à ongles", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 7, + "question": "Tous les joueurs célibataires", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 8, + "question": "Tous ceux qui ont des lunettes", + "gorger": 2, + "distribution": true, + "recois": true + }, + { + "id": 9, + "question": "Tous ceux qui ont déjà triché à un examen", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 10, + "question": "Le/La plus radin(e)", + "gorger": 4, + "distribution": false, + "recois": true + }, + { + "id": 11, + "question": " a toi de juger : entre et qui stresse le plus pour un rien selon toi? Le perdant ", + "gorger": 5, + "distribution": false, + "recois": true + }, { + "id": 12, + "question": "Le mec qui a le plus gros ventre à bière ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 13, + "question": "Tous ceux qui se sont déjà fait exclure de cours", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 14, + "question": ", donne le nombre d'habitant du/de la ( à 1 000 000 près) Si tu as faux tu bois, sinon tu ", + "gorger": 3, + "distribution": true, + "recois": false, + "variante": ["Tadjikistant", "Monaco", "Belgique", "Suisse", "Allemagne", "Chine", "Inde"] + }, + { + "id": 15, + "question": "Tous ceux qui ont des frères et soeurs", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 16, + "question": " a qui appartient le slogan suivant? ", + "variante": ["Des pâtes oui mais des (panzani)"," Le plaisir pour les petites faims. (Kinder Bueno)","Réveillez le lion qui est en vous. (Cereale lion)","Parce que le monde bouge (CIC)","Ça coule de source ! (Cristaline)", "Pensez différemment (apple)" ], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 17, + "question": "Celles et ceux qui ont eu un Windows phone", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 18, + "question": ", Boire un café fait baisser le taux d'alcool? Si tu as faux ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 19, + "question": "Celles/Ceux qui se sont déjà battus", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 20, + "question": "Celui/Celle qui pèse le plus lourd", + "variante": ["lourd","leger"], + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 21, + "question": "Pour se décoincer, le/la plus ", + "variante": ["timide", "enervé ", "angoissé","aigri"], + "gorger": 2, + "distribution": false, + "recois": true + }, + { + "id": 22, + "question": "Le/La plus ", + "gorger": 3, + "variante": ["jeune","vieille"], + "distribution": false, + "recois": true + }, + { + "id": 23, + "question": "Celles/Ceux qui ont fait des études ", + "gorger": 3, + "variante": ["L","Scientifique", "Bac Professionel", "STMG"], + "distribution": true, + "recois": true + }, + { + "id": 25, + "question": "Celles et ceux qui ont deja joué de maniere recurrente ", + "gorger": 3, + "variante": ["du piano","de la guitare", "du saxophone", "de la batterie"], + "distribution": true, + "recois": true + }, + { + "id": 26, + "question": "Les gens qui se sont masturbés aujourd'hui", + "gorger": 3, + "distribution": true, + "recois": true, + "caliente": true + }, + { + "id": 27, + "question": "Celui ou celle a la meilleure place", + "gorger": 2, + "distribution": false, + "recois": true + }, + { + "id": 28, + "question": "Celles et ceux qui n'ont jamais trompé leur partenaire", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 29, + "question": "Celui/Celle avec les vêtements les plus beaux ", + "gorger": 1, + "distribution": false, + "recois": true + }, + { + "id": 30, + "question": "Celui/Celle qui a les cheveux les plus ", + "gorger": 2, + "variante": ["longs","courts"], + "distribution": true, + "recois": true + }, + { + "id": 31, + "question": "Les végans ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 32, + "question": "La personne la plus maquillé ", + "gorger": 2, + "distribution": true, + "recois": true + }, { + "id": 33, + "question": "Celles/Ceux qui ont déjà appelé leur partenaire par le prénom de leurs ex", + "gorger": 4, + "distribution": false, + "recois": true + }, + { + "id": 34, + "question": "Celles et ceux qui boit de la actuellement", + "gorger": 3, + "distribution": true, + "recois": true, + "variante": ["vodka", "rhum", "tequila", "whisky"] + }, + { + "id": 35, + "question": "Les joueurs qui ont un dans leurs prénom", + "gorger": 3, + "distribution": false, + "recois": true, + "variante": ["a","e","i","o","u","y"] + }, + { + "id": 36, + "question": "Le/La joueur/euse avec le plus gros cul", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 37, + "question": "Celles/Ceux qui ont moins de ans", + "gorger": 3, + "distribution": false, + "recois": true, + "variante": ["21","22","23","24","25","26"] + }, + { + "id": 38, + "question": "Celui/celle avec le plus gros appetit sexuel", + "gorger": 3, + "distribution": false, + "recois": true, + "caliente": true + }, + { + "id": 39, + "question": "Ceux/Celles qui fumes (VapeNation compris)", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 40, + "question": "Celles et ceux qui ont au moins un BAC +", + "gorger": 1, + "distribution": true, + "recois": true, + "variante": [0,1,2,3,4,5] + }, + { + "id": 41, + "question": "Le premier joueur à se lever", + "doubledistribution": true, + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 42, + "question": "Ceux qui n'ont jamais eu l'occasion de faire un strip tease", + "gorger": 3, + "distribution": false, + "recois": true, + "caliente": true + }, + { + "id": 43, + "question": "Le premier joueur à enlever un vêtements", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 44, + "question": "Tous ceux qui ont déjà uriné dans une piscine ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 30, + "question": "Celui/Celle avec le plus de follow sur ", + "gorger": 3, + "distribution": true, + "recois": true, + "variante": ["instagram","facebook","tik-tok"] + }, + { + "id": 31, + "question": "Celui/Celle avec le nom de famille le plus compliqué", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 32, + "question": "Les joueurs qui n'ont pas encore distribué de gorgées", + "gorger": 3, + "distribution": false, + "recois": true + }, { + "id": 33, + "question": "Le premier joueur à donner l'heure", + "doubledistribution": true, + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 34, + "question": "Celles et ceux qui ont déjà dépenser plus de 2000 euros en un achat", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 35, + "question": "La personne la moins courageuse", + "gorger": 1, + "distribution": false, + "recois": true + }, + { + "id": 36, + "question": "Celles/Ceux qui rentre chez eux à la fin de la soirée", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 37, + "question": "Celles et ceux dont le jour d'anniversaire est un nombre ", + "gorger": 3, + "distribution": true, + "recois": true, + "variante": ["impaire","paire"] + }, + { + "id": 38, + "question": "Si tu as un téléphone qui a un prix supperieur d'achat a 1000Euros, tu est riche donc en tant que personne généreuse", + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 39, + "question": "Tous ceux qui ont fait plus de 100km pour venir ici ", + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 40, + "jeux": true, + "question": "Le jeu du revolver: Chaque joueur a maintenant 7 balles, une balle correspondant à une gorgée. Les joueurs ont la capacité de tirer des balles à tout moment du jeu.", + "distribution": false, + "recois": false + }, + { + "id": 41, + "question": "", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 42, + "jeux": true, + "question": " est le vieu/vieille briscard ! Interdiction de montrer tes dents pendant manches", + "manches": true, + "arret": "Tu peux arreter de cacher tes belles dents" + + }, + { + "id": 43, + "jeux": true, + "question": " et liser le premier SMS qui s'affiche quand on tape dans la barre de recherche. le plus marrant", + "gorger": 3, + "variante": ["désolé","caca","bourré","mine","nazi"], + "distribution": true, + "recois": false + }, { + "id": 44, + "jeux": true, + "question": "A tour de role, vous avez exactement 3 secondes pour donner un mot en rapport avec le mots dit precedemment. tu commences en choissisant un mot. Le perdant", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 45, + "jeux": true, + "question": "Le jeu du PIM PAM POUM. Le premier qui perd ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 46, + "jeux": true, + "question": " defie au chifoumi ! Le perdant", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 47, + "jeux": true, + "question": " est dans le ! Tu dois parler au pendant manches ", + "variante": ["passé", "futur"], + "manches": true, + "arret": "Tu est revenu dans le present", + "distribution": false, + "recois": false, + "caliente": false + }, + { + "id": 48, + "question": " tu bois autant de gorgées que tu as d'années d'études après le BAC" + }, + { + "id": 49, + "jeux": true, + "question": " et ferment leurs yeux ! Ils/Elles doivent deviner la couleur des yeux de l'autre. ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 50, + "jeux": true, + "question": " est manchot ! Il/Elle ne peut plus utiliser ses doigts durant manches . Si il/elle s'en sert, il/elle devra boire autant de gorgées qu'il/elle a utilisé de doigts", + "distribution": false, + "arret": "Tu n'es plus manchot", + "recois": true + }, + { + "id": 51, + "jeux": true, + "question": " et , si vous êtes ensemble dans la vraie vie, vous pouvez distribuer 2 gorgées , autrement buvez-les" + + }, + { + "id": 52, + "jeux": true, + "question": " a la tourette ! A chaque fois que tu bois une gorgée, tu dois CRIER une insulte. C'est un stade avancé, ça dure manches", + "manches": true, + "arret": "Tu n'as plus tourette." + + }, + { + "id": 53, + "jeux": true, + "question": ", donne la couleur préférée de si tu te trompes", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 54, + "jeux": true, + "question": " à l'oeil de serpent ! Dès qu'un joueur te regarde dans les yeux, il/elle boit. Si tu es arrivé a faire boire personne avant manches, tu ", + "gorger": 4, + "distribution": false, + "recois": true + }, { + "id": 55, + "jeux": true, + "question": " et se mesurent ! Le/la plus ", + "gorger": 3, + "variante": ["petit","grand"], + "distribution": true, + "recois": true + }, + { + "id": 56, + "jeux": true, + "question": " doit terminer toutes ses phrases par - pendant manches", + "variante": ["C'est clair","han","quoicoubeh"] + }, + { + "id": 57, + "jeux": true, + "question": " et se défient au 'je te tiens, tu me tiens', le premier qui rit sera dechiré, et ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 58, + "jeux": true, + "question": " et n'ont plus le droit d'utiliser leur téléphone pendant manches !", + "manches": "true", + "arret": "vous pouvez enfin utiliser vos téléphone bande de geek" + }, + { + "id": 59, + "jeux": true, + "question": " et racontent une anecdote, celui/celle qui sort la plus ", + "variante": ["banale","incroyable","marrante"], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 60, + "jeux": true, + "question": ", Si on te dit Marco? ... Si tu as dis Polo ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 61, + "jeux": true, + "question": " est l'aigris pendant manches ! Dès que tu souris ou rigoles,", + "gorger": 1, + "manches": true, + "distribution": false, + "arret": "Tu n'es plus aigris!", + "recois": true + }, + { + "id": 62, + "jeux": true, + "question": " fait un geste, le suivant répète et en ajoute un. Le perdant ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 63, + "question": ", et vont désigner quelqu'un qui doit terminer son verre", + "jeux": true + }, + { + "id": 64, + "question": "Récitez l'alphabet en énonçant une lettre à tour de rôle. Si finit son verre avant, cul sec pour tout le monde !", + "jeux": true + }, + { + "id": 65, + "question": "Si arrive a finir son verre en moins de 5 secondes, il/elle ", + "gorger": 6, + "distribution": true, + "recois": false, + "jeux": true + }, + { + "id": 66, + "jeux": true, + "question": " et sont lies, si l'un boit alors l'autre aussi, et ce pendant manches", + "manches": true, + "arret": "Vous n'etes plus liés par le verre de l'amitié et plus.." + }, + { + "id": 67, + "question": " dit un mot, la personne suivante le répète et en ajoute un nouveau, ainsi de suite jusqu'a ce que quelqu'un se trompe. Le perdant boit autant de gorgées qu'il y a eu de personne avant lui", + "jeux": true + }, + { + "id": 68, + "question": " doit choisir un mot que tout le monde devra dire à chaque fois qu'une personne boit. Pendant manches", + "jeux": false, + "manches": true, + "arret": "Plus besoin de dire le mots avant de boire" + }, + { + "id": 69, + "question": "Quand l'heure affichera un multiple de 10 (22h, 22h10 ...) le premier a crier 'merde j'ai oublié mon chat'", + "gorger": 3, + "distribut":false, + "manches": true, + "arret": "Vous avez retrouver le chat!" + }, + { + "id": 70, + "question": "Plutôt ne plus avoir de mains ou de jambes? les perdants ", + "gorger": 3, + "jeux": false, + "distribution": false, + "recois": true + }, + { + "id": 71, + "question": "Vive la poésie ! Nos phrases doivent rimer sous peine d'une gorgée pendant manches", + "manches": true, + "arret": "Vous ne devez plus faire de rime." + }, + { + "id": 72, + "question": "Choisissez le joueur le drôle d'entre vous, ce dernier ", + "variante": ["moins", "plus"], + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 73, + "question": "Les ", + "variante": ["filles","garçons","couples","celibataires"], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 74, + "jeux": true, + "question": "Plutôt avoir un tapis volant, ou un frigo qui se remplit tout seul ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true, + "manches": false + }, + { + "id": 75, + "question": "Plutôt avoir du temps ou de l'argent ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + + }, + { + "id": 76, + "question": "Le premier joueur qui en embrasse un autre sur la bouche", + "gorger": 5, + "distribution": true, + "recois": false, + "caliente": true + }, + { + "id": 77, + "question": "Plutôt série ou film ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 78, + "question": "Plutôt jeux-videos ou livre ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + + { + "id": 79, + "question": "Plutôt anime ou jeux-videos ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 80, + "question": "Elisez le plus d'entre vous, ce dernier ", + "variante": ["con", "intelligent", "beau", "gentil","dragueur","timide"], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 81, + "question": "Le premier qui donne un film de ", + "gorger": 3, + "distribution": true, + "recois": false, + "variante": ["Christopher Nolan","James Cameron","Tim Burton","Quentin tarantino","Steven Spielberg"] + }, + { + "id": 82, + "question": "Le premier qui donne un film avec ", + "variante": ["Christian Clavier","Morgan freeman","Brad Pitt", "Jean Reno","Marion Cotillard"], + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 83, + "question": "La première personne qui désigne le/la plus ", + "gorger": 3, + "distribution": true, + "recois": false, + "variante": ["jeune", "vieille"] + }, + { + "id": 84, + "question": "Plutôt avoir des connaissances illimitées ou diriger le monde ? Votez tous en même temps. La minorité", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 85, + "question": "Plutôt n'avoir aucun ami ou ne plus pouvoir utiliser d'appareil électronique ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 86, + "question": "Plutot vaincre le patrikaka ou la polution dans le monde? Votez tous en meme temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 87, + "question": "Jeu du LUTIN : Pendant manches. Vous devez enlever le lutin de votre verre pour pouvoir boire et le remettre ensuite sinon vous devait reboire", + "gorger": 3, + "distribution": false, + "recois": false, + "manches": true, + "arret": "Le Lutin est parti. Vous pouvez boire normalement" + }, + { + "id": 88, + "question": "Le premier joueur à ramener un objet (pas de vêtements) ", + "gorger": 3, + "distribution": true, + "variante": ["rouge","vert","bleu","jaune"], + "recois": false, + "manches": false + }, + { + "id": 89, + "question": "Le premier joueur qui dévoile un de ses secrets et que personne ne sait ", + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 90, + "question": "Jeu des peaux! Triez vous du joueur le plus bronzé au joueur le moins bronzé. Le plus bronzé prend 1 gorgée, le second 2 gorgées, etc.", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 91, + "question": "Plutôt avoir du pouvoir ou de la connaissance ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 92, + "question": "Il est désormais interdit de se tutoyer pendant manches", + "manches": true, + "arret":"Vous pouvez vous enfin vous tutoyer" + + }, + { + "id": 93, + "question": "Vaccin contre le COVID19 : Le DR Raoul à dit que boire un cul sec avait les mêmes effets que le vaccin. Tout le monde bois sont verre cul sec" + }, + { + "id": 94, + "question": "Faites un concours de clash : Rap contenders entre et le perdant ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 95, + "question": "Choisissez un joueur qui doit imiter un animal pendant manches sans se faire prendre", + "manches": true, + "arret": "Fin de l'imitation animale" + }, + { + "id": 96, + "question": "Qui a le plus de talents cachés ? Votez et le perdant", + "gorger": 2, + "distribution": false, + "recois": true + }, + { + "id": 97, + "question": "Le prochain qui parle de travail ou d'école doit boire un shot", + "duree": true, + "arret": "Fin de l'interdiction" + }, + { + "id": 98, + "question": "Karaoké improvisé : choisit une chanson pour ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 99, + "question": "Qui serait le plus susceptible de survivre dans un film de survie ? Votez", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 100, + "question": "Défi cuisine : doit Créez la combinaison d'alcool la plus bizarre avec les ingrédients présents, doit boire la mixture", + "gorger": 2, + "distribution": false, + "recois": true + } + + ] +} diff --git a/app/src/main/assets/questionOLD.json b/app/src/main/assets/questionOLD.json new file mode 100644 index 0000000..0cb1b00 --- /dev/null +++ b/app/src/main/assets/questionOLD.json @@ -0,0 +1,809 @@ +{ + "version": "2", + "questions": [ + { + "id": 1, + "question": "Celles/Ceux qui ont habité dans plus de 3 villes diferentes", + "gorger": 3, + "distribution": true, + "recois": true + + }, + { + "id": 2, + "question": "Ceux qui ont dansé aujourd'hui", + "gorger": 1, + "distribution": true, + "recois": true + }, + { + "id": 3, + "question": "si tu n'as pas ton veritable nom sur insta", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 4, + "question": "si tu a des photos sur insta", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 5, + "question": "Les joueurs de Counter Strike ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 5, + "question": "La dernière personne à avoir vomi en soirée ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 6, + "question": "Toutes celles (ou ceux) qui ont du verni à ongles", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 7, + "question": "Tous les joueurs célibataires", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 8, + "question": "Tous ceux qui ont des lunettes", + "gorger": 2, + "distribution": true, + "recois": true + }, + { + "id": 9, + "question": "Tous ceux qui ont déjà triché à un examen", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 10, + "question": "Le/La plus radin(e)", + "gorger": 4, + "distribution": false, + "recois": true + }, + { + "id": 11, + "question": " a toi de juger : entre et qui stresse le plus pour un rien selon toi? Le perdant ", + "gorger": 5, + "distribution": false, + "recois": true + }, { + "id": 12, + "question": "Le mec qui a le plus gros ventre à bière ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 13, + "question": "Tous ceux qui se sont déjà fait exclure de cours", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 14, + "question": ", donne le nombre d'habitant du/de la ( à 1 000 000 près) Si tu as faux tu bois, sinon tu ", + "gorger": 3, + "distribution": true, + "recois": false, + "variante": ["Tadjikistant", "Monaco", "Belgique", "Suisse", "Allemagne", "Chine", "Inde"] + }, + { + "id": 15, + "question": "Tous ceux qui ont des frères et soeurs", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 16, + "question": " a qui appartient le slogan suivant? ", + "variante": ["Des pâtes oui mais des (panzani)"," Le plaisir pour les petites faims. (Kinder Bueno)","Réveillez le lion qui est en vous. (Cereale lion)","Parce que le monde bouge (CIC)","Ça coule de source ! (Cristaline)", "Pensez différemment (apple)" ], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 17, + "question": "Celles et ceux qui ont eu un Windows phone", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 18, + "question": ", Boire un café fait baisser le taux d'alcool? Si tu as faux ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 19, + "question": "Celles/Ceux qui se sont déjà battus", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 20, + "question": "Celui/Celle qui pèse le plus lourd", + "variante": ["lourd","leger"], + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 21, + "question": "Pour se décoincer, le/la plus ", + "variante": ["timide", "enervé ", "angoissé","aigri"], + "gorger": 2, + "distribution": false, + "recois": true + }, + { + "id": 22, + "question": "Le/La plus ", + "gorger": 3, + "variante": ["jeune","vieille"], + "distribution": false, + "recois": true + }, + { + "id": 23, + "question": "Celles/Ceux qui ont fait des études ", + "gorger": 3, + "variante": ["L","Scientifique", "Bac Professionel", "STMG"], + "distribution": true, + "recois": true + }, + { + "id": 25, + "question": "Celles et ceux qui ont deja joué de maniere recurrente ", + "gorger": 3, + "variante": ["du piano","de la guitare", "du saxophone", "de la batterie"], + "distribution": true, + "recois": true + }, + { + "id": 26, + "question": "Les gens qui se sont masturbés aujourd'hui", + "gorger": 3, + "distribution": true, + "recois": true, + "caliente": true + }, + { + "id": 27, + "question": "Celui ou celle a la meilleure place", + "gorger": 2, + "distribution": false, + "recois": true + }, + { + "id": 28, + "question": "Celles et ceux qui n'ont jamais trompé leur partenaire", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 29, + "question": "Celui/Celle avec les vêtements les plus beaux ", + "gorger": 1, + "distribution": false, + "recois": true + }, + { + "id": 30, + "question": "Celui/Celle qui a les cheveux les plus ", + "gorger": 2, + "variante": ["longs","courts"], + "distribution": true, + "recois": true + }, + { + "id": 31, + "question": "Les végans ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 32, + "question": "La personne la plus maquillé ", + "gorger": 2, + "distribution": true, + "recois": true + }, { + "id": 33, + "question": "Celles/Ceux qui ont déjà appelé leur partenaire par le prénom de leurs ex", + "gorger": 4, + "distribution": false, + "recois": true + }, + { + "id": 34, + "question": "Celles et ceux qui boit de la actuellement", + "gorger": 3, + "distribution": true, + "recois": true, + "variante": ["vodka", "rhum", "tequila", "whisky"] + }, + { + "id": 35, + "question": "Les joueurs qui ont un dans leurs prénom", + "gorger": 3, + "distribution": false, + "recois": true, + "variante": ["a","e","i","o","u","y"] + }, + { + "id": 36, + "question": "Le/La joueur/euse avec le plus gros cul", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 37, + "question": "Celles/Ceux qui ont moins de ans", + "gorger": 3, + "distribution": false, + "recois": true, + "variante": ["21","22","23","24","25","26"] + }, + { + "id": 38, + "question": "Celui/celle avec le plus gros appetit sexuel", + "gorger": 3, + "distribution": false, + "recois": true, + "caliente": true + }, + { + "id": 39, + "question": "Ceux/Celles qui fumes (VapeNation compris)", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 40, + "question": "Celles et ceux qui ont au moins un BAC +", + "gorger": 1, + "distribution": true, + "recois": true, + "variante": [0,1,2,3,4,5] + }, + { + "id": 41, + "question": "Le premier joueur à se lever", + "doubledistribution": true, + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 42, + "question": "Ceux qui n'ont jamais eu l'occasion de faire un strip tease", + "gorger": 3, + "distribution": false, + "recois": true, + "caliente": true + }, + { + "id": 43, + "question": "Le premier joueur à enlever un vêtements", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 44, + "question": "Tous ceux qui ont déjà uriné dans une piscine ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 30, + "question": "Celui/Celle avec le plus de follow sur ", + "gorger": 3, + "distribution": true, + "recois": true, + "variante": ["instagram","facebook","tik-tok"] + }, + { + "id": 31, + "question": "Celui/Celle avec le nom de famille le plus compliqué", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 32, + "question": "Les joueurs qui n'ont pas encore distribué de gorgées", + "gorger": 3, + "distribution": false, + "recois": true + }, { + "id": 33, + "question": "Le premier joueur à donner l'heure", + "doubledistribution": true, + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 34, + "question": "Celles et ceux qui ont déjà dépenser plus de 2000 euros en un achat", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 35, + "question": "La personne la moins courageuse", + "gorger": 1, + "distribution": false, + "recois": true + }, + { + "id": 36, + "question": "Celles/Ceux qui rentre chez eux à la fin de la soirée", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 37, + "question": "Celles et ceux dont le jour d'anniversaire est un nombre ", + "gorger": 3, + "distribution": true, + "recois": true, + "variante": ["impaire","paire"] + }, + { + "id": 38, + "question": "Si tu as un téléphone qui a un prix supperieur d'achat a 1000Euros, tu est riche donc en tant que personne généreuse", + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 39, + "question": "Tous ceux qui ont fait plus de 100km pour venir ici ", + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 40, + "jeux": true, + "question": "Le jeu du revolver: Chaque joueur a maintenant 7 balles, une balle correspondant à une gorgée. Les joueurs ont la capacité de tirer des balles à tout moment du jeu.", + "distribution": false, + "recois": false + }, + { + "id": 41, + "question": "", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 42, + "jeux": true, + "question": " est le vieu/vieille briscard ! Interdiction de montrer tes dents pendant manches", + "manche": true, + "arret": "Tu peux arreter de cacher tes belles dents" + + }, + { + "id": 43, + "jeux": true, + "question": " et liser le premier SMS qui s'affiche quand on tape dans la barre de recherche. le plus marrant", + "gorger": 3, + "variante": ["désolé","caca","bourré","mine","nazi"], + "distribution": true, + "recois": false + }, { + "id": 44, + "jeux": true, + "question": "A tour de role, vous avez exactement 3 secondes pour donner un mot en rapport avec le mots dit precedemment. tu commences en choissisant un mot. Le perdant", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 45, + "jeux": true, + "question": "Le jeu du PIM PAM POUM. Le premier qui perd ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 46, + "jeux": true, + "question": " defie au chifoumi ! Le perdant", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 47, + "jeux": true, + "question": " est dans le ! Tu dois parler au pendant manches ", + "variante": ["passé", "futur"], + "manche": true, + "arret": "Tu est revenu dans le present", + "distribution": false, + "recois": false, + "caliente": false + }, + { + "id": 48, + "question": " tu bois autant de gorgées que tu as d'années d'études après le BAC" + }, + { + "id": 49, + "jeux": true, + "question": " et ferment leurs yeux ! Ils/Elles doivent deviner la couleur des yeux de l'autre. ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 50, + "jeux": true, + "question": " est manchot ! Il/Elle ne peut plus utiliser ses doigts durant manches . Si il s'en sert, il/elle devra boire autant de gorgées qu'il/elle a utilisé de doigts", + "distribution": false, + "arret": "Tu n'es plus manchot", + "recois": false + }, + { + "id": 51, + "jeux": true, + "question": " et , si vous êtes ensemble dans la vraie vie, vous pouvez distribuer 2 gorgées , autrement buvez-les" + + }, + { + "id": 52, + "jeux": true, + "question": " a la tourette ! A chaque fois que tu bois une gorgée, tu dois CRIER une insulte. C'est un stade avancé, ça dure manches", + "manches": true, + "arret": "Tu n'as plus tourette." + + }, + { + "id": 53, + "jeux": true, + "question": ", donne la couleur préférée de si tu te trompes", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 54, + "jeux": true, + "question": " à l'oeil de serpent ! Dès qu'un joueur te regarde dans les yeux, il/elle boit. Si tu es arrivé a faire boire personne avant manches, tu ", + "gorger": 4, + "distribution": false, + "recois": true + }, { + "id": 55, + "jeux": true, + "question": " et se mesurent ! Le/la plus ", + "gorger": 3, + "variante": ["petit","grand"], + "distribution": true, + "recois": true + }, + { + "id": 56, + "jeux": true, + "question": " doit terminer toutes ses phrases par - pendant manches", + "variante": ["C'est clair","han","quoicoubeh"] + }, + { + "id": 57, + "jeux": true, + "question": " et se défient au 'je te tiens, tu me tiens', le premier qui rit sera dechiré, et ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 58, + "jeux": true, + "question": " et n'ont plus le droit d'utiliser leur téléphone pendant manches !", + "manches": "true" + }, + { + "id": 59, + "jeux": true, + "question": " et racontent une anecdote, celui/celle qui sort la plus ", + "variante": ["banale","incroyable","marrante"], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 60, + "jeux": true, + "question": ", Si on te dit Marco? ... Si tu as dis Polo ", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 61, + "jeux": true, + "question": " est l'aigris pendant manches ! Dès que tu souris ou rigoles,", + "gorger": 1, + "manches": true, + "distribution": false, + "arret": "Tu n'es plus aigris!", + "recois": true + }, + { + "id": 62, + "jeux": true, + "question": " fait un geste, le suivant répète et en ajoute un. Le perdant ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 63, + "question": ", et vont désigner quelqu'un qui doit terminer son verre", + "jeux": true + }, + { + "id": 64, + "question": "Récitez l'alphabet en énonçant une lettre à tour de rôle. Si finit son verre avant, cul sec pour tout le monde !", + "jeux": true + }, + { + "id": 65, + "question": "Si arrive a finir son verre en moins de 5 secondes, il/elle ", + "gorger": 6, + "distribution": true, + "recois": false, + "jeux": true + }, + { + "id": 66, + "jeux": true, + "question": " et sont lies, si l'un boit alors l'autre aussi, et ce pendant manches", + "manches": true + }, + { + "id": 67, + "question": " dit un mot, la personne suivante le répète et en ajoute un nouveau, ainsi de suite jusqu'a ce que quelqu'un se trompe. Le perdant boit autant de gorgées qu'il y a eu de personne avant lui", + "jeux": true + }, + { + "id": 68, + "question": " doit choisir un mot que tout le monde devra dire à chaque fois qu'une personne boit. Pendant manches", + "jeux": false, + "manches": true, + "arret": "Plus besoin de dire le mots avant de boire" + }, + { + "id": 69, + "question": "Quand l'heure affichera un multiple de 10 (22h, 22h10 ...) le premier a crier 'merde j'ai oublié mon chat'", + "gorger": 3, + "distribut":false, + "manches": true, + "arret": "Vous avez retrouver le chat!" + }, + { + "id": 70, + "question": "Plutôt ne plus avoir de mains ou de jambes? les perdants ", + "gorger": 3, + "jeux": false, + "distribution": false, + "recois": true + }, + { + "id": 71, + "question": "Vive la poésie ! Nos phrases doivent rimer sous peine d'une gorgée pendant manches", + "manches": true, + "arret": "Vous ne devez plus faire de rime." + }, + { + "id": 72, + "question": "Choisissez le joueur le drôle d'entre vous, ce dernier ", + "variante": ["moins", "plus"], + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 73, + "question": "Les ", + "variante": ["filles","garçons","couples","celibataires"], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 74, + "jeux": true, + "question": "Plutôt avoir un tapis volant, ou un frigo qui se remplit tout seul ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true, + "manches": false + }, + { + "id": 75, + "question": "Plutôt avoir du temps ou de l'argent ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + + }, + { + "id": 76, + "question": "Le premier joueur qui en embrasse un autre sur la bouche", + "gorger": 5, + "distribution": true, + "recois": false, + "caliente": true + }, + { + "id": 77, + "question": "Plutôt série ou film ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 78, + "question": "Plutôt jeux-videos ou livre ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + + { + "id": 79, + "question": "Plutôt anime ou jeux-videos ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 80, + "question": "Elisez le plus d'entre vous, ce dernier ", + "variante": ["con", "intelligent", "beau", "gentil","dragueur","timide"], + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 81, + "question": "Le premier qui donne un film de ", + "gorger": 3, + "distribution": true, + "recois": false, + "variante": ["Christopher Nolan","James Cameron","Tim Burton","Quentin tarantino","Steven Spielberg"] + }, + { + "id": 82, + "question": "Le premier qui donne un film avec ", + "variante": ["Christian Clavier","Morgan freeman","Brad Pitt", "Jean Reno","Marion Cotillard"], + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 83, + "question": "La première personne qui désigne le/la plus ", + "gorger": 3, + "distribution": true, + "recois": false, + "variante": ["jeune", "vieille"] + }, + { + "id": 84, + "question": "Plutôt avoir des connaissances illimitées ou diriger le monde ? Votez tous en même temps. La minorité", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 85, + "question": "Plutôt n'avoir aucun ami ou ne plus pouvoir utiliser d'appareil électronique ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 86, + "question": "Plutot vaincre le patrikaka ou la polution dans le monde? Votez tous en meme temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 87, + "question": "Jeu du LUTIN : Pendant manches. Vous devez enlever le lutin de votre verre pour pouvoir boire et le remettre ensuite sinon vous devait reboire", + "gorger": 3, + "distribution": false, + "recois": false, + "manches": true, + "arret": "Le Lutin est parti. Vous pouvez boire normalement" + }, + { + "id": 88, + "question": "Le premier joueur à ramener un objet (pas de vêtements) ", + "gorger": 3, + "distribution": true, + "variante": ["rouge","vert","bleu","jaune"], + "recois": false, + "manches": false + }, + { + "id": 89, + "question": "Le premier joueur qui dévoile un de ses secrets et que personne ne sait ", + "gorger": 3, + "distribution": true, + "recois": false + }, + { + "id": 90, + "question": "Jeu des peaux! Triez vous du joueur le plus bronzé au joueur le moins bronzé. Le plus bronzé prend 1 gorgée, le second 2 gorgées, etc.", + "gorger": 3, + "distribution": true, + "recois": true + }, + { + "id": 91, + "question": "Plutôt avoir du pouvoir ou de la connaissance ? Votez tous en même temps. La minorité ", + "gorger": 3, + "distribution": false, + "recois": true + }, + { + "id": 92, + "question": "Il est désormais interdit de se tutoyer pendant manches", + "manches": true, + "arret":"Vous pouvez vous tutoyer" + + }, + { + "id": 93, + "question": "Vaccin contre le COVID19 : Le DR Raoul à dit que boire un cul sec avait les mêmes effets que le vaccin. Tout le monde bois sont verre cul sec" + }, + { + "id": 94, + "question": "Faites un concours de clash : Rap contenders entre et le perdant ", + "gorger": 3, + "distribution": false, + "recois": true + } + ] +} diff --git a/app/src/main/java/com/example/boidelov3/BoideloAnimationUtils.java b/app/src/main/java/com/example/boidelov3/BoideloAnimationUtils.java new file mode 100644 index 0000000..bedb1d4 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/BoideloAnimationUtils.java @@ -0,0 +1,415 @@ +package com.example.boidelov3; + +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; +import android.os.VibrationEffect; +import android.os.Vibrator; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; +import android.view.animation.OvershootInterpolator; + +import androidx.core.content.ContextCompat; + +/** + * Classe utilitaire pour les animations et effets visuels + */ +public class BoideloAnimationUtils { + + private static final Interpolator OVERSHOOT = new OvershootInterpolator(); + + /** + * Anime le changement de couleur de fond d'une vue + * + * @param view La vue à animer + * @param targetColor La couleur cible + * @param duration La durée de l'animation en ms + */ + public static void animateBackgroundColor(View view, int targetColor, int duration) { + if (view == null) return; + + int currentColor = getBackgroundColor(view); + if (currentColor == targetColor) return; + + ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), currentColor, targetColor); + anim.setDuration(duration); + anim.addUpdateListener(animation -> { + int color = (int) animation.getAnimatedValue(); + view.setBackgroundColor(color); + }); + anim.start(); + } + + /** + * Anime le changement de couleur de fond avec la durée par défaut (500ms) + */ + public static void animateBackgroundColor(View view, int targetColor) { + animateBackgroundColor(view, targetColor, 500); + } + + /** + * Obtient la couleur de fond actuelle d'une vue + */ + private static int getBackgroundColor(View view) { + if (view.getBackground() instanceof ColorDrawable) { + return ((ColorDrawable) view.getBackground()).getColor(); + } + return 0xFFFFFFFF; // Blanc par défaut + } + + /** + * Déclenche une vibration haptique + * + * @param context Le contexte + * @param duration Durée de la vibration en ms + */ + public static void triggerHapticFeedback(Context context, int duration) { + if (context == null) return; + + Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if (vibrator != null && vibrator.hasVibrator()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + VibrationEffect effect = VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE); + vibrator.vibrate(effect); + } else { + vibrator.vibrate(duration); + } + } + } + + /** + * Déclenche une vibration haptique courte (100ms) + */ + public static void triggerHapticFeedback(Context context) { + triggerHapticFeedback(context, 100); + } + + /** + * Déclenche une vibration haptique de succès + */ + public static void triggerSuccessHaptic(Context context) { + if (context == null) return; + + Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if (vibrator != null && vibrator.hasVibrator() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + long[] pattern = {0, 50, 50, 50}; + VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1); + vibrator.vibrate(effect); + } + } + + /** + * Déclenche une vibration haptique d'erreur + */ + public static void triggerErrorHaptic(Context context) { + if (context == null) return; + + Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); + if (vibrator != null && vibrator.hasVibrator() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + long[] pattern = {0, 100, 50, 100}; + VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1); + vibrator.vibrate(effect); + } + } + + /** + * Anime l'apparition d'une vue avec un effet de fade-in + * + * @param view La vue à animer + * @param duration Durée de l'animation + */ + public static void fadeIn(View view, int duration) { + if (view == null) return; + + view.setAlpha(0f); + view.setVisibility(View.VISIBLE); + view.animate() + .alpha(1f) + .setDuration(duration) + .start(); + } + + /** + * Anime la disparition d'une vue avec un effet de fade-out + * + * @param view La vue à animer + * @param duration Durée de l'animation + */ + public static void fadeOut(View view, int duration) { + if (view == null) return; + + view.animate() + .alpha(0f) + .setDuration(duration) + .withEndAction(() -> view.setVisibility(View.GONE)) + .start(); + } + + /** + * Anime une vue avec un effet de scale + * + * @param view La vue à animer + * @param scale Échelle cible (1.0 = normal, 0.5 = moitié) + * @param duration Durée de l'animation + */ + public static void scale(View view, float scale, int duration) { + if (view == null) return; + + view.animate() + .scaleX(scale) + .scaleY(scale) + .setDuration(duration) + .setInterpolator(OVERSHOOT) + .start(); + } + + /** + * Anime une vue avec un effet de slide depuis le bas + * + * @param view La vue à animer + * @param duration Durée de l'animation + */ + public static void slideUp(View view, int duration) { + if (view == null) return; + + view.setTranslationY(view.getHeight()); + view.setVisibility(View.VISIBLE); + view.animate() + .translationY(0f) + .setDuration(duration) + .setInterpolator(new android.view.animation.DecelerateInterpolator()) + .start(); + } + + /** + * Applique une animation de pression à un bouton + * + * @param view La vue (bouton) à animer + */ + public static void applyButtonPressAnimation(View view) { + if (view == null) return; + + view.setOnTouchListener((v, event) -> { + switch (event.getAction()) { + case android.view.MotionEvent.ACTION_DOWN: + v.animate() + .scaleX(0.95f) + .scaleY(0.95f) + .setDuration(100) + .start(); + return true; + case android.view.MotionEvent.ACTION_UP: + case android.view.MotionEvent.ACTION_CANCEL: + v.animate() + .scaleX(1f) + .scaleY(1f) + .setDuration(100) + .start(); + v.performClick(); + return true; + } + return false; + }); + } + + /** + * Anime une vue avec un effet de pulsation + * + * @param view La vue à animer + * @param duration Durée d'un cycle de pulsation + */ + public static void pulse(View view, int duration) { + if (view == null) return; + + view.animate() + .scaleX(1.05f) + .scaleY(1.05f) + .setDuration(duration / 2) + .withEndAction(() -> { + view.animate() + .scaleX(1f) + .scaleY(1f) + .setDuration(duration / 2) + .start(); + }) + .start(); + } + + /** + * Anime une vue avec un effet de shake (tremblement) + * + * @param view La vue à animer + */ + public static void shake(View view) { + if (view == null) return; + + Animation shake = AnimationUtils.loadAnimation(view.getContext(), R.anim.button_press); + view.startAnimation(shake); + } + + /** + * Obtient la couleur depuis une ressource de couleur + */ + public static int getColorFromResource(Context context, int colorResId) { + return ContextCompat.getColor(context, colorResId); + } + + /** + * Anime une vue avec un effet de bounce (rebond) + * + * @param view La vue à animer + * @param duration Durée de l'animation + */ + public static void bounce(View view, int duration) { + if (view == null) return; + + view.animate() + .scaleY(0.8f) + .scaleX(0.8f) + .setDuration(duration / 2) + .setInterpolator(new android.view.animation.DecelerateInterpolator()) + .withEndAction(() -> { + view.animate() + .scaleY(1f) + .scaleX(1f) + .setDuration(duration / 2) + .setInterpolator(OVERSHOOT) + .start(); + }) + .start(); + } + + /** + * Anime une vue pour la supprimer (slide out + fade out) + * + * @param view La vue à animer + * @param duration Durée de l'animation + * @param endAction Action à exécuter après l'animation + */ + public static void slideOutToRemove(View view, int duration, Runnable endAction) { + if (view == null) return; + + view.animate() + .translationX(-view.getWidth()) + .alpha(0f) + .setDuration(duration) + .setInterpolator(new android.view.animation.AccelerateInterpolator()) + .withEndAction(endAction) + .start(); + } + + /** + * Anime l'apparition d'une vue (slide in + fade in) + * + * @param view La vue à animer + * @param duration Durée de l'animation + */ + public static void slideIn(View view, int duration) { + if (view == null) return; + + view.setTranslationX(view.getWidth()); + view.setAlpha(0f); + view.setVisibility(View.VISIBLE); + view.animate() + .translationX(0f) + .alpha(1f) + .setDuration(duration) + .setInterpolator(new android.view.animation.DecelerateInterpolator()) + .start(); + } + + /** + * Anime une vue avec un effet de rotation + * + * @param view La vue à animer + * @param degrees Angle de rotation en degrés + * @param duration Durée de l'animation + */ + public static void rotate(View view, float degrees, int duration) { + if (view == null) return; + + view.animate() + .rotation(degrees) + .setDuration(duration) + .setInterpolator(new android.view.animation.DecelerateInterpolator()) + .start(); + } + + /** + * Anime une vue avec un effet de wiggle (gauche-droite) + * + * @param view La vue à animer + */ + public static void wiggle(View view) { + if (view == null) return; + + view.animate() + .rotation(5f) + .setDuration(50) + .withEndAction(() -> { + view.animate() + .rotation(-5f) + .setDuration(50) + .withEndAction(() -> { + view.animate() + .rotation(3f) + .setDuration(50) + .withEndAction(() -> { + view.animate() + .rotation(0f) + .setDuration(50) + .start(); + }) + .start(); + }) + .start(); + }) + .start(); + } + + /** + * Anime une vue avec un effet de pop-in (apparition avec scale) + * + * @param view La vue à animer + * @param duration Durée de l'animation + */ + public static void popIn(View view, int duration) { + if (view == null) return; + + view.setScaleX(0f); + view.setScaleY(0f); + view.setAlpha(0f); + view.setVisibility(View.VISIBLE); + view.animate() + .scaleX(1f) + .scaleY(1f) + .alpha(1f) + .setDuration(duration) + .setInterpolator(OVERSHOOT) + .start(); + } + + /** + * Anime une vue avec un effet de pop-out (disparition avec scale) + * + * @param view La vue à animer + * @param duration Durée de l'animation + * @param endAction Action à exécuter après l'animation + */ + public static void popOut(View view, int duration, Runnable endAction) { + if (view == null) return; + + view.animate() + .scaleX(0f) + .scaleY(0f) + .alpha(0f) + .setDuration(duration) + .setInterpolator(new android.view.animation.AccelerateInterpolator()) + .withEndAction(endAction) + .start(); + } +} diff --git a/app/src/main/java/com/example/boidelov3/ChatGPTTask.java b/app/src/main/java/com/example/boidelov3/ChatGPTTask.java new file mode 100644 index 0000000..e71b9d5 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/ChatGPTTask.java @@ -0,0 +1,85 @@ +package com.example.boidelov3; + +//public class ChatGPTTask extends AsyncTask { +//// private Jeux jeuxActivity; +//// private String keyOpenai; +//// +//// public ChatGPTTask(Jeux jeuxActivity, String keyOpenai) { +//// this.jeuxActivity = jeuxActivity; +//// this.keyOpenai = keyOpenai; +//// } +//// +//// +//// @Override +//// protected String doInBackground(Void... voids) { +//// String url = "https://api.openai.com/v1/chat/completions"; +//// String apiKey = keyOpenai; +//// System.out.println("apiKey de ChatGPTTASK.java: " + apiKey); +//// String model = "gpt-3.5-turbo"; +//// +//// String prompt = "Tu es une IA française qui génère des questions ainsi que la categories de la question. Voici des exemples :" + +//// "Celles/Ceux qui ont habité dans plus de 3 villes diferentes';'La vie" + +//// "Ceux qui ont dansé aujourd'hui' ; 'Soirée'" + +//// "'Pour se décoincer, le/la plus timide' ; 'Caractère'" + +//// "'Celles et ceux qui ont déjà dépenser plus de 2000 euros en un achat' ; 'Dépense'" + +//// "'Le/La plus radin(e)' ; 'Caractère'"; +// +//// try { +//// URL obj = new URL(url); +//// HttpURLConnection connection = (HttpURLConnection) obj.openConnection(); +//// connection.setRequestMethod("POST"); +//// connection.setRequestProperty("Authorization", "Bearer " + apiKey); +//// connection.setRequestProperty("Content-Type", "application/json"); +//// +//// // The request body +//// String body = "{\"model\": \"" + model + "\", \"messages\": [{\"role\": \"user\", \"content\": \"" + prompt + "\"}]}"; +//// System.out.println("body: " + body); +//// connection.setDoOutput(true); +//// OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); +//// writer.write(body); +//// writer.flush(); +//// writer.close(); +//// +//// // Response from ChatGPT +//// BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); +//// String line; +//// +//// StringBuffer response = new StringBuffer(); +//// +//// while ((line = br.readLine()) != null) { +//// response.append(line); +//// } +//// br.close(); +//// +//// // calls the method to extract the message. +//// return extractMessageFromJSONResponse(response.toString()); +//// +//// } catch (IOException e) { +//// System.out.println("Il y a eu une erreur" + e); +//// throw new RuntimeException(e); +//// +//// } +//// } +//// +//// public String extractMessageFromJSONResponse(String response) { +//// int start = response.indexOf("content") + 11; +//// int end = response.indexOf("\"", start); +//// String extractedMessage = response.substring(start, end); +//// System.out.println("extractedMessage: " + extractedMessage); +//// return extractedMessage; +//// } +//// +//// @Override +//// protected void onPostExecute(String result) { +//// if (result != null) { +//// // Handle the extracted message here +//// jeuxActivity.handleExtractedMessage(result); +//// } else { +//// Toast.makeText(jeuxActivity.getApplicationContext(), "Échec de la communication avec l'API !", Toast.LENGTH_SHORT).show(); +//// jeuxActivity.navigateToJeuxParametres(); +//// } +//// } +// +// +// return url; +// }} \ No newline at end of file diff --git a/app/src/main/java/com/example/boidelov3/DatabaseConnection.java b/app/src/main/java/com/example/boidelov3/DatabaseConnection.java new file mode 100644 index 0000000..4e3db86 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/DatabaseConnection.java @@ -0,0 +1,40 @@ +package com.example.boidelov3; + +import android.os.AsyncTask; + +import com.impossibl.postgres.api.jdbc.PGConnection; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class DatabaseConnection extends AsyncTask { + private static final String DB_URL = "jdbc:postgresql://82.65.214.214:5432/boidelo"; + private static final String USER = "Tux2543"; + private static final String PASSWORD = "6wa*teCnuxsG#grAc5HzC!Rh%#@c&"; + + @Override + protected PGConnection doInBackground(Void... params) { + PGConnection connection = null; + try { + // Code de connexion à la base de données PostgreSQL + String url = DB_URL; + String username = USER; + String password = PASSWORD; + connection = (PGConnection) DriverManager.getConnection(url, username, password); + } catch (SQLException e) { + e.printStackTrace(); + } + return connection; + } + + + protected void onPostExecute(Connection connection) { + // Traitez le résultat de la connexion ici + if (connection != null) { + // Connexion réussie + } else { + // Échec de la connexion + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/boidelov3/EndGameActivity.java b/app/src/main/java/com/example/boidelov3/EndGameActivity.java new file mode 100644 index 0000000..e2a5827 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/EndGameActivity.java @@ -0,0 +1,191 @@ +package com.example.boidelov3; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.animation.DecelerateInterpolator; +import android.widget.TextView; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; + +import com.google.android.material.button.MaterialButton; + +import java.util.ArrayList; + +/** + * Activité de fin de partie + * Affiche un résumé de la partie et permet de rejouer ou retourner à l'accueil + */ +public class EndGameActivity extends AppCompatActivity { + + // Vues + private TextView questionsPlayedValue; + private TextView playersCountValue; + private TextView gorgeesTotalValue; + private MaterialButton homeButton; + private MaterialButton replayButton; + + // Données + private int questionsPlayed; + private int playersCount; + private ArrayList players; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_end_game); + + // Initialiser les vues + initViews(); + + // Récupérer les données de la partie + getGameData(); + + // Afficher les statistiques + displayStats(); + + // Configurer les boutons + setupButtons(); + + // Animations d'entrée + animateEntry(); + } + + /** + * Initialise toutes les vues + */ + private void initViews() { + questionsPlayedValue = findViewById(R.id.questionsPlayedValue); + playersCountValue = findViewById(R.id.playersCountValue); + gorgeesTotalValue = findViewById(R.id.gorgeesTotalValue); + homeButton = findViewById(R.id.homeButton); + replayButton = findViewById(R.id.replayButton); + + // Appliquer les animations aux boutons + BoideloAnimationUtils.applyButtonPressAnimation(homeButton); + BoideloAnimationUtils.applyButtonPressAnimation(replayButton); + } + + /** + * Récupère les données de la partie terminée + */ + private void getGameData() { + // Récupérer les données depuis l'intent + questionsPlayed = getIntent().getIntExtra("EXTRA_QUESTIONS_PLAYED", 0); + playersCount = getIntent().getIntExtra("EXTRA_PLAYERS_COUNT", 0); + players = getIntent().getStringArrayListExtra("EXTRA_PLAYERS"); + + // Si pas de données, utiliser les SharedPreferences + if (questionsPlayed == 0) { + android.content.SharedPreferences prefs = getSharedPreferences("game_stats", Context.MODE_PRIVATE); + questionsPlayed = prefs.getInt("questions_played", 0); + playersCount = prefs.getInt("players_count", 0); + } + } + + /** + * Affiche les statistiques de la partie + */ + private void displayStats() { + // Animer les chiffres + animateValue(questionsPlayedValue, 0, questionsPlayed, 1000); + animateValue(playersCountValue, 0, playersCount, 1000); + + // Afficher les joueurs (simplifié pour l'instant) + if (players != null && !players.isEmpty()) { + StringBuilder playersText = new StringBuilder(); + for (int i = 0; i < players.size(); i++) { + if (i > 0) playersText.append(", "); + playersText.append(players.get(i)); + } + } + + // Afficher un message de félicitations + showCongratulationMessage(); + } + + /** + * Affiche un message de félicitations selon le nombre de questions + */ + private void showCongratulationMessage() { + // Le message pourrait être personnalisé selon les performances + // Pour l'instant, on utilise le titre par défaut du layout + } + + /** + * Configure les boutons + */ + private void setupButtons() { + homeButton.setOnClickListener(v -> { + BoideloAnimationUtils.triggerHapticFeedback(this); + goToHome(); + }); + + replayButton.setOnClickListener(v -> { + BoideloAnimationUtils.triggerSuccessHaptic(this); + replay(); + }); + } + + /** + * Retourne à l'écran d'accueil + */ + private void goToHome() { + Intent intent = new Intent(this, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + finish(); + } + + /** + * Relance une nouvelle partie + */ + private void replay() { + Intent intent = new Intent(this, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + finish(); + } + + /** + * Anime l'entrée des éléments + */ + private void animateEntry() { + // Animation du trophée + View trophyIcon = findViewById(R.id.trophyIcon); + BoideloAnimationUtils.scale(trophyIcon, 1.0f, 400); + + // Animation fade-in pour le contenu + View titleText = findViewById(R.id.titleText); + View subtitleText = findViewById(R.id.subtitleText); + + BoideloAnimationUtils.fadeIn(titleText, 600); + BoideloAnimationUtils.fadeIn(subtitleText, 800); + } + + /** + * Anime un chiffre de 0 à la valeur cible + */ + private void animateValue(TextView textView, int start, int end, int duration) { + if (textView == null) return; + + android.animation.ValueAnimator animator = android.animation.ValueAnimator.ofInt(start, end); + animator.setDuration(duration); + animator.setInterpolator(new DecelerateInterpolator()); + + animator.addUpdateListener(animation -> { + int value = (int) animation.getAnimatedValue(); + textView.setText(String.valueOf(value)); + }); + + animator.start(); + } + + @Override + public void onBackPressed() { + // Retourner à l'accueil au lieu de revenir au jeu + goToHome(); + } +} diff --git a/app/src/main/java/com/example/boidelov3/Jeux.java b/app/src/main/java/com/example/boidelov3/Jeux.java new file mode 100644 index 0000000..7975afb --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/Jeux.java @@ -0,0 +1,687 @@ +package com.example.boidelov3; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.os.Bundle; +import android.text.Html; +import android.view.View; +import android.view.animation.DecelerateInterpolator; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; + +import com.google.android.material.button.MaterialButton; +import com.google.gson.Gson; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * Activité principale du jeu Boidelo + * Affiche les questions et gère les interactions de jeu + */ +public class Jeux extends AppCompatActivity { + // Vues + private TextView questionTextView; + private TextView progressTextView; + private TextView mancheCounterTextView; + private TextView mancheQuestionText; + private ProgressBar progressBar; + private MaterialButton suivantButton; + private MaterialButton skipButton; + private LinearLayout questionIndicator; + private ImageView indicatorIcon; + private TextView indicatorText; + + // Données + private Questions questions; + private List toutlesjoueurs; + private List questionsAvecManches = new ArrayList<>(); + + // Paramètres de partie + private int nombreQuestions; + private int ajoutGorgees; + private boolean openAI; + private int ratiOpenai; + private String keyOpenai; + + // État du jeu + private int currentQuestionIndex = 0; + private int totalQuestionsAsked = 0; + private String currentQuestionText = ""; + private boolean isMancheActive = false; + + // Clés pour sauvegarde d'état + private static final String KEY_TOTAL_QUESTIONS = "total_questions_asked"; + private static final String KEY_CURRENT_QUESTION_TEXT = "current_question_text"; + private static final String KEY_IS_MANCHE_ACTIVE = "is_manche_active"; + private static final String KEY_MANCHES_COUNT = "manches_count"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_jeux); + + // Initialiser les vues + initViews(); + + // Récupération des données passées par l'activité précédente + toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR"); + nombreQuestions = getIntent().getIntExtra("EXTRA_NOMBRE_QUESTIONS", 50); + ajoutGorgees = getIntent().getIntExtra("EXTRA_AJOUT_GORGEE", 0); + openAI = getIntent().getBooleanExtra("EXTRA_OPENAI", false); + ratiOpenai = getIntent().getIntExtra("EXTRA_RATIO_OPENAI", 0); + keyOpenai = getIntent().getStringExtra("EXTRA_KEY_OPENAI"); + + // Charger les questions depuis le JSON + loadQuestions(); + + // Configurer la barre de progression + setupProgressBar(); + + // Restaurer l'état si disponible (rotation) + if (savedInstanceState != null) { + restoreGameState(savedInstanceState); + } else { + // Afficher la première question + updateQuestion(); + } + + // Configuration des listeners de boutons + setupButtonListeners(); + } + + /** + * Initialise toutes les vues de l'activité + */ + private void initViews() { + questionTextView = findViewById(R.id.textView1); + progressTextView = findViewById(R.id.progressText); + mancheCounterTextView = findViewById(R.id.mancheCounter); + mancheQuestionText = findViewById(R.id.mancheQuestionText); + progressBar = findViewById(R.id.progressBar); + suivantButton = findViewById(R.id.button); + skipButton = findViewById(R.id.skipButton); + questionIndicator = findViewById(R.id.questionIndicator); + indicatorIcon = findViewById(R.id.indicatorIcon); + indicatorText = findViewById(R.id.indicatorText); + + // Appliquer les animations aux boutons + BoideloAnimationUtils.applyButtonPressAnimation(suivantButton); + BoideloAnimationUtils.applyButtonPressAnimation(skipButton); + + // Initialiser la couleur de fond (respecte le mode jour/nuit) + int backgroundColor = ContextCompat.getColor(this, R.color.game_normal); + getWindow().getDecorView().setBackgroundColor(backgroundColor); + } + + /** + * Charge les questions depuis le fichier JSON + */ + private void loadQuestions() { + try { + InputStream is = getAssets().open("question.json"); + int size = is.available(); + byte[] buffer = new byte[size]; + is.read(buffer); + is.close(); + String json = new String(buffer, "UTF-8"); + + Gson gson = new Gson(); + questions = gson.fromJson(json, Questions.class); + } catch (IOException ex) { + ex.printStackTrace(); + Toast.makeText(this, "Erreur de chargement des questions", Toast.LENGTH_SHORT).show(); + } + } + + /** + * Configure la barre de progression initiale + */ + private void setupProgressBar() { + progressBar.setMax(nombreQuestions); + progressBar.setProgress(0); + updateProgressText(); + } + + /** + * Configure les listeners des boutons + */ + private void setupButtonListeners() { + suivantButton.setOnClickListener(v -> { + BoideloAnimationUtils.triggerHapticFeedback(this); + updateQuestion(); + }); + + skipButton.setOnClickListener(v -> { + BoideloAnimationUtils.triggerHapticFeedback(this); + skipQuestion(); + }); + } + + /** + * Met à jour le texte de progression + */ + private void updateProgressText() { + progressTextView.setText("Question " + (totalQuestionsAsked + 1) + " / " + nombreQuestions); + } + + /** + * Met à jour la barre de progression + */ + private void updateProgressBar() { + progressBar.setProgress(totalQuestionsAsked); + updateProgressText(); + } + + /** + * Met à jour la question affichée avec toutes les animations + */ + private void updateQuestion() { + // Vérifier si toutes les questions ont été posées + if (totalQuestionsAsked >= nombreQuestions) { + // Vérifier s'il y a encore des manches actives + if (!questionsAvecManches.isEmpty()) { + // Afficher le message de fin de manche et terminer + showFinalMancheEndMessage(); + return; + } + endGame(); + return; + } + + // Gérer les questions avec manches actives + Iterator iterator = questionsAvecManches.iterator(); + boolean hasMancheActive = false; + while (iterator.hasNext()) { + Question mancheQuestion = iterator.next(); + mancheQuestion.setManchesRestantes(mancheQuestion.getManchesRestantes() - 1); + + if (mancheQuestion.getManchesRestantes() <= 0) { + // Afficher brièvement le message d'arrêt et continuer + showMancheEndNotification(mancheQuestion.getArretMessageManche()); + iterator.remove(); + // Continuer avec une nouvelle question après la fin de manche + break; + } else { + // Afficher la question de manche en petit et continuer + hasMancheActive = true; + displayMancheQuestionSmall(mancheQuestion); + break; // Un seul défi à manches à la fois + } + } + + // Afficher une nouvelle question (que ce soit pendant ou hors manche) + Question question = getRandomQuestion(); + if (question != null) { + displayQuestion(question, hasMancheActive); + totalQuestionsAsked++; + updateProgressBar(); + } else { + endGame(); + } + } + + /** + * Affiche une notification de fin de manche (sans bloquer le jeu) + */ + private void showMancheEndNotification(String message) { + // Afficher un Toast avec le message de fin + Toast.makeText(this, message, Toast.LENGTH_LONG).show(); + + // Vibration de succès + BoideloAnimationUtils.triggerSuccessHaptic(this); + + // Masquer le compteur de manches et l'indicateur + mancheCounterTextView.setVisibility(View.GONE); + questionIndicator.setVisibility(View.GONE); + mancheQuestionText.setVisibility(View.GONE); + + // Animation de fond jaune temporaire + int yellowColor = ContextCompat.getColor(this, R.color.game_manche_end); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), yellowColor); + + // Revenir à la couleur normale après un délai + mancheCounterTextView.postDelayed(() -> { + int defaultColor = ContextCompat.getColor(this, R.color.game_normal); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), defaultColor); + }, 1000); + } + + /** + * Affiche le message de fin de manche finale (quand le jeu se termine) + */ + private void showFinalMancheEndMessage() { + // Récupérer le message de la dernière manche + if (!questionsAvecManches.isEmpty()) { + Question lastManche = questionsAvecManches.get(0); + questionTextView.setText(Html.fromHtml(lastManche.getArretMessageManche(), Html.FROM_HTML_MODE_LEGACY)); + } + + // Animation de fond jaune + int yellowColor = ContextCompat.getColor(this, R.color.game_manche_end); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), yellowColor); + + // Vibration de succès + BoideloAnimationUtils.triggerSuccessHaptic(this); + + // Masquer le compteur et l'indicateur + mancheCounterTextView.setVisibility(View.GONE); + questionIndicator.setVisibility(View.GONE); + mancheQuestionText.setVisibility(View.GONE); + + // Terminer après un délai + mancheCounterTextView.postDelayed(() -> { + questionsAvecManches.clear(); + endGame(); + }, 3000); + } + + /** + * Affiche une question de manche en petit (sans bloquer le jeu) + */ + private void displayMancheQuestionSmall(Question question) { + // Afficher la question de manche en petit avec le nombre de manches restantes + String mancheQuestion = question.getQuestion() + " (" + question.getManchesRestantes() + " manche(s) restante(s))"; + mancheQuestionText.setText(Html.fromHtml(mancheQuestion, Html.FROM_HTML_MODE_LEGACY)); + mancheQuestionText.setVisibility(View.VISIBLE); + + // Mettre à jour le compteur + updateMancheCounter(question.getManchesRestantes(), question.getQuestion()); + } + + /** + * Affiche une question de manche active (ancienne méthode, plus utilisée) + */ + private void displayMancheQuestion(Question question) { + questionTextView.setText(Html.fromHtml(question.getQuestion(), Html.FROM_HTML_MODE_LEGACY)); + + // Fond bleu pour les manches + int blueColor = ContextCompat.getColor(this, R.color.game_question_manche); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), blueColor); + + // Afficher l'indicateur de manche + showQuestionIndicator(R.drawable.ic_manche, "Manche en cours"); + + // Mettre à jour le compteur + updateMancheCounter(question.getManchesRestantes(), question.getQuestion()); + } + + /** + * Met à jour le compteur de manches (affiché comme rappel) + */ + private void updateMancheCounter(int manchesRestantes, String mancheQuestion) { + mancheCounterTextView.setText("Défi en cours: " + manchesRestantes + " tour(s) restant(s)"); + mancheCounterTextView.setVisibility(View.VISIBLE); + + // Afficher l'indicateur de manche en haut + showQuestionIndicator(R.drawable.ic_manche, "Manche en cours"); + + // Animation du compteur + BoideloAnimationUtils.pulse(mancheCounterTextView, 300); + } + + /** + * Affiche une nouvelle question + */ + private void displayQuestion(Question question, boolean hasMancheActive) { + questionTextView.setText(Html.fromHtml(question.getQuestion(), Html.FROM_HTML_MODE_LEGACY)); + + // Masquer ou afficher la question de manche selon l'état + if (!hasMancheActive) { + mancheQuestionText.setVisibility(View.GONE); + } + + // Déterminer le type de question et animer le fond en conséquence + String questionText = question.getQuestion(); + + // Réinitialiser les indicateurs + questionIndicator.setVisibility(View.GONE); + mancheCounterTextView.setVisibility(View.GONE); + + // Fond par défaut (respecte le mode jour/nuit) + int defaultColor = ContextCompat.getColor(this, R.color.game_normal); + BoideloAnimationUtils.animateBackgroundColor( + getWindow().getDecorView(), + defaultColor + ); + + // Vérifier le type de question + boolean isJoueurs1 = questionText.contains(""); + boolean isJoueurs2 = questionText.contains(""); + boolean isJoueurs3 = questionText.contains(""); + boolean hasManches = questionText.contains(""); + + if (hasManches) { + int blueColor = ContextCompat.getColor(this, R.color.game_question_manche); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), blueColor); + showQuestionIndicator(R.drawable.ic_manche, "Défi à manches"); + } else if (isJoueurs1 && isJoueurs2 && isJoueurs3) { + int greenDarkColor = ContextCompat.getColor(this, R.color.game_question_3players); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), greenDarkColor); + showQuestionIndicator(R.drawable.ic_player_three, "3 joueurs"); + } else if (isJoueurs1 && isJoueurs2) { + int greenColor = ContextCompat.getColor(this, R.color.game_question_2players); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), greenColor); + showQuestionIndicator(R.drawable.ic_player_two, "2 joueurs"); + } else if (isJoueurs1) { + int greenLightColor = ContextCompat.getColor(this, R.color.game_question_1player); + BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), greenLightColor); + showQuestionIndicator(R.drawable.ic_player_one, "1 joueur"); + } + } + + /** + * Affiche l'indicateur de type de question + */ + private void showQuestionIndicator(int iconRes, String text) { + indicatorIcon.setImageResource(iconRes); + indicatorText.setText(text); + questionIndicator.setVisibility(View.VISIBLE); + BoideloAnimationUtils.fadeIn(questionIndicator, 300); + } + + /** + * Passe la question actuelle + */ + private void skipQuestion() { + // Marquer la question comme posée pour ne pas la revoir + totalQuestionsAsked++; + updateProgressBar(); + updateQuestion(); + } + + /** + * Termine la partie et affiche l'écran de fin + */ + private void endGame() { + // Sauvegarder les statistiques de la partie + saveGameStats(); + + // Lancer l'activité de fin de partie + Intent intent = new Intent(this, EndGameActivity.class); + intent.putExtra("EXTRA_QUESTIONS_PLAYED", totalQuestionsAsked); + intent.putExtra("EXTRA_PLAYERS_COUNT", toutlesjoueurs != null ? toutlesjoueurs.size() : 0); + intent.putStringArrayListExtra("EXTRA_PLAYERS", (ArrayList) toutlesjoueurs); + startActivity(intent); + + // Animation de transition + overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + + // Vibration de fin + BoideloAnimationUtils.triggerErrorHaptic(this); + + // Réinitialiser les questions posées pour une prochaine partie + resetAskedQuestions(); + + // Terminer l'activité + finish(); + } + + /** + * Sauvegarde les statistiques de la partie + */ + private void saveGameStats() { + SharedPreferences prefs = getSharedPreferences("game_stats", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt("questions_played", totalQuestionsAsked); + editor.putInt("players_count", toutlesjoueurs != null ? toutlesjoueurs.size() : 0); + editor.apply(); + } + + /** + * Réinitialise la liste des questions posées + */ + private void resetAskedQuestions() { + SharedPreferences prefs = getSharedPreferences("app", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + editor.remove("askedQuestions"); + editor.apply(); + } + + /** + * Sélectionne trois joueurs aléatoires différents + */ + public List TroisJoueurAleatoire(List toutlesjoueurs) { + Set setJoueur = new HashSet<>(); + Random rand = new Random(); + + while (setJoueur.size() < 3 && toutlesjoueurs.size() >= 3) { + setJoueur.add(toutlesjoueurs.get(rand.nextInt(toutlesjoueurs.size()))); + } + + return new ArrayList<>(setJoueur); + } + + /** + * Récupère le message d'arrêt par ID + */ + private String getArretById(int id) { + for (Question question : questions.getQuestions()) { + if (question.getId() == id) { + return question.getArret(); + } + } + return null; + } + + /** + * Obtient une question aléatoire qui n'a pas encore été posée + */ + private Question getRandomQuestion() { + if (questions == null) { + return null; + } + + SharedPreferences prefs = getSharedPreferences("app", Context.MODE_PRIVATE); + Set askedQuestions = prefs.getStringSet("askedQuestions", new HashSet<>()); + + List unaskedQuestions = new ArrayList<>(); + for (Question question : questions.getQuestions()) { + if (!askedQuestions.contains(String.valueOf(question.getId()))) { + unaskedQuestions.add(question); + } + } + + if (unaskedQuestions.isEmpty()) { + return null; + } + + Random random = new Random(); + Question question = unaskedQuestions.get(random.nextInt(unaskedQuestions.size())); + askedQuestions.add(String.valueOf(question.getId())); + + // Sauvegarder les questions posées + SharedPreferences.Editor editor = prefs.edit(); + editor.putStringSet("askedQuestions", askedQuestions); + editor.apply(); + + // Traiter la question + processQuestion(question); + + return question; + } + + /** + * Traite une question (remplace les variables, etc.) + */ + private void processQuestion(Question question) { + Random random = new Random(); + String questionText = question.getQuestion(); + + // Remplacer les variantes + if (question.getVariante() != null && !question.getVariante().isEmpty()) { + String chosenVariante = question.getVariante().get(random.nextInt(question.getVariante().size())); + questionText = questionText.replace("", chosenVariante); + } + + // Gérer les manches + if (questionText.contains("")) { + int nbaleatoiremanches = random.nextInt(10) + 5; + questionText = questionText.replace("", String.valueOf(nbaleatoiremanches)); + question.setManchesRestantes(nbaleatoiremanches); + + String stopid = getArretById(question.getId()); + question.setArretMessageManche("Fin de défi!\n" + stopid); + questionsAvecManches.add(question); + } + + // Remplacer les joueurs + boolean isJoueurs1 = questionText.contains(""); + boolean isJoueurs2 = questionText.contains(""); + boolean isJoueurs3 = questionText.contains(""); + + if (isJoueurs1 || isJoueurs2 || isJoueurs3) { + List aleatoirejoueurs = TroisJoueurAleatoire(toutlesjoueurs); + + if (isJoueurs1 && isJoueurs2 && isJoueurs3 && aleatoirejoueurs.size() >= 3) { + questionText = questionText.replace("", aleatoirejoueurs.get(0)); + questionText = questionText.replace("", aleatoirejoueurs.get(1)); + questionText = questionText.replace("", aleatoirejoueurs.get(2)); + } else if (isJoueurs1 && isJoueurs2 && aleatoirejoueurs.size() >= 2) { + questionText = questionText.replace("", aleatoirejoueurs.get(0)); + questionText = questionText.replace("", aleatoirejoueurs.get(1)); + } else if (isJoueurs1 && aleatoirejoueurs.size() >= 1) { + questionText = questionText.replace("", aleatoirejoueurs.get(0)); + } + } + + // Ajouter les gorgées + if (question.isDistribution() || question.isRecois()) { + if (question.isRecois() && question.isDistribution()) { + boolean rand = random.nextBoolean(); + if (rand) { + questionText = questionText.concat(" bois"); + } else { + questionText = questionText.concat(" distribue"); + } + } else if (question.isRecois()) { + questionText = questionText.concat(" bois"); + } else if (question.isDistribution()) { + questionText = questionText.concat(" distribue"); + } + + questionText = questionText.concat(" " + (question.getGorger() + ajoutGorgees) + " gorgée" + + ((question.getGorger() + ajoutGorgees) > 1 ? "s" : "") + "."); + } + + question.setQuestion(questionText); + } + + /** + * Méthode publique pour le bouton suivant (compatibilité avec XML) + */ + public void OnClickButton1(View view) { + BoideloAnimationUtils.triggerHapticFeedback(this); + updateQuestion(); + } + + /** + * Méthode publique pour le bouton passer + */ + public void onSkipClick(View view) { + BoideloAnimationUtils.triggerHapticFeedback(this); + skipQuestion(); + } + + /** + * Navigue vers l'activité JeuxParametres en cas d'échec API + */ + public void navigateToJeuxParametres() { + Intent intent = new Intent(Jeux.this, JeuxParametres.class); + Toast.makeText(getApplicationContext(), "Échec de la communication avec l'API !", Toast.LENGTH_SHORT).show(); + startActivity(intent); + finish(); + } + + /** + * Sauvegarde l'état du jeu avant la rotation + */ + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt(KEY_TOTAL_QUESTIONS, totalQuestionsAsked); + outState.putString(KEY_CURRENT_QUESTION_TEXT, questionTextView.getText().toString()); + outState.putBoolean(KEY_IS_MANCHE_ACTIVE, isMancheActive); + + // Sauvegarder l'état des manches actives + ArrayList mancheIds = new ArrayList<>(); + ArrayList mancheCounts = new ArrayList<>(); + for (Question q : questionsAvecManches) { + mancheIds.add(q.getId()); + mancheCounts.add(q.getManchesRestantes()); + } + outState.putIntegerArrayList("manche_ids", mancheIds); + outState.putIntegerArrayList("manche_counts", mancheCounts); + } + + /** + * Restaure l'état du jeu après rotation + */ + private void restoreGameState(Bundle savedInstanceState) { + totalQuestionsAsked = savedInstanceState.getInt(KEY_TOTAL_QUESTIONS, 0); + currentQuestionText = savedInstanceState.getString(KEY_CURRENT_QUESTION_TEXT, ""); + isMancheActive = savedInstanceState.getBoolean(KEY_IS_MANCHE_ACTIVE, false); + + // Restaurer la progression + progressBar.setProgress(totalQuestionsAsked); + updateProgressText(); + + // Restaurer le texte de la question + if (!currentQuestionText.isEmpty()) { + questionTextView.setText(Html.fromHtml(currentQuestionText, Html.FROM_HTML_MODE_LEGACY)); + } + + // Restaurer les manches actives + ArrayList mancheIds = savedInstanceState.getIntegerArrayList("manche_ids"); + ArrayList mancheCounts = savedInstanceState.getIntegerArrayList("manche_counts"); + if (mancheIds != null && mancheCounts != null) { + questionsAvecManches.clear(); + for (int i = 0; i < mancheIds.size(); i++) { + Question q = findQuestionById(mancheIds.get(i)); + if (q != null) { + q.setManchesRestantes(mancheCounts.get(i)); + questionsAvecManches.add(q); + } + } + } + } + + /** + * Trouve une question par son ID + */ + private Question findQuestionById(int id) { + if (questions == null) return null; + for (Question q : questions.getQuestions()) { + if (q.getId() == id) { + // Créer une copie pour éviter de modifier l'original + Question copy = new Question(); + copy.setId(q.getId()); + copy.setQuestion(q.getQuestion()); + copy.setArret(q.getArret()); + copy.setVariante(q.getVariante()); + copy.setDistribution(q.isDistribution()); + copy.setRecois(q.isRecois()); + copy.setGorger(q.getGorger()); + copy.setManchesRestantes(q.getManchesRestantes()); + return copy; + } + } + return null; + } +} diff --git a/app/src/main/java/com/example/boidelov3/JeuxParametres.java b/app/src/main/java/com/example/boidelov3/JeuxParametres.java new file mode 100644 index 0000000..45b51d4 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/JeuxParametres.java @@ -0,0 +1,333 @@ +package com.example.boidelov3; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.Button; +import android.widget.CompoundButton; + +import com.google.android.material.switchmaterial.SwitchMaterial; +import android.widget.EditText; +import android.widget.SeekBar; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class JeuxParametres extends AppCompatActivity { + + private SeekBar seekBar1, seekBar2, seekBar3; + private TextView textView1, textView2, textView5, textViewRatioGen; + private SwitchMaterial checkBoxGPT; + private EditText editText, editTextKeyGPT; + private String keyGPT; + private int nbQuestions; + + private List toutlesjoueurs; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR"); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_jeux_parametres); + + // Initialisation des vues + seekBar1 = findViewById(R.id.seekBar1); + seekBar2 = findViewById(R.id.seekBar2); + seekBar3 = findViewById(R.id.seekBar3); + textView1 = findViewById(R.id.textView1); + textView2 = findViewById(R.id.textView2); + textView5 = findViewById(R.id.textView5); + editTextKeyGPT = findViewById(R.id.editTextGPT); + textViewRatioGen = findViewById(R.id.textViewRatioGen); + + // Initialiser les TextView avec les valeurs par défaut + int initialQuestions = 50; + int initialGorgees = 0; + int initialRatio = 8; + + textView1.setText("Nombre de questions avant la fin de partie : " + initialQuestions); + textView2.setText("Ajout de gorgées : " + initialGorgees); + textView5.setText("Palier : Grosse merde"); + textViewRatioGen.setText("Ratio BDD/OPENAI : 1/" + initialRatio); + + Button buttonTestApi = findViewById(R.id.ButtonTestApi); + + // Configuration de la seekBar1 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + seekBar1.setMin(20); + } + seekBar1.setMax(150); + seekBar1.setProgress(50); + + // Configuration de la seekBar2 + seekBar2.setMax(20); + seekBar2.setProgress(0); + + // Configuration de la seekBar3 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + seekBar2.setMin(0); + seekBar3.setMin(1); + } + seekBar3.setMax(15); + seekBar3.setProgress(8); + + // Configuration des listeners pour les seekBars + seekBar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + // Ajustement de la valeur au multiple de 10 le plus proche + int adjustedProgress = Math.round(progress / 10) * 10; + seekBar.setProgress(adjustedProgress); + textView1.setText("Nombre de questions avant la fin de partie : " + adjustedProgress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + + seekBar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + // Mise à jour du textView2 en fonction de la valeur de la seekBar2 + textView2.setText("Ajout de gorgées : " + progress); + // Mise à jour du textView5 en fonction de la valeur de la seekBar2 + switch (progress) { + case 0: + textView5.setText("Palier : Grosse merde"); + break; + case 2: + textView5.setText("Palier : Petite merde"); + break; + case 4: + textView5.setText("Palier : Petit joueur"); + break; + case 6: + textView5.setText("Palier : Un p'tit verre ?!"); + break; + case 8: + textView5.setText("Palier : ça commence à aller"); + break; + case 10: + textView5.setText("Palier : Alcoolique"); + break; + case 12: + textView5.setText("Palier : COMA ETHYLIX"); + break; + case 13: + textView5.setText("Palier : APÉROOOOO !!"); + break; + case 14: + textView5.setText("Palier : LA J'SUIS BIENG"); + break; + case 15: + textView5.setText("Palier : J'VOIS PLUS RIENG"); + break; + case 17: + textView5.setText("Palier : J'AI PLUS DE VERRES"); + break; + case 18 : + textView5.setText("Palier : Soirée Murge"); + break; + case 19: + textView5.setText("Palier : Soirée Pétée"); + break; + case 20: + textView5.setText("Palier : L'ENDER DRAGON"); + break; + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + + // Configuration du checkBox // Q : IL sert a quoi ? + // R : Il sert à activer/désactiver les vues en dessous + + checkBoxGPT = findViewById(R.id.checkBoxGPT); + checkBoxGPT.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + // Activation/désactivation des vues en fonction de l'état du checkBox + editTextKeyGPT.setEnabled(isChecked); + //editText.setEnabled(isChecked); + textViewRatioGen.setEnabled(isChecked); + seekBar3.setEnabled(isChecked); + buttonTestApi.setEnabled(isChecked); + } + }); + + // Configuration de la seekBar3 + seekBar3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar3, int progress, boolean fromUser) { + textViewRatioGen.setText("Ratio BDD/OPENAI : 1/" + progress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar3) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar3) { + } + }); + + // Partie OpenAI : enregistrement de la clé en dur. + // Récupérer une instance des SharedPreferences + SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE); + final SharedPreferences.Editor editor = sharedPreferences.edit(); + // Récupérer l'EditText + final EditText editText = findViewById(R.id.editTextGPT); + // Récupérer la valeur enregistrée dans les SharedPreferences + String apiKey = editText.getText().toString(); + + // Récupérer la valeur enregistrée dans les SharedPreferences + String savedText = sharedPreferences.getString("savedText", ""); + editText.setText(savedText); + + // Enregistrer le contenu de l'EditText lorsque l'utilisateur modifie le texte + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + + @Override + public void afterTextChanged(Editable s) { + // Enregistrer le texte dans les SharedPreferences + editor.putString("savedText", editText.getText().toString()); + editor.apply(); + } + }); + } + + public void onClickButtonTestAPI(View view) { + + String apiKey = editTextKeyGPT.getText().toString(); + // Créer un client OkHttpClient pour effectuer la requête + OkHttpClient client = new OkHttpClient(); + + // Construire la requête d'essai vers l'API + Request request = new Request.Builder() + .url("https://api.openai.com/v1/engines/davinci") // Endpoint d'essai, vous pouvez le modifier selon vos besoins + .header("Authorization", "Bearer " + apiKey) // Ajouter la clé API dans l'en-tête de la requête + .build(); + + // Exécuter la requête de test + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(@NonNull Call call, IOException e) { + // Gérer les erreurs de requête + e.printStackTrace(); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), "Échec de la communication avec l'API !", Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + // Vérifier le code de réponse de la requête + if (response.isSuccessful()) { + // La clé API est valide et l'API a répondu avec succès + // Vous pouvez effectuer d'autres opérations ici + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), "Communication avec l'API réussie !", Toast.LENGTH_SHORT).show(); + } + }); + } else { + // La clé API est invalide ou il y a eu une erreur de communication avec l'API + System.out.println("Échec de la communication avec l'API !"); + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(getApplicationContext(), "Échec de la communication avec l'API !", Toast.LENGTH_SHORT).show(); + } + }); + } + response.close(); + } + }); + } + + public void onClickButtonStart(View view) { + // Récupérer les paramètres de la partie + int nombreQuestions = seekBar1.getProgress(); + int ajoutGorgees = seekBar2.getProgress(); + int ratioBddOpenAI = seekBar3.getProgress(); + boolean openAI = checkBoxGPT.isChecked(); + + toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR"); + // Récupérer les joueurs (vous devrez définir comment vous les récupérez) + SharedPreferences sharedPreferences = getSharedPreferences("Joueurs", Context.MODE_PRIVATE); + ArrayList joueurs = new ArrayList<>(); + + for (int i = 1; i <= 3; i++) { + String joueur = sharedPreferences.getString("J" + i, ""); + if (!joueur.isEmpty()) { + joueurs.add(joueur); + } + } + + // Récupérer les joueurs supplémentaires en utilisant une boucle + int i = 4; + String nomJoueur = sharedPreferences.getString("J" + i, ""); + while (!nomJoueur.isEmpty()) { + joueurs.add(nomJoueur); + i++; + nomJoueur = sharedPreferences.getString("J" + i, ""); + } + + // Créer une instance de la classe Jeux avec les paramètres récupérés + Jeux jeux = new Jeux(); + + // Lancer l'activité Jeux avec les paramètres + Intent intent = new Intent(this, Jeux.class); + intent.putExtra("EXTRA_NOMBRE_QUESTIONS", nombreQuestions); + intent.putExtra("EXTRA_AJOUT_GORGEE", ajoutGorgees); + intent.putExtra("EXTRA_RATIO_OPENAI", ratioBddOpenAI); + intent.putExtra("EXTRA_OPENAI", openAI); + final EditText editText = findViewById(R.id.editTextGPT); + intent.putExtra("EXTRA_KEY_OPENAI",editText.getText().toString() ); + + toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR"); + intent.putStringArrayListExtra("EXTRA_LIST_JOUEUR", (ArrayList) toutlesjoueurs); + startActivity(intent); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/boidelov3/Jeuxold.java b/app/src/main/java/com/example/boidelov3/Jeuxold.java new file mode 100644 index 0000000..3050b05 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/Jeuxold.java @@ -0,0 +1,350 @@ +package com.example.boidelov3; + +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + + +public class Jeuxold extends AppCompatActivity { + private List toutlesjoueurs, phraseGPT; + private int nombreQuestions; + private int ajoutGorgees; + boolean openAI; + int ratiOpenai; + String keyOpenai, phraseGPTString; + + + public Jeuxold() { + //System.out.println("Je suis dans le constructeur jeux"); + } + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_jeux); + //Recuperation des valeurs des activités précédentes + toutlesjoueurs = getIntent().getStringArrayListExtra("EXTRA_LIST_JOUEUR"); + nombreQuestions = getIntent().getIntExtra("EXTRA_NOMBRE_QUESTIONS", 75); + ajoutGorgees = getIntent().getIntExtra("EXTRA_AJOUT_GORGEE", 0); + openAI = getIntent().getBooleanExtra("EXTRA_OPENAI", false); + ratiOpenai = getIntent().getIntExtra("EXTRA_RATIO_OPENAI", 0); + keyOpenai = getIntent().getStringExtra("EXTRA_KEY_OPENAI"); + + + + System.out.println("ACTJeux all player : " + toutlesjoueurs); + System.out.println("ACTJeux nombre de questions : " + nombreQuestions); + System.out.println("ACTJeux ajout de gorgées : " + ajoutGorgees); + System.out.println("ACTJeux openAI : " + openAI); + System.out.println("ACTJeux ratio openAI : " + ratiOpenai); + System.out.println("ACTJeux key openAI : " + keyOpenai); + + + + + + //Parti OpenAI ; keyOpenai ; ratiOpenai, openAI + //new DatabaseConnection().execute(); + +// if(openAI) { +// ChatGPTTask chatGPTTask = new ChatGPTTask( this, keyOpenai); +// chatGPTTask.execute(); +// +// } + + //Phrase avec nom ou pas? +/* if(JoueurOuPas()){ + PhraseAvecNom(toutlesjoueurs); + }else{ + PhraseSansNom(); + } + }*/ + } + + + public void handleExtractedMessage(String phraseGPTString) { + // Traitez la réponse extraite ici + System.out.println(phraseGPTString); + // Par exemple, affichez-la dans une TextView ou effectuez une action en fonction de la réponse +} + + public void navigateToJeuxParametres() { + Intent intent = new Intent(Jeuxold.this, JeuxParametres.class); + Toast.makeText(getApplicationContext(), "Échec de la communication avec l'API !", Toast.LENGTH_SHORT).show(); + startActivity(intent); + } + + /*public void PhraseAvecNom(List toutlesjoueurs){ + //System.out.println("Je suis dans phrase avec pseudo"); + List phraseAvecNom = new ArrayList(); + List aleatoirejoueurs = TroisJoueurAleatoire(toutlesjoueurs); + phraseAvecNom.add(ChoixJoueurAleatoire(toutlesjoueurs) + " dois boire " + Gorgeesaleatoire(2, 4)+ " Gorgées"); + phraseAvecNom.add(ChoixJoueurAleatoire((toutlesjoueurs))+ " est le vieux briscard ! Interdiction de montrer tes dents pendant 5 manches"); + phraseAvecNom.add(aleatoirejoueurs.get(0) + " et "+ aleatoirejoueurs.get(1) +" liser le premier SMS qui s'affiche quand on tape désolé dans la barre de recherche. Refusez pour 5 gorgées"); + phraseAvecNom.add( "A tour de role, vous avez exactement 3 secondes pour donner un mot en rapport avec le mots dit precedemment. Le joueur qui perd boit "+ Gorgeesaleatoire(2, 4) + " Gorgées! "+ aleatoirejoueurs.get(2)+" tu commences en choissisant un mot."); + phraseAvecNom.add(aleatoirejoueurs.get(0)+ " defie "+ aleatoirejoueurs.get(1) + " au chifoumi ! Le joueur qui gagne distribue 5 Gorgées"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+ " a toi de juger : entre "+aleatoirejoueurs.get(1)+ " et "+ aleatoirejoueurs.get(2) + " qui stresse le plus pour un rien selon toi? Cette personne se detendra en buvant " + Gorgeesaleatoire(3, 5 ) + " Gorgées"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" est dans le futur ! Tu dois parler au futur pendant 4 tours Une gorgées a chaque manque."); + phraseAvecNom.add("Les joueurs de Counter Strike peuvent distribuer" + GorgeesaleatoireAmeliorer(1, 4)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" tu bois autant de gorgées que tu as d'années d'études après le BAC"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+aleatoirejoueurs.get(1)+" ferment leurs yeux ! Ils/Elles doivent deviner la couleur des yeux de l'autre. Si ils/elles se trompent, c'est "+GorgeesaleatoireAmeliorer(2, 4)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" est manchot ! Il/Elle ne peut plus utiliser ses doigts durant 3 tours . Si il/elle s'en sert, il/elle devra boire autant de gorgées qu'il/elle a utilisé de doigts"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+ aleatoirejoueurs.get(1)+" , si vous êtes ensemble dans la vraie vie, vous pouvez distribuer 2 gorgées , autrement buvez-les"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", donne le nombre d'habitant du Tadjikistant ( à 1 000 000 près) ou boit "+GorgeesaleatoireAmeliorer(2, 4)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" a la tourette ! A chaque fois que tu bois une gorgée, tu dois CRIER une insulte. C'est un stade avancé, ça dure 3 tours"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", donne la couleur préférée de "+aleatoirejoueurs.get(1)+" si tu te trompes, c'est 2 gorgées"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" à l'oeil de serpent pendant 5 tours ! Dès qu'un joueur te regarde dans les yeux, il/elle boit. Si personne ne t'as regardé tu bois"+GorgeesaleatoireAmeliorer(5, 9)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+ aleatoirejoueurs.get(1)+"se mesurent ! Le plus petit peut bois"+GorgeesaleatoireAmeliorer(3, 5)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" doit terminer toutes ses phrases par - C'est clair pendant 7 tours"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" distribue"+GorgeesaleatoireAmeliorer(2,5)+" à la personne que tu trouves la mieux foutue"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" distribue"+GorgeesaleatoireAmeliorer(2,5)+" à qui tu veux."); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+aleatoirejoueurs.get(1)+" se défient au 'je te tiens, tu me tiens', le premier qui rit sera une tapette, et devra boire"+GorgeesaleatoireAmeliorer(4,6)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+aleatoirejoueurs.get(1)+"n'ont plus le droit d'utiliser leur téléphone jusqu'à la fin du jeu ! A chaque manque c'est"+GorgeesaleatoireAmeliorer(1,3)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+aleatoirejoueurs.get(1)+ "racontent une anecdote, celui/celle qui sort la plus banale boit "+GorgeesaleatoireAmeliorer(3, 6)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", pour"+GorgeesaleatoireAmeliorer(2,4)+", a qui est ce slogan? Y a pas plus fort. (Vigor)"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", Vrai ou faux? L'eau est bleu car elle reflète le ciel? (Non) Si tu as repondu faux tu devras boire : "+GorgeesaleatoireAmeliorer(2,4)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", Si on te dit Marco? ... Si tu as dis Polo tu bois "+GorgeesaleatoireAmeliorer(1,3)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", Boire un café fait baisser le taux d'alcool? "+GorgeesaleatoireAmeliorer(5, 8)+"en jeu (FAUX)"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" est l'aigris pendant 5tours ! Dès que tu souris ou rigoles, tu bois "+GorgeesaleatoireAmeliorer(2,3)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" fait un geste, le suivant répète et en ajoute un. Le perdant boit"+GorgeesaleatoireAmeliorer(3,5)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", "+aleatoirejoueurs.get(2)+" et "+aleatoirejoueurs.get(1)+" vont désigner quelqu'un qui doit terminer son verre "); + phraseAvecNom.add("Récitez l'alphabet en énonçant une lettre à tour de rôle. Si "+aleatoirejoueurs.get(0)+" finit son verre avant, cul sec pour tout le monde !"); + phraseAvecNom.add("Si"+aleatoirejoueurs.get(0)+" arrive a finir son verre en moins de 5 secondes, il/elle peut distribuer"+ GorgeesaleatoireAmeliorer(5, 8)); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" et "+ aleatoirejoueurs.get(1)+"sont lies, si l'un boit alors l'autre aussi, et ce pendant 5 tours"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+", "+aleatoirejoueurs.get(2)+" et "+ aleatoirejoueurs.get(1)+"sont lies, si l'un boit alors les autres aussi, et ce pendant 5 tours"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" dit un mot, la personne suivante le répète et en ajoute un nouveau, ainsi de suite jusqu'a ce que quelqu'un se trompe. Le perdant boit autant de gorgées qu'il y a eu de personne avant lui"); + phraseAvecNom.add(aleatoirejoueurs.get(0)+" doit choisir un mot que tout le monde devra dire à chaque fois qu'une personne boit."); + //phraseAvecNom.add(aleatoirejoueurs.get(0)+""); + //phraseAvecNom.add(aleatoirejoueurs.get(0)+""); + //phraseAvecNom.add(aleatoirejoueurs.get(0)+""); + //Affichage : + TextView textView1 = (TextView) findViewById(R.id.textView1); + textView1.setText(Nbaleatoirelist(phraseAvecNom)); + } + public void PhraseSansNom(){ + //System.out.println("Je suis dans phrase sans pseudo"); + List phraseSansNom = new ArrayList(); + //Ajout de defis + phraseSansNom.add("Tout le monde boit "+ Gorgeesaleatoire(1, 2)+" gorgée(s)"); + phraseSansNom.add("Quand l'heure affichera un multiple de 10 (22h, 22h10 ...) le premier a crier \"merde j'ai oublié mon chat\" distribura " + Gorgeesaleatoire(10, 12)+ " Gorgées"); + phraseSansNom.add("Ceux qui ont dansé aujourd'hui boivent 4 gorgées"); + phraseSansNom.add("Bois "+ Gorgeesaleatoire(2, 6)+ " Gorgées si tu n'as pas ton veritable nom sur insta"); + phraseSansNom.add("Bois "+ Gorgeesaleatoire(2, 3)+ " Gorgées si tu a des photos sur insta."); + phraseSansNom.add("Plutôt ne plus avoir de mains ou de jambes? les perdants boivent "+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celles/Ceux qui ont habité dans plus de 3 villes boivent "+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Vive la poésie ! Nos phrases doivent rimer sous peine d'une gorgée"); + phraseSansNom.add("Elisez le joueur le moins drôle d'entre vous, ce dernier boit" + GorgeesaleatoireAmeliorer(1,4 )); + phraseSansNom.add("Elisez le joueur le plus drôle d'entre vous, ce dernier distribue" + GorgeesaleatoireAmeliorer(1,4 )); + phraseSansNom.add("La dernière personne à avoir vomi en soirée distribue" + GorgeesaleatoireAmeliorer(2,4)); + phraseSansNom.add("Les filles peuvent distribuer"+ GorgeesaleatoireAmeliorer(1, 2)); + phraseSansNom.add("Les garçons peuvent distribuer"+ GorgeesaleatoireAmeliorer(1, 2)); + phraseSansNom.add("Toutes celles (ou ceux) qui ont du verni à ongles boivent"+GorgeesaleatoireAmeliorer(1,2)); + phraseSansNom.add("Tous les joueurs célibataires boivent"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Tous ceux qui ont des lunettes boivent"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Le premier joueur qui arrive à mettre son doigt dans le nez d'un autre joueur peut distribuer"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Tous ceux qui ont déjà triché à un examen boivent "+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Plutôt avoir un tapis volant, ou un frigo qui se remplit tout seul ? Votez tous en même temps. La minorité boit "+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Les couples trinquer ensemble "+ GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Le/La plus radin(e) boit"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Le mec qui a le plus gros ventre à bière boit"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Tous ceux qui se sont déjà fait exclure de cours boivent"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Tous ceux qui ont des frères et soeurs boivent"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celles et ceux qui ont un Windows phone peuvent distribuer"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celles/Ceux qui se sont déjà battus boivent"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celui/Celle qui pèse le plus lourd boit "+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Pour se décoincer, le/la plus timide boit"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Le/La plus jeune boit"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Plutôt avoir du temps ou de l'argent ? Votez tous en même temps. La minorité boit"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celles/Ceux qui ont fait des études de L boivent"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Le premier joueur qui en embrasse un autre sur la bouche pourra distribuer"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celles et ceux qui joue de la guitare peuvent distribuer"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Celles et ceux qui joue du piano peuvent distribuer"+GorgeesaleatoireAmeliorer(1,4)); + phraseSansNom.add("Les gens qui se sont masturbés aujourd'hui peuvent distribuer"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Celui ou celle a la meilleure place boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Celles et ceux qui n'ont jamais trompé leur partenaire (c'est bien) peuvent distribuer"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Celui/Celle avec les vêtements les plus moches boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Celui/Celle qui a les cheveux les plus longs boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("On doit doser son Alcool les yeux fermés"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Plutôt série ou film ? Votez tous en même temps. La minorité boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Elisez le plus débile d'entre vous, ce dernier boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Le premier qui donne un film de - Christopher Nolan - pourra distribuer"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Le premier qui donne un film avec Christian Clavier pourra boire"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Les végans boivent "+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("La fille la plus maquillé boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Celles/Ceux qui ont déjà appelé leur partenaire par le prénom de leurs ex boivent"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("La première personne qui désigne le plus jeune peut distribuer"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Plutôt avoir des connaissances illimitées ou dirigier le monde ? Votez tous en même temps. La minorité boit"+GorgeesaleatoireAmeliorer(1, 4)); + phraseSansNom.add("Plutôt n'avoir aucun ami ou ne plus pouvoir utiliser d'appareil électronique ? Votez tous en même temps. La minorité boit"+ GorgeesaleatoireAmeliorer(2, 5)); + phraseSansNom.add("Plutot vaincre le patrikaka ou la polution dans le monde? Votez tous en meme temps. La minorité boit"+GorgeesaleatoireAmeliorer(1, 2)); + phraseSansNom.add("Jeu du LUTIN : Jusqu'a la fin du jeu. Vous devez enlever le lutin de votre verre pour pouvoir boire et le remettre ensuite sinon vous devait reboire"); + phraseSansNom.add("Celles et ceux qui boivent de la Vodka peuvent distribuer "+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Les joueurs qui ont un A dans leur prénom boivent "+GorgeesaleatoireAmeliorer(3,5)); + phraseSansNom.add("Les joueurs qui ont un P dans le prénom distribue"+GorgeesaleatoireAmeliorer(1, 3)); + phraseSansNom.add("Le premier joueur à ramener un objet rouge (pas de vêtements) peut distribuer"+GorgeesaleatoireAmeliorer(3,5)); + phraseSansNom.add("Le premier joueur qui dévoile un de ses secrets et que personne autour ne sait peut distribuer"+ GorgeesaleatoireAmeliorer(3, 6)); + phraseSansNom.add("Chaque joueur doit lire à haute voix le dernier SMS qu'il a reçu. Si il/elle refuse, c'est"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Le joueur avec le plus gros cul boit"+ GorgeesaleatoireAmeliorer(2, 6)); + phraseSansNom.add("Celles/Ceux qui ont moins de 20ans boivent"+ GorgeesaleatoireAmeliorer(2, 7)); + phraseSansNom.add("Celui ou celle avec le plus gros appetit sexuel boit"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Ceux/Celles qui fumes boivent "+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Celles et ceux qui ont au moins un BAC +3 peuvent distribuer"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Le premier joueur à se lever peut donner"+ GorgeesaleatoireAmeliorer(6, 7)); + phraseSansNom.add("Celles et ceux qui n'ont jamais fait de strip tease boivent"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Le premier joueur à enlever un vêtements pourra distribuer"+ GorgeesaleatoireAmeliorer(5, 7)); + phraseSansNom.add("Jeu des peaux ! Triez vous du joueur le plus bronzé au joueur le moins bronzé. Le plus bronzé prend 1 gorgée, le second 2 gorgées, etc."); + phraseSansNom.add("Tous ceux qui ont déjà uriné dans une piscine boivent"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Celui/Celle avec le plus d'amis sur Facebook boit"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Celui/Celle avec le nom de famille le plus compliqué boit"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Les joueurs qui n'ont pas encore distribué de gorgées boivent"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Plutôt avoir du pouvoir ou de la connaissance ? Votez tous en même temps. La minorité boit"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("le plus gros dalleux avec les filles boit"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Le premier joueur à donner l'heure pourra distribuer"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Celles et ceux qui ont déjà dépenser plus de 2000 euros en un achat peuvent distribuer"+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Le mec le moins courageux boit "+ GorgeesaleatoireAmeliorer(2, 4)); + phraseSansNom.add("Celles/Ceux qui rentre chez eux à la fin de la soirée boivent"+ GorgeesaleatoireAmeliorer(8, 12)); + phraseSansNom.add("Il est désormais interdit de se tutoyer"); + phraseSansNom.add("Toutes les règles existantes sont annulées"); + phraseSansNom.add("Celles et ceux dont le jour d'anniversaire est un nombre impair boivent"+ GorgeesaleatoireAmeliorer(2, 4)); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add(""); + //phraseSansNom.add("");*/ + + + // + + //Affichage : + TextView textView1 = (TextView) findViewById(R.id.textView1); + //textView1.setText(Nbaleatoirelist(phraseSansNom)); + //} + + public int Gorgeesaleatoire(int Min, int Max){ + int offset = ajoutGorgees; + int nbgorgées; + Random rand = new Random(); + if (Min == 1 && Max == 2){ + nbgorgées = rand.nextInt(Max + Min); + }else { + nbgorgées = Min+rand.nextInt(Max - Min); + } + if(nbgorgées == 0){ + nbgorgées = 1; + } + nbgorgées = nbgorgées + offset; + return nbgorgées; + } + public String GorgeesaleatoireAmeliorer(int Min, int Max){ + int offset = ajoutGorgees; + int nbgorgées; + Random rand = new Random(); + if (Min == 1 && Max == 2){ + nbgorgées = rand.nextInt(Max + Min); + }else { + nbgorgées = Min+rand.nextInt(Max - Min); + } + if(nbgorgées == 0){ + nbgorgées = 1; + } + nbgorgées = nbgorgées + offset; + String debut; + + String nbgorgéesstr; + String nbgorgéesstr1; + debut = " "; + nbgorgéesstr1 = " Gorgée(s)"; + nbgorgéesstr = debut + Integer.toString(nbgorgées) + nbgorgéesstr1; + return nbgorgéesstr; + } + + public String Nbaleatoirelist(List list){ + Random rand = new Random(); + String phrase = (String) list.get(rand.nextInt(list.size())); + return phrase; + } + public int Nbaleatoire(){ + int Max = 100; + int Min = 0; + Random rand = new Random(); + int nbaleatoire = rand.nextInt(Max - Min); + return nbaleatoire; + } + public boolean JoueurOuPas(){ + boolean TrueFalse; + int nbaleatoire = Nbaleatoire(); + int pourcentage = 40; + //System.out.println(nbaleatoire); + if(nbaleatoire >= pourcentage){ + TrueFalse = false;} + else{ + TrueFalse = true; + } + //System.out.println(TrueFalse); + return TrueFalse; + } + public List TroisJoueurAleatoire(List toutlesjoueurs){ + List listJoueur = new ArrayList(); + while (true){ + Random rand = new Random(); + String joueur1 = (String) toutlesjoueurs.get(rand.nextInt(toutlesjoueurs.size())); + String joueur2 = (String) toutlesjoueurs.get(rand.nextInt(toutlesjoueurs.size())); + String joueur3 = (String) toutlesjoueurs.get(rand.nextInt(toutlesjoueurs.size())); + if(joueur1 == joueur2 ){ + }else{ + if (joueur1 == joueur3){ + }else { + if (joueur2 == joueur3) { + }else{ + listJoueur.add(joueur1); + listJoueur.add(joueur2); + listJoueur.add(joueur3); + return listJoueur; + } + + } + } + } + } + + public String ChoixJoueurAleatoire( List toutlesjoueurs){ + //System.out.println(inttoutlesjoueurs); + Random rand = new Random(); + String joueur = (String) toutlesjoueurs.get(rand.nextInt(toutlesjoueurs.size())); + //System.out.println(joueur); + //int nbaleatoire = rand.nextInt(max -min + 1 ) + min; + //int nbaleatoire2 = nbaleatoire - 1; + //if(nbaleatoire2 == -1 ){ + // nbaleatoire2 = 0; + //} + //System.out.println( "nb aleatoire " + nbaleatoire) ; + //joueur = (String) toutlesjoueurs.get(nbaleatoire2); + //System.out.println(joueur); + return joueur ; + + } + public void OnClickButton1(View v){ + finish(); + startActivity(getIntent()); + + } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + // Votre code pour gérer les modifications d'orientation ici + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/boidelov3/MainActivity.java b/app/src/main/java/com/example/boidelov3/MainActivity.java new file mode 100644 index 0000000..6704a97 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/MainActivity.java @@ -0,0 +1,298 @@ +package com.example.boidelov3; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.os.Bundle; +import android.text.Editable; +import android.text.InputType; +import android.text.TextWatcher; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + +import com.google.android.material.textfield.TextInputEditText; + +import java.util.ArrayList; +import java.util.List; + + +public class MainActivity extends AppCompatActivity { + + String J1S, J2S, J3S; + private int offset; + private List toutlesjoueurs; + private TextInputEditText J1; + private TextInputEditText J2; + private TextInputEditText J3; + private List editTextList = new ArrayList<>(); + private List playerRowList = new ArrayList<>(); // Liste des lignes de joueurs pour suppression + private TextView playerCountText; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // Récupérer le TextView du compteur + playerCountText = findViewById(R.id.playerCountText); + + // Initialiser les 3 champs statiques et ajouter les listeners + J1 = findViewById(R.id.J1); + J2 = findViewById(R.id.J2); + J3 = findViewById(R.id.J3); + + // Ajouter un TextWatcher à chaque champ pour mettre à jour le compteur + TextWatcher playerCountWatcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + updatePlayerCount(); + } + + @Override + public void afterTextChanged(Editable s) {} + }; + + if (J1 != null) J1.addTextChangedListener(playerCountWatcher); + if (J2 != null) J2.addTextChangedListener(playerCountWatcher); + if (J3 != null) J3.addTextChangedListener(playerCountWatcher); + + // Mise à jour initiale + updatePlayerCount(); + } + + /** + * Met à jour le compteur de joueurs en temps réel + */ + private void updatePlayerCount() { + int count = 0; + if (J1 != null && J1.getText() != null && !J1.getText().toString().isEmpty()) count++; + if (J2 != null && J2.getText() != null && !J2.getText().toString().isEmpty()) count++; + if (J3 != null && J3.getText() != null && !J3.getText().toString().isEmpty()) count++; + + // Compter les champs dynamiques + for (TextInputEditText edit : editTextList) { + if (edit != null && edit.getText() != null && !edit.getText().toString().isEmpty()) { + count++; + } + } + + if (playerCountText != null) { + playerCountText.setText("Joueurs: " + count + " / min. 3"); + } + } + + public void onClickButton1(View view) { + LinearLayout nameEntryLayout = findViewById(R.id.nameEntryLayout); + + // Créer un conteneur pour la ligne de joueur (EditText + Bouton supprimer) + FrameLayout playerRow = new FrameLayout(this); + LinearLayout.LayoutParams rowParams = new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + rowParams.setMargins(0, 8, 0, 8); + playerRow.setLayoutParams(rowParams); + + // Créer un nouveau TextInputLayout + com.google.android.material.textfield.TextInputLayout textInputLayout = new com.google.android.material.textfield.TextInputLayout(this); + FrameLayout.LayoutParams textInputParams = new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ); + textInputParams.setMargins(0, 0, 60, 0); // Laisser de la place pour le bouton supprimer + textInputLayout.setLayoutParams(textInputParams); + textInputLayout.setBoxBackgroundMode(com.google.android.material.textfield.TextInputLayout.BOX_BACKGROUND_OUTLINE); + textInputLayout.setHint("Nom"); + + // Appliquer les couleurs du thème pour la cohérence + int primaryColor = androidx.core.content.ContextCompat.getColor(this, R.color.primary); + int hintColor = androidx.core.content.ContextCompat.getColor(this, R.color.text_hint); + textInputLayout.setBoxStrokeColor(primaryColor); + textInputLayout.setDefaultHintTextColor(androidx.core.content.ContextCompat.getColorStateList(this, R.color.text_hint)); + + // Créer un nouveau TextInputEditText + TextInputEditText newEditText = new TextInputEditText(this); + newEditText.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + newEditText.setInputType(InputType.TYPE_TEXT_FLAG_CAP_WORDS); + newEditText.setMaxLines(1); + newEditText.setTextSize(16); + newEditText.setTextColor(androidx.core.content.ContextCompat.getColor(this, R.color.text_primary)); + newEditText.setHintTextColor(androidx.core.content.ContextCompat.getColor(this, R.color.text_hint)); + + // Ajouter un TextWatcher pour mettre à jour le compteur en temps réel + newEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + updatePlayerCount(); + } + + @Override + public void afterTextChanged(Editable s) {} + }); + + // Ajouter l'EditText au TextInputLayout + textInputLayout.addView(newEditText); + + // Créer le bouton de suppression + ImageButton deleteButton = new ImageButton(this); + FrameLayout.LayoutParams buttonParams = new FrameLayout.LayoutParams( + (int) (48 * getResources().getDisplayMetrics().density), + (int) (48 * getResources().getDisplayMetrics().density) + ); + buttonParams.setMargins(0, 4, 8, 4); + buttonParams.gravity = android.view.Gravity.END | android.view.Gravity.CENTER_VERTICAL; + deleteButton.setLayoutParams(buttonParams); + deleteButton.setBackgroundResource(android.R.drawable.ic_menu_delete); + int errorColor = androidx.core.content.ContextCompat.getColor(this, R.color.error); + deleteButton.setColorFilter(errorColor); + deleteButton.setScaleType(ImageButton.ScaleType.CENTER_INSIDE); + deleteButton.setContentDescription("Supprimer ce joueur"); + + // Configuration du bouton de suppression avec animation + deleteButton.setOnClickListener(v -> removePlayerRow(playerRow, newEditText)); + + // Ajouter les éléments au conteneur + playerRow.addView(textInputLayout); + playerRow.addView(deleteButton); + + // Ajouter à la liste et au layout avec animation + editTextList.add(newEditText); + playerRowList.add(playerRow); + nameEntryLayout.addView(playerRow); + + // Animation d'apparition + BoideloAnimationUtils.popIn(playerRow, 300); + BoideloAnimationUtils.triggerHapticFeedback(this); + } + + /** + * Supprime une ligne de joueur avec animation + */ + private void removePlayerRow(View playerRow, TextInputEditText editText) { + BoideloAnimationUtils.triggerHapticFeedback(this); + + // Animation de suppression + BoideloAnimationUtils.slideOutToRemove(playerRow, 300, () -> { + // Retirer de la liste et du layout après l'animation + editTextList.remove(editText); + playerRowList.remove(playerRow); + ViewGroup parent = (ViewGroup) playerRow.getParent(); + if (parent != null) { + parent.removeView(playerRow); + } + // Mettre à jour le compteur après suppression + updatePlayerCount(); + }); + } + + + public void onClickButtonStart(View view) { + // Récupérer les 3 premiers champs de saisie + J1 = findViewById(R.id.J1); + if (J1 != null && J1.getText() != null) { + J1S = J1.getText().toString(); + } else { + J1S = ""; + } + + J2 = findViewById(R.id.J2); + if (J2 != null && J2.getText() != null) { + J2S = J2.getText().toString(); + } else { + J2S = ""; + } + + J3 = findViewById(R.id.J3); + if (J3 != null && J3.getText() != null) { + J3S = J3.getText().toString(); + } else { + J3S = ""; + } + + // Creation d'une liste avec tt les j et verif si elle est completé + toutlesjoueurs = new ArrayList<>(); + if (!J1S.isEmpty()) { + toutlesjoueurs.add(J1S); + } + if (!J2S.isEmpty()) { + toutlesjoueurs.add(J2S); + } + if (!J3S.isEmpty()) { + toutlesjoueurs.add(J3S); + } + + // Ajouter les champs dynamiques + int nbnom = editTextList.size(); + for (int i = 0; i < nbnom; i++) { + TextInputEditText editText = editTextList.get(i); + if (editText != null && editText.getText() != null) { + String nom = editText.getText().toString(); + if (!nom.isEmpty()) { + toutlesjoueurs.add(nom); + } + } + } + + openParametres(); + } + + public void openParametres(){ + //enregistrement des joueurs dans les shared preferences Joueurs + SharedPreferences sharedPreferences = getSharedPreferences("Joueurs", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + + editor.putString("J1", J1S != null ? J1S : ""); + editor.putString("J2", J2S != null ? J2S : ""); + editor.putString("J3", J3S != null ? J3S : ""); + + for (int i = 0; i < editTextList.size(); i++) { + TextInputEditText editText = editTextList.get(i); + if (editText != null && editText.getText() != null) { + String nom = editText.getText().toString(); + editor.putString("J" + (i + 4), nom); + } + } + + editor.apply(); + //Lancement de l'activité (Jeux_parametres) + + Intent intent = new Intent(this, JeuxParametres.class); + //Regarde si le pseudo est vide et envoie a l'activité jeux + if (toutlesjoueurs.isEmpty()){ + Context context = getApplicationContext(); + CharSequence text = "Merci de rentrer des joueurs"; + int duration = Toast.LENGTH_SHORT; + + Toast toast = Toast.makeText(context, text, duration); + toast.show(); + } + else { + if (toutlesjoueurs.size() >= 3) { + intent.putStringArrayListExtra("EXTRA_LIST_JOUEUR", (ArrayList) toutlesjoueurs); + intent.putExtra("EXTRA_OFFSET", offset); + startActivity(intent); + } else { + Context context = getApplicationContext(); + CharSequence text = "La partie ne peux pas commencer avec moins de 3 joueurs"; + int duration = Toast.LENGTH_SHORT; + Toast toast = Toast.makeText(context, text, duration); + toast.show(); + + } + } + } +} diff --git a/app/src/main/java/com/example/boidelov3/Question.java b/app/src/main/java/com/example/boidelov3/Question.java new file mode 100644 index 0000000..c21eff7 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/Question.java @@ -0,0 +1,109 @@ +package com.example.boidelov3; + +import java.util.List; + +public class Question { + private int id; + private String question; + private int gorger; + private boolean distribution; + private List variante; + private boolean recois; + private boolean manches; + private String arret; // mise à jour du type de données + private int manchesRestantes; // pour le nombre de manches restantes + private String arretMessage; // pour le message d'arrêt + private String arretMessageManche; // pour le message d'arrêt pour les manches + + // Constructeur par défaut + public Question() { + } + + // Getters et setters pour tous les champs + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getQuestion() { + return question; + } + + public void setQuestion(String question) { + this.question = question; + } + + public int getGorger() { + return gorger; + } + + public void setGorger(int gorger) { + this.gorger = gorger; + } + + public boolean isDistribution() { + return distribution; + } + + public void setDistribution(boolean distribution) { + this.distribution = distribution; + } + + public List getVariante() { + return variante; + } + + public void setVariante(List variante) { + this.variante = variante; + } + + public boolean isRecois() { + return recois; + } + + public void setRecois(boolean recois) { + this.recois = recois; + } + + public boolean isManches() { + return manches; + } + + public void setManches(boolean manches) { + this.manches = manches; + } + + public String getArret() { + return arret; + } + + public void setArret(String arret) { + this.arret = arret; + } + + public int getManchesRestantes() { + return manchesRestantes; + } + + public void setManchesRestantes(int manchesRestantes) { + this.manchesRestantes = manchesRestantes; + } + + public String getArretMessage() { + return arretMessage; + } + + public void setArretMessage(String arretMessage) { + this.arretMessage = arretMessage; + } + public String getArretMessageManche() { + return arretMessageManche; + } + + public void setArretMessageManche(String arretMessageManche) { + this.arretMessageManche = arretMessageManche; + } +} diff --git a/app/src/main/java/com/example/boidelov3/Questions.java b/app/src/main/java/com/example/boidelov3/Questions.java new file mode 100644 index 0000000..363e23f --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/Questions.java @@ -0,0 +1,15 @@ +package com.example.boidelov3; + +import java.util.List; + +public class Questions { + private String version; + private List questions; + + // Getters et setters pour chaque champ + public List getQuestions() { + return questions; + } + + // autres getters et setters... +} diff --git a/app/src/main/java/com/example/boidelov3/SoundManager.java b/app/src/main/java/com/example/boidelov3/SoundManager.java new file mode 100644 index 0000000..0af0928 --- /dev/null +++ b/app/src/main/java/com/example/boidelov3/SoundManager.java @@ -0,0 +1,123 @@ +package com.example.boidelov3; + +import android.content.Context; +import android.media.AudioAttributes; +import android.media.SoundPool; + +/** + * Gestionnaire des effets sonores de l'application + */ +public class SoundManager { + private static SoundManager instance; + private SoundPool soundPool; + private boolean soundEnabled = true; + + // IDs des sons + private int soundClick; + private int soundSuccess; + private int soundError; + private int soundNext; + private int soundManche; + + /** + * Obtient l'instance unique du SoundManager + */ + public static synchronized SoundManager getInstance(Context context) { + if (instance == null) { + instance = new SoundManager(context); + } + return instance; + } + + /** + * Constructeur privé + */ + private SoundManager(Context context) { + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_GAME) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build(); + + soundPool = new SoundPool.Builder() + .setMaxStreams(5) + .setAudioAttributes(audioAttributes) + .build(); + + // Charger les sons (pour l'instant, on utilise des sons système) + // TODO: Ajouter des fichiers audio personnalisés dans res/raw/ + // soundClick = soundPool.load(context, R.raw.click, 1); + // soundSuccess = soundPool.load(context, R.raw.success, 1); + // etc. + } + + /** + * Joue le son de clic + */ + public void playClick() { + if (soundEnabled && soundPool != null) { + // Son de clic par défaut + // Pour l'instant, feedback haptique uniquement + } + } + + /** + * Joue le son de succès + */ + public void playSuccess() { + if (soundEnabled && soundPool != null) { + // Son de succès par défaut + } + } + + /** + * Joue le son d'erreur + */ + public void playError() { + if (soundEnabled && soundPool != null) { + // Son d'erreur par défaut + } + } + + /** + * Joue le son de transition (question suivante) + */ + public void playNext() { + if (soundEnabled && soundPool != null) { + // Son de transition par défaut + } + } + + /** + * Joue le son de manche + */ + public void playManche() { + if (soundEnabled && soundPool != null) { + // Son de manche par défaut + } + } + + /** + * Active ou désactive les sons + */ + public void setSoundEnabled(boolean enabled) { + this.soundEnabled = enabled; + } + + /** + * Retourne l'état des sons + */ + public boolean isSoundEnabled() { + return soundEnabled; + } + + /** + * Libère les ressources + */ + public void release() { + if (soundPool != null) { + soundPool.release(); + soundPool = null; + } + instance = null; + } +} diff --git a/app/src/main/res/anim/button_press.xml b/app/src/main/res/anim/button_press.xml new file mode 100644 index 0000000..9aa5150 --- /dev/null +++ b/app/src/main/res/anim/button_press.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/anim/button_release.xml b/app/src/main/res/anim/button_release.xml new file mode 100644 index 0000000..61f142e --- /dev/null +++ b/app/src/main/res/anim/button_release.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/anim/color_transition.xml b/app/src/main/res/anim/color_transition.xml new file mode 100644 index 0000000..3b33fbf --- /dev/null +++ b/app/src/main/res/anim/color_transition.xml @@ -0,0 +1,8 @@ + + + + diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml new file mode 100644 index 0000000..e8590a4 --- /dev/null +++ b/app/src/main/res/anim/fade_in.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml new file mode 100644 index 0000000..6543476 --- /dev/null +++ b/app/src/main/res/anim/fade_out.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/main/res/anim/slide_down.xml b/app/src/main/res/anim/slide_down.xml new file mode 100644 index 0000000..d37900c --- /dev/null +++ b/app/src/main/res/anim/slide_down.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..b712961 --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..6a314c6 --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..3a01ede --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..204ece8 --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/anim/slide_up.xml b/app/src/main/res/anim/slide_up.xml new file mode 100644 index 0000000..4bbf3bd --- /dev/null +++ b/app/src/main/res/anim/slide_up.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_button_primary.xml b/app/src/main/res/drawable/bg_button_primary.xml new file mode 100644 index 0000000..980a2c6 --- /dev/null +++ b/app/src/main/res/drawable/bg_button_primary.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_button_secondary.xml b/app/src/main/res/drawable/bg_button_secondary.xml new file mode 100644 index 0000000..a871e40 --- /dev/null +++ b/app/src/main/res/drawable/bg_button_secondary.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/bg_card.xml b/app/src/main/res/drawable/bg_card.xml new file mode 100644 index 0000000..fd9bf78 --- /dev/null +++ b/app/src/main/res/drawable/bg_card.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_manche.xml b/app/src/main/res/drawable/ic_manche.xml new file mode 100644 index 0000000..bff0f59 --- /dev/null +++ b/app/src/main/res/drawable/ic_manche.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_player_one.xml b/app/src/main/res/drawable/ic_player_one.xml new file mode 100644 index 0000000..9658d39 --- /dev/null +++ b/app/src/main/res/drawable/ic_player_one.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_player_three.xml b/app/src/main/res/drawable/ic_player_three.xml new file mode 100644 index 0000000..12526ee --- /dev/null +++ b/app/src/main/res/drawable/ic_player_three.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_player_two.xml b/app/src/main/res/drawable/ic_player_two.xml new file mode 100644 index 0000000..cccfd36 --- /dev/null +++ b/app/src/main/res/drawable/ic_player_two.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/layout/activity_end_game.xml b/app/src/main/res/layout/activity_end_game.xml new file mode 100644 index 0000000..d31616a --- /dev/null +++ b/app/src/main/res/layout/activity_end_game.xml @@ -0,0 +1,299 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_jeux.xml b/app/src/main/res/layout/activity_jeux.xml new file mode 100644 index 0000000..2991b13 --- /dev/null +++ b/app/src/main/res/layout/activity_jeux.xml @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_jeux_parametres.xml b/app/src/main/res/layout/activity_jeux_parametres.xml new file mode 100644 index 0000000..60b59cf --- /dev/null +++ b/app/src/main/res/layout/activity_jeux_parametres.xml @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..913b625 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216bfb Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml new file mode 100644 index 0000000..33456d8 --- /dev/null +++ b/app/src/main/res/values-night/colors.xml @@ -0,0 +1,50 @@ + + + + + + #1E1E1E + #2D2D2D + #3A3A3A + #2D2D2D + + + #FFFFFF + #E0E0E0 + #9E9E9E + + + #B388FF + #7C4DFF + #D1C4E9 + + + #2D2D2D + #1E1E1E + #2D2D2D + #372E45 + #413E5A + #4B4E6F + #2E3E5A + #5A4E2E + #5A3E2E + + + #81C784 + #EF5350 + #FFB74D + + + #FFFFFF + #000000 + #B388FF + #E0E0E0 + #4A3A69 + #EDE7F6 + #404040 + #404040 + #FFFFFF + #FFFFFF + #80000000 + #80FFFFFF + diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..d6f6cd7 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..4336f1b --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,50 @@ + + + + + + #FFFFFF + #FFFFFF + #F0F0F0 + #FFFFFF + + + #000000 + #333333 + #999999 + + + #7C4DFF + #6200EA + #B388FF + + + #FFFFFF + #FFFFFF + #FFFFFF + #F3E5F5 + #E1BEE7 + #CE93D8 + #E8EAF6 + #FFF59D + #FFCCBC + + + #4CAF50 + #F44336 + #FF9800 + + + #FFFFFF + #000000 + #7C4DFF + #333333 + #EDE7F6 + #1A0033 + #E0E0E0 + #E0E0E0 + #000000 + #FFFFFF + #80000000 + #80FFFFFF + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..71107e2 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,24 @@ + + Boidelo + J10 + Pseudo + Nom + c ki + komment il s\'appel + who + Joueur + Prenom + Ajouter une nouvelle personne + Pour commencer le jeu, il suffit d\'abord de rentrer le noms des joueurs + Joueur : + Bienvenue sur Boidelo + Eclatax (+4 Gorgées) + Habitués (+2 Gorgées) + "Suivant !" + Paramètres du jeu + Commencer a vous mettre une mine ! + Activer les questions par ChatGPT + Clé API OpenAI + OpenAI [En cours de développement] + Test de Connectivité Openai + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..f78bdfd --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..1cfe5f0 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..fa0f996 --- /dev/null +++ b/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/color_transition.xml b/app/src/main/res/xml/color_transition.xml new file mode 100644 index 0000000..e5462a4 --- /dev/null +++ b/app/src/main/res/xml/color_transition.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..9ee9997 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..73312f9 --- /dev/null +++ b/build.gradle @@ -0,0 +1,5 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { +id 'com.android.application' version '8.12.0' apply false +} + diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..3e927b1 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..73cfbb4 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Dec 31 00:34:52 CET 2025 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..bad886e --- /dev/null +++ b/settings.gradle @@ -0,0 +1,17 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "BoideloV3" +include ':app'