diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7db48ea..0d2e14c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -82,22 +82,9 @@ android:exported="false" android:screenOrientation="portrait" /> - - - + - - - - diff --git a/app/src/main/assets/questionOLD.json b/app/src/main/assets/questionOLD.json deleted file mode 100644 index 0cb1b00..0000000 --- a/app/src/main/assets/questionOLD.json +++ /dev/null @@ -1,809 +0,0 @@ -{ - "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/ChatGPTTask.java b/app/src/main/java/com/example/boidelov3/ChatGPTTask.java deleted file mode 100644 index e71b9d5..0000000 --- a/app/src/main/java/com/example/boidelov3/ChatGPTTask.java +++ /dev/null @@ -1,85 +0,0 @@ -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/Jeux.java b/app/src/main/java/com/example/boidelov3/Jeux.java deleted file mode 100644 index 767f212..0000000 --- a/app/src/main/java/com/example/boidelov3/Jeux.java +++ /dev/null @@ -1,1257 +0,0 @@ -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.util.Log; -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.example.boidelov3.data.PlayerStats; -import com.example.boidelov3.data.QuestionCategory; -import com.example.boidelov3.utils.SoundManager; -import com.example.boidelov3.utils.ErrorHandler; -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.Collections; -import java.util.HashMap; -import java.util.Map; -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; - private View rootLayout; // Layout racine pour la couleur de fond - - // Données - private Questions questions; - private List toutlesjoueurs; - private List questionsAvecManches = new ArrayList<>(); - private Map playerStatsMap; // Statistiques des joueurs - private SoundManager soundManager; // Gestionnaire de sons - private OpenAIService openAIService; // Service OpenAI - private OpenAIService.AIProvider aiProvider = OpenAIService.AIProvider.OPENAI; // Provider IA - private List generatedAIQuestions; // Questions générées par l'IA - - // Générateur aléatoire unique pour toute l'activité - private final Random random = new Random(); - - // Paramètres de partie - private int nombreQuestions; - private int ajoutGorgees; - private boolean openAI; - private int ratiOpenai; - private String keyOpenai; - private int durationDefis; // Offset pour la durée des défis - - // État du jeu - private int currentQuestionIndex = 0; - private int totalQuestionsAsked = 0; - private String currentQuestionText = ""; - private boolean isMancheActive = false; - private boolean isFinishingGame = false; // Flag pour empêcher les appels multiples pendant la fin du jeu - private int questionsSinceLastAI = 0; // Compteur pour le ratio IA - - // Constantes pour les nombres magiques - private static final int MIN_DEFI_ROUNDS = 4; // Minimum 4 manches pour les défis - private static final int MAX_DEFI_ROUNDS_RANDOM = 6; // Max 6 tours aléatoires (4-10 tours au total) - private static final int MIN_MANCHES_COUNT = 4; - private static final int PREGENERATED_AI_QUESTIONS = 2; - private static final int MIN_AI_QUESTION_STOCK = 2; - private static final int MIN_AI_GORGEE = 1; // Minimum 1 gorgée - private static final int MAX_AI_GORGEE_ADDITIONAL = 3; - private static final int ANIMATION_DURATION_SHORT_MS = 300; - private static final int BACKGROUND_COLOR_DELAY_MS = 1000; - private static final int END_GAME_DELAY_MS = 3000; - private static final int RANDOM_PLAYER_SELECTION_COUNT = 3; - private static final int TWO_PLAYERS = 2; - private static final int ONE_PLAYER = 1; - - // 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"); - - // Initialiser les statistiques des joueurs - initializePlayerStats(); - - // Initialiser le gestionnaire de sons - soundManager = SoundManager.getInstance(this); - - // Initialiser les services IA si activés - generatedAIQuestions = new ArrayList<>(); - - nombreQuestions = getIntent().getIntExtra("EXTRA_NOMBRE_QUESTIONS", 50); - ajoutGorgees = getIntent().getIntExtra("EXTRA_AJOUT_GORGEE", 0); - ratiOpenai = getIntent().getIntExtra("EXTRA_RATIO_OPENAI", 0); - durationDefis = getIntent().getIntExtra("EXTRA_DURATION_DEFIS", 0); - openAI = getIntent().getBooleanExtra("EXTRA_OPENAI", false); - keyOpenai = getIntent().getStringExtra("EXTRA_KEY_OPENAI"); - - // Récupérer le provider IA - String providerName = getIntent().getStringExtra("EXTRA_AI_PROVIDER"); - if (providerName != null) { - try { - aiProvider = OpenAIService.AIProvider.valueOf(providerName); - } catch (IllegalArgumentException e) { - aiProvider = OpenAIService.AIProvider.OPENAI; - } - } - - if (openAI && keyOpenai != null && !keyOpenai.isEmpty()) { - // Valider la clé API avant de créer le service - if (OpenAIService.validateApiKey(keyOpenai, aiProvider)) { - openAIService = new OpenAIService(keyOpenai, aiProvider); - // Prégénérer quelques questions IA pour avoir un stock au démarrage - for (int i = 0; i < PREGENERATED_AI_QUESTIONS; i++) { - generateAIQuestion(); - } - } else { - // Clé API invalide : désactiver l'IA et afficher un message - Log.w("Jeux", "Clé API invalide, désactivation de la génération IA"); - openAI = false; - Toast.makeText(this, "Clé API invalide. Vérifiez votre configuration.", Toast.LENGTH_LONG).show(); - } - } - - // 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 { - // Réinitialiser le flag de fin de jeu - isFinishingGame = false; - // 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); - rootLayout = findViewById(R.id.rootLayout); - - // Appliquer les animations aux boutons - BoideloAnimationUtils.applyButtonPressAnimation(suivantButton); - BoideloAnimationUtils.applyButtonPressAnimation(skipButton); - - // Cacher le bouton Passé au début (uniquement visible pendant les défis) - skipButton.setVisibility(View.GONE); - } - - /** - * Charge les questions depuis le fichier JSON - */ - private void loadQuestions() { - try { - try (InputStream is = getAssets().open("question.json")) { - int size = is.available(); - byte[] buffer = new byte[size]; - is.read(buffer); - String json = new String(buffer, "UTF-8"); - - Gson gson = new Gson(); - questions = gson.fromJson(json, Questions.class); - } - } catch (IOException ex) { - String operation = "Chargement du fichier question.json depuis les assets"; - String details = "Impossible de lire ou de parser le fichier de questions"; - ErrorHandler.showError(this, "Jeux", operation, details + ": " + ex.getMessage(), ex); - } - } - - /** - * Initialise les statistiques des joueurs - */ - private void initializePlayerStats() { - playerStatsMap = new HashMap<>(); - if (toutlesjoueurs != null) { - for (String joueur : toutlesjoueurs) { - playerStatsMap.put(joueur, new PlayerStats(joueur)); - } - } - } - - /** - * 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); - // Plus de son de clic - juste la vibration haptique - 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() { - // Si le jeu est en train de se terminer, ne rien faire - if (isFinishingGame) { - return; - } - - // Vérifier si toutes les questions ont été posées - if (shouldEndGame()) { - handleGameEnd(); - return; - } - - // Gérer les questions avec manches actives - boolean hasMancheActive = processActiveManches(); - - // Afficher une nouvelle question (que ce soit pendant ou hors manche) - displayNewQuestion(hasMancheActive); - } - - /** - * Vérifie si le jeu doit se terminer - */ - private boolean shouldEndGame() { - return totalQuestionsAsked >= nombreQuestions; - } - - /** - * Gère la fin du jeu - */ - private void handleGameEnd() { - // Vérifier s'il y a encore des manches actives - if (!questionsAvecManches.isEmpty()) { - // Afficher le message de fin de manche et terminer - showFinalMancheEndMessage(); - } else { - endGame(); - } - } - - /** - * Traite les manches actives et retourne true si une manche est active - */ - private boolean processActiveManches() { - 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 - } - } - - return hasMancheActive; - } - - /** - * Affiche une nouvelle question - */ - private void displayNewQuestion(boolean hasMancheActive) { - 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, l'indicateur et le bouton Passé - mancheCounterTextView.setVisibility(View.GONE); - questionIndicator.setVisibility(View.GONE); - mancheQuestionText.setVisibility(View.GONE); - skipButton.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); - }, BACKGROUND_COLOR_DELAY_MS); - } - - /** - * Affiche le message de fin de manche finale (quand le jeu se termine) - */ - private void showFinalMancheEndMessage() { - // Marquer le jeu comme en train de se terminer - isFinishingGame = true; - - // 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, l'indicateur et le bouton Passé - mancheCounterTextView.setVisibility(View.GONE); - questionIndicator.setVisibility(View.GONE); - mancheQuestionText.setVisibility(View.GONE); - skipButton.setVisibility(View.GONE); - suivantButton.setEnabled(false); // Désactiver le bouton pendant la fin - - // Terminer après un délai - mancheCounterTextView.postDelayed(() -> { - questionsAvecManches.clear(); - endGame(); - }, END_GAME_DELAY_MS); - } - - /** - * 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, ANIMATION_DURATION_SHORT_MS); - } - - /** - * Affiche une nouvelle question - */ - private void displayQuestion(Question question, boolean hasMancheActive) { - // Afficher le texte de la question - displayQuestionText(question); - - // Masquer ou afficher la question de manche selon l'état - handleMancheQuestionVisibility(hasMancheActive); - - // Détecter et afficher la catégorie de la question - QuestionCategory.Category category = QuestionCategory.detectCategory(question); - applyCategoryStyle(category); - - // Déterminer et afficher l'indicateur de joueurs - String indicatorText = determinePlayerCountIndicator(question, category); - showIndicatorText(indicatorText); - } - - /** - * Affiche le texte de la question - */ - private void displayQuestionText(Question question) { - questionTextView.setText(Html.fromHtml(question.getQuestion(), Html.FROM_HTML_MODE_LEGACY)); - } - - /** - * Gère la visibilité de la question de manche - */ - private void handleMancheQuestionVisibility(boolean hasMancheActive) { - if (!hasMancheActive) { - mancheQuestionText.setVisibility(View.GONE); - } - } - - /** - * Applique le style de catégorie (couleur de fond, etc.) - */ - private void applyCategoryStyle(QuestionCategory.Category category) { - // Réinitialiser les indicateurs - questionIndicator.setVisibility(View.GONE); - mancheCounterTextView.setVisibility(View.GONE); - - // Appliquer la couleur de fond - int categoryColor = QuestionCategory.getColorForCategory(category); - rootLayout.setBackgroundColor(categoryColor); - } - - /** - * Détermine le texte de l'indicateur en fonction du nombre de joueurs et de la catégorie - */ - private String determinePlayerCountIndicator(Question question, QuestionCategory.Category category) { - String questionText = question.getQuestion(); - boolean isJoueurs1 = questionText.contains(""); - boolean isJoueurs2 = questionText.contains(""); - boolean isJoueurs3 = questionText.contains(""); - - String categoryEmoji = getCategoryEmoji(category); - String categoryName = QuestionCategory.getNameForCategory(category); - - // Priorité aux indications de nombre de joueurs si applicable - if (isJoueurs1 && isJoueurs2 && isJoueurs3) { - return "3 joueurs"; - } else if (isJoueurs1 && isJoueurs2) { - return "2 joueurs"; - } else if (isJoueurs1) { - return "1 joueur"; - } else { - // Juste l'emoji et le nom de la catégorie - return categoryEmoji + " " + categoryName; - } - } - - /** - * Affiche l'indicateur avec le texte spécifié - */ - private void showIndicatorText(String textToShow) { - questionIndicator.setVisibility(View.VISIBLE); - indicatorIcon.setVisibility(View.GONE); - indicatorText.setText(textToShow); - } - - /** - * Retourne l'emoji associé à une catégorie - */ - private String getCategoryEmoji(QuestionCategory.Category category) { - switch (category) { - case CIBLAGE: - return "🎯"; - case CLASSEMENT: - return "👑"; - case JUGEMENT: - return "⚖️"; - case DUEL: - return "🤝"; - case INTERACTIF: - return "🎮"; - case DEFI_MANCHES: - return "🔥"; - case VARIANTE: - return "❓"; - case CALIENTE: - return "😈"; - case VOTE: - return "🗳️"; - case CLASSIQUE: - default: - return "⚪"; - } - } - - - /** - * Affiche l'indicateur de type de question - */ - private void showQuestionIndicator(int iconRes, String text) { - indicatorIcon.setImageResource(iconRes); - indicatorIcon.setVisibility(View.VISIBLE); - indicatorText.setText(text); - questionIndicator.setVisibility(View.VISIBLE); - BoideloAnimationUtils.fadeIn(questionIndicator, ANIMATION_DURATION_SHORT_MS); - } - - /** - * Passe la question actuelle ou ignore le défi en cours - */ - private void skipQuestion() { - // Vérifier s'il y a un défi en cours - if (!questionsAvecManches.isEmpty()) { - // Ignorer le défi actuel - Question mancheToRemove = questionsAvecManches.get(0); - questionsAvecManches.clear(); - - // Masquer le compteur, l'indicateur et le bouton Passé - mancheCounterTextView.setVisibility(View.GONE); - questionIndicator.setVisibility(View.GONE); - mancheQuestionText.setVisibility(View.GONE); - skipButton.setVisibility(View.GONE); - - // Afficher un message de confirmation - Toast.makeText(this, "Défi ignoré !", Toast.LENGTH_SHORT).show(); - - // Vibration de confirmation - BoideloAnimationUtils.triggerHapticFeedback(this); - - // Animation de fond - int defaultColor = ContextCompat.getColor(this, R.color.game_normal); - BoideloAnimationUtils.animateBackgroundColor(getWindow().getDecorView(), defaultColor); - } else { - // Sinon, passer simplement la question - totalQuestionsAsked++; - updateProgressBar(); - } - updateQuestion(); - } - - /** - * Termine la partie et affiche l'écran de fin - */ - private void endGame() { - // Jouer le son de fin - if (soundManager != null) soundManager.playFin(); - - // 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); - - // Passer les statistiques des joueurs - ArrayList playerStatsList = new ArrayList<>(playerStatsMap.values()); - intent.putParcelableArrayListExtra("PLAYER_STATS", playerStatsList); - - 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<>(); - - while (setJoueur.size() < RANDOM_PLAYER_SELECTION_COUNT && toutlesjoueurs.size() >= RANDOM_PLAYER_SELECTION_COUNT) { - setJoueur.add(toutlesjoueurs.get(random.nextInt(toutlesjoueurs.size()))); - } - - // Mélanger la liste pour avoir un ordre aléatoire (pas toujours le même) - List result = new ArrayList<>(setJoueur); - Collections.shuffle(result, random); - return result; - } - - /** - * 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; - } - - /** - * Génère une nouvelle question via l'IA OpenAI - */ - private void generateAIQuestion() { - if (openAIService == null) { - return; - } - - openAIService.generateQuestion(toutlesjoueurs, ajoutGorgees, new OpenAIService.OpenAICallback() { - @Override - public void onSuccess(String questionText) { - if (questionText != null && !questionText.isEmpty()) { - // Créer une nouvelle question à partir du texte généré - Question aiQuestion = createAIQuestion(questionText); - if (aiQuestion != null) { - generatedAIQuestions.add(aiQuestion); - // Afficher un petit indicateur que c'est une question IA - Toast.makeText(Jeux.this, "✨ Question IA générée !", Toast.LENGTH_SHORT).show(); - } - } - } - - @Override - public void onError(String errorMessage) { - // En cas d'erreur, on continue avec les questions JSON - // Pas de toast pour ne pas interrompre le jeu - android.util.Log.e("OpenAI", "Erreur génération question: " + errorMessage); - } - }); - } - - /** - * Crée un objet Question à partir du texte généré par l'IA - */ - private Question createAIQuestion(String questionText) { - try { - Question question = new Question(); - question.setId(-1); // ID négatif pour les questions IA - question.setQuestion(questionText); - question.setGorger(MIN_AI_GORGEE + random.nextInt(MAX_AI_GORGEE_ADDITIONAL)); // 2-4 gorgées par défaut - question.setDistribution(random.nextBoolean()); - question.setRecois(!question.isDistribution() || random.nextBoolean()); - - // Détecter si c'est une question de vote - if (questionText.toLowerCase().contains("votez") || - questionText.toLowerCase().contains("minorité") || - questionText.toLowerCase().contains("majorité")) { - question.setDistribution(false); - question.setRecois(true); - } - - return question; - } catch (Exception e) { - android.util.Log.e("OpenAI", "Erreur création question IA: " + e.getMessage()); - return null; - } - } - - /** - * Obtient une question aléatoire qui n'a pas encore été posée - * Intègre les questions générées par l'IA selon le ratio configuré - */ - private Question getRandomQuestion() { - // Incrémenter le compteur de questions depuis la dernière IA - questionsSinceLastAI++; - - // Vérifier si on doit utiliser une question IA - Question aiQuestion = tryGetAIQuestion(); - if (aiQuestion != null) { - return aiQuestion; - } - - // Générer une question IA en arrière-plan si le stock est bas - if (shouldGenerateAIInBackground()) { - generateAIQuestion(); - } - - // Sinon, utiliser une question du JSON - return getJSONQuestion(); - } - - /** - * Tente de récupérer une question IA si les conditions sont remplies - */ - private Question tryGetAIQuestion() { - if (!shouldUseAIQuestion()) { - return null; - } - - if (generatedAIQuestions.isEmpty()) { - return null; - } - - Question aiQuestion = generatedAIQuestions.remove(0); - questionsSinceLastAI = 0; // Réinitialiser le compteur - - // Traiter la question IA - processQuestion(aiQuestion); - - // Générer en arrière-plan la prochaine question IA pour avoir un stock - generateAIQuestion(); - - return aiQuestion; - } - - /** - * Vérifie si on doit utiliser une question IA selon le ratio - */ - private boolean shouldUseAIQuestion() { - return ratiOpenai > 0 && openAIService != null && questionsSinceLastAI >= ratiOpenai; - } - - /** - * Vérifie si on doit générer une question IA en arrière-plan - */ - private boolean shouldGenerateAIInBackground() { - return openAIService != null && generatedAIQuestions.size() < MIN_AI_QUESTION_STOCK; - } - - /** - * Récupère une question depuis le fichier JSON - */ - private Question getJSONQuestion() { - if (questions == null) { - return null; - } - - SharedPreferences prefs = getSharedPreferences("app", Context.MODE_PRIVATE); - Set askedQuestions = prefs.getStringSet("askedQuestions", new HashSet<>()); - - List unaskedQuestions = getUnaskedQuestions(askedQuestions); - - if (unaskedQuestions.isEmpty()) { - return null; - } - - List availableQuestions = filterAvailableQuestions(unaskedQuestions); - - if (availableQuestions.isEmpty()) { - return null; - } - - Question question = selectRandomQuestion(availableQuestions); - markQuestionAsAsked(question, askedQuestions, prefs); - - // Traiter la question - processQuestion(question); - - return question; - } - - /** - * Récupère la liste des questions non posées - */ - private List getUnaskedQuestions(Set askedQuestions) { - List unaskedQuestions = new ArrayList<>(); - for (Question question : questions.getQuestions()) { - if (!askedQuestions.contains(String.valueOf(question.getId()))) { - unaskedQuestions.add(question); - } - } - return unaskedQuestions; - } - - /** - * Filtre les questions disponibles selon qu'un défi est en cours ou non - */ - private List filterAvailableQuestions(List unaskedQuestions) { - List availableQuestions = new ArrayList<>(); - boolean mancheActive = !questionsAvecManches.isEmpty(); - - for (Question question : unaskedQuestions) { - if (mancheActive) { - // Un défi est en cours, exclure les questions avec - if (!question.getQuestion().contains("")) { - availableQuestions.add(question); - } - } else { - // Pas de défi en cours, toutes les questions sont disponibles - availableQuestions.add(question); - } - } - - return availableQuestions; - } - - /** - * Sélectionne une question aléatoire parmi celles disponibles - */ - private Question selectRandomQuestion(List availableQuestions) { - return availableQuestions.get(random.nextInt(availableQuestions.size())); - } - - /** - * Marque une question comme posée et sauvegarde l'état - */ - private void markQuestionAsAsked(Question question, Set askedQuestions, SharedPreferences prefs) { - askedQuestions.add(String.valueOf(question.getId())); - - // Sauvegarder les questions posées - SharedPreferences.Editor editor = prefs.edit(); - editor.putStringSet("askedQuestions", askedQuestions); - editor.apply(); - } - - /** - * Traite une question (remplace les variables, etc.) - */ - private void processQuestion(Question question) { - String questionText = question.getQuestion(); - - // Remplacer les variantes - questionText = processVariantes(question, questionText); - - // Gérer les manches - questionText = processManches(question, questionText); - - // Remplacer les joueurs et récupérer le nom du joueur J1 pour les stats - PlayerSelectionResult playerResult = replacePlayers(questionText); - questionText = playerResult.questionText; - - // Ajouter les gorgées et tracker les stats (en passant le nombre de joueurs pour l'accord) - GorgeeResult gorgeeResult = processGorgees(question, questionText, playerResult.playerCount); - questionText = gorgeeResult.questionText; - - // Mettre à jour les statistiques du joueur J1 - updatePlayerStats(playerResult.j1Name, gorgeeResult); - - question.setQuestion(questionText); - } - - /** - * Remplace les variantes dans la question - */ - private String processVariantes(Question question, String questionText) { - if (question.getVariante() != null && !question.getVariante().isEmpty()) { - String chosenVariante = question.getVariante().get(random.nextInt(question.getVariante().size())); - questionText = questionText.replace("", chosenVariante); - } - return questionText; - } - - /** - * Gère les manches pour les défis - */ - private String processManches(Question question, String questionText) { - if (questionText.contains("")) { - int nbaleatoiremanches = calculateManchesCount(); - questionText = questionText.replace("", String.valueOf(nbaleatoiremanches)); - question.setManchesRestantes(nbaleatoiremanches); - - String stopid = getArretById(question.getId()); - if (stopid == null) stopid = "Le défi est terminé !"; - question.setArretMessageManche("Fin de défi!\n" + stopid); - questionsAvecManches.add(question); - - // Jouer le son de manche - if (soundManager != null) soundManager.playManche(); - - // Afficher le bouton Passé pendant les défis - skipButton.setVisibility(View.VISIBLE); - BoideloAnimationUtils.fadeIn(skipButton, ANIMATION_DURATION_SHORT_MS); - } - return questionText; - } - - /** - * Calcule le nombre de manches pour un défi - */ - private int calculateManchesCount() { - int nbaleatoiremanches = random.nextInt(MAX_DEFI_ROUNDS_RANDOM) + MIN_DEFI_ROUNDS + durationDefis; - // S'assurer qu'il y a au moins 1 manche - return Math.max(nbaleatoiremanches, MIN_MANCHES_COUNT); - } - - /** - * Résultat du remplacement des joueurs - */ - private static class PlayerSelectionResult { - String questionText; - String j1Name; - int playerCount; // Nombre de joueurs sélectionnés pour l'accord du verbe - - PlayerSelectionResult(String questionText, String j1Name, int playerCount) { - this.questionText = questionText; - this.j1Name = j1Name; - this.playerCount = playerCount; - } - } - - /** - * Remplace les placeholders de joueurs dans la question - */ - private PlayerSelectionResult replacePlayers(String questionText) { - boolean isJoueurs1 = questionText.contains(""); - boolean isJoueurs2 = questionText.contains(""); - boolean isJoueurs3 = questionText.contains(""); - - String j1Name = null; - int playerCount = 0; - - if (isJoueurs1 || isJoueurs2 || isJoueurs3) { - List aleatoirejoueurs = TroisJoueurAleatoire(toutlesjoueurs); - - if (isJoueurs1 && isJoueurs2 && isJoueurs3 && aleatoirejoueurs.size() >= RANDOM_PLAYER_SELECTION_COUNT) { - playerCount = 3; - j1Name = aleatoirejoueurs.get(0); - questionText = questionText.replace("", ErrorHandler.escapeHtml(j1Name)); - questionText = questionText.replace("", ErrorHandler.escapeHtml(aleatoirejoueurs.get(1))); - questionText = questionText.replace("", ErrorHandler.escapeHtml(aleatoirejoueurs.get(2))); - } else if (isJoueurs1 && isJoueurs2 && aleatoirejoueurs.size() >= TWO_PLAYERS) { - playerCount = 2; - j1Name = aleatoirejoueurs.get(0); - questionText = questionText.replace("", ErrorHandler.escapeHtml(j1Name)); - questionText = questionText.replace("", ErrorHandler.escapeHtml(aleatoirejoueurs.get(1))); - } else if (isJoueurs1 && aleatoirejoueurs.size() >= ONE_PLAYER) { - playerCount = 1; - j1Name = aleatoirejoueurs.get(0); - questionText = questionText.replace("", ErrorHandler.escapeHtml(j1Name)); - } - } - - return new PlayerSelectionResult(questionText, j1Name, playerCount); - } - - /** - * Résultat du traitement des gorgées - */ - private static class GorgeeResult { - String questionText; - int totalGorgees; - boolean isBois; - boolean isDistribue; - - GorgeeResult(String questionText, int totalGorgees, boolean isBois, boolean isDistribue) { - this.questionText = questionText; - this.totalGorgees = totalGorgees; - this.isBois = isBois; - this.isDistribue = isDistribue; - } - } - - /** - * Traite les gorgées pour une question - */ - private GorgeeResult processGorgees(Question question, String questionText, int playerCount) { - int totalGorgees = 0; - boolean isBois = false; - boolean isDistribue = false; - - if (question.isDistribution() || question.isRecois()) { - totalGorgees = question.getGorger() + ajoutGorgees; - - ActionChoiceResult actionResult = determineActionChoice(question, questionText, playerCount); - questionText = actionResult.questionText; - isBois = actionResult.isBois; - isDistribue = actionResult.isDistribue; - - questionText = appendGorgeeCount(questionText, totalGorgees); - } - - return new GorgeeResult(questionText, totalGorgees, isBois, isDistribue); - } - - /** - * Résultat du choix d'action (bois/distribue) - */ - private static class ActionChoiceResult { - String questionText; - boolean isBois; - boolean isDistribue; - - ActionChoiceResult(String questionText, boolean isBois, boolean isDistribue) { - this.questionText = questionText; - this.isBois = isBois; - this.isDistribue = isDistribue; - } - } - - /** - * Détermine l'action (boit/boivent ou distribue/distribuent) selon le nombre de joueurs - */ - private ActionChoiceResult determineActionChoice(Question question, String questionText, int playerCount) { - boolean isBois = false; - boolean isDistribue = false; - - // Accord du verbe selon le nombre de joueurs - String boisVerb = (playerCount > 1) ? "boivent" : "boit"; - String distribueVerb = (playerCount > 1) ? "distribuent" : "distribue"; - - if (question.isRecois() && question.isDistribution()) { - boolean rand = random.nextBoolean(); - if (rand) { - questionText = questionText.concat(" " + boisVerb + ""); - isBois = true; - } else { - questionText = questionText.concat(" " + distribueVerb + ""); - isDistribue = true; - } - } else if (question.isRecois()) { - questionText = questionText.concat(" " + boisVerb + ""); - isBois = true; - } else if (question.isDistribution()) { - questionText = questionText.concat(" " + distribueVerb + ""); - isDistribue = true; - } - - return new ActionChoiceResult(questionText, isBois, isDistribue); - } - - /** - * Ajoute le nombre de gorgées au texte de la question - */ - private String appendGorgeeCount(String questionText, int totalGorgees) { - String plural = totalGorgees > 1 ? "s" : ""; - return questionText.concat(" " + totalGorgees + " gorgée" + plural + "."); - } - - /** - * Met à jour les statistiques du joueur J1 - */ - private void updatePlayerStats(String j1Name, GorgeeResult gorgeeResult) { - if (j1Name != null && playerStatsMap != null && playerStatsMap.containsKey(j1Name)) { - PlayerStats stats = playerStatsMap.get(j1Name); - if (gorgeeResult.isBois) { - stats.addGorgeesBuves(gorgeeResult.totalGorgees); - } - if (gorgeeResult.isDistribue) { - stats.addGorgeesDistribuees(gorgeeResult.totalGorgees); - } - } - } - - /** - * 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); - isFinishingGame = false; // Réinitialiser le flag de fin de jeu - - // 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; - } - - @Override - protected void onDestroy() { - super.onDestroy(); - // Libérer les ressources du SoundManager - if (soundManager != null) { - soundManager.release(); - } - // Libérer les ressources du service OpenAI - if (openAIService != null) { - openAIService.shutdown(); - } - } -} diff --git a/app/src/main/java/com/example/boidelov3/JeuxParametres.java b/app/src/main/java/com/example/boidelov3/JeuxParametres.java deleted file mode 100644 index 56134cd..0000000 --- a/app/src/main/java/com/example/boidelov3/JeuxParametres.java +++ /dev/null @@ -1,480 +0,0 @@ -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.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -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 com.example.boidelov3.utils.ErrorHandler; - -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, seekBarDuration; - private TextView textView1, textView2, textView5, textViewRatioGen, questionCountValue, gorgeesValue, durationValue; - private SwitchMaterial checkBoxGPT; - private Button buttonTestApi; - private EditText editText, editTextKeyGPT; - private AutoCompleteTextView autoCompleteProvider; - private String keyGPT; - private OpenAIService.AIProvider selectedProvider = OpenAIService.AIProvider.OPENAI; - 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); - seekBarDuration = findViewById(R.id.seekBarDuration); - textView1 = findViewById(R.id.textView1); - textView2 = findViewById(R.id.textView2); - textView5 = findViewById(R.id.textView5); - editTextKeyGPT = findViewById(R.id.editTextGPT); - autoCompleteProvider = findViewById(R.id.autoCompleteProvider); - buttonTestApi = findViewById(R.id.ButtonTestApi); - textViewRatioGen = findViewById(R.id.textViewRatioGen); - questionCountValue = findViewById(R.id.questionCountValue); - gorgeesValue = findViewById(R.id.gorgeesValue); - durationValue = findViewById(R.id.durationValue); - - // Configuration du dropdown pour le provider IA - String[] providers = new String[]{ - OpenAIService.AIProvider.OPENAI.getDisplayName(), - OpenAIService.AIProvider.OPENROUTER.getDisplayName(), - OpenAIService.AIProvider.ZAI.getDisplayName() - }; - ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, providers); - autoCompleteProvider.setAdapter(adapter); - - // Charger le provider sauvegardé - SharedPreferences providerPrefs = getSharedPreferences("MyPrefs", MODE_PRIVATE); - String savedProvider = providerPrefs.getString("aiProvider", OpenAIService.AIProvider.OPENAI.getDisplayName()); - autoCompleteProvider.setText(savedProvider, false); - - // Définir le provider sélectionné - if (savedProvider.equals(OpenAIService.AIProvider.OPENROUTER.getDisplayName())) { - selectedProvider = OpenAIService.AIProvider.OPENROUTER; - } else if (savedProvider.equals(OpenAIService.AIProvider.ZAI.getDisplayName())) { - selectedProvider = OpenAIService.AIProvider.ZAI; - } else { - selectedProvider = OpenAIService.AIProvider.OPENAI; - } - - // Listener pour le changement de provider - autoCompleteProvider.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - String selected = (String) parent.getItemAtPosition(position); - SharedPreferences.Editor editor = providerPrefs.edit(); - editor.putString("aiProvider", selected); - editor.apply(); - - if (selected.equals(OpenAIService.AIProvider.OPENROUTER.getDisplayName())) { - selectedProvider = OpenAIService.AIProvider.OPENROUTER; - } else if (selected.equals(OpenAIService.AIProvider.ZAI.getDisplayName())) { - selectedProvider = OpenAIService.AIProvider.ZAI; - } else { - selectedProvider = OpenAIService.AIProvider.OPENAI; - } - } - }); - - // Initialiser les TextView avec les valeurs par défaut - int initialQuestions = 50; - int initialGorgees = 0; - int initialRatio = 8; - int initialDuration = 0; // 0 pour avoir 4-10 tours par défaut (MIN_DEFI_ROUNDS=4) - - questionCountValue.setText(String.valueOf(initialQuestions)); - gorgeesValue.setText(String.valueOf(initialGorgees)); - durationValue.setText("0"); // Afficher 0 par défaut pour avoir 4-10 tours - textView5.setText("Palier : Grosse merde"); - textViewRatioGen.setText("Ratio BDD/OPENAI : 1/" + initialRatio); - - // 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 de la seekBarDuration (permet valeurs négatives pour offset) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - seekBarDuration.setMin(-5); // Permet un offset négatif jusqu'à -5 - } - seekBarDuration.setMax(15); - seekBarDuration.setProgress(0); // Valeur par défaut à 0 pour avoir 4-10 tours (MIN_DEFI_ROUNDS=4) - - // 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); - questionCountValue.setText(String.valueOf(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 gorgeesValue en fonction de la valeur de la seekBar2 - gorgeesValue.setText(String.valueOf(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 à quoi ? - // R : Il sert à activer/désactiver les vues en dessous - - Button buttonTestApi = findViewById(R.id.ButtonTestApi); - - 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 - autoCompleteProvider.setEnabled(isChecked); - // Pour le champ API key : on garde le layout activé pour le toggle password, - // mais on désactive l'édition du texte - editTextKeyGPT.setFocusable(isChecked); - editTextKeyGPT.setFocusableInTouchMode(isChecked); - editTextKeyGPT.setClickable(isChecked); - editTextKeyGPT.setCursorVisible(isChecked); - if (!isChecked) { - editTextKeyGPT.clearFocus(); - } - 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) { - } - }); - - // Configuration de la seekBarDuration - seekBarDuration.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - // Afficher avec signe +/- pour bien voir l'offset, mais sans signe pour 0 - String displayValue; - if (progress > 0) { - displayValue = "+" + progress; - } else { - displayValue = String.valueOf(progress); // Affiche "0" ou "-X" - } - durationValue.setText(displayValue); - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - - // 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(); - - if (apiKey == null || apiKey.isEmpty()) { - Toast.makeText(this, "Veuillez entrer une clé API", Toast.LENGTH_SHORT).show(); - return; - } - - // Créer un client OkHttpClient pour effectuer la requête - OkHttpClient client = new OkHttpClient.Builder() - .connectTimeout(10, java.util.concurrent.TimeUnit.SECONDS) - .readTimeout(10, java.util.concurrent.TimeUnit.SECONDS) - .build(); - - // Déterminer l'URL, le modèle et le format selon le provider sélectionné - String testUrl; - String testModel; - String jsonBody; - boolean isAnthropicFormat = (selectedProvider == OpenAIService.AIProvider.ZAI); - - switch (selectedProvider) { - case OPENROUTER: - testUrl = "https://openrouter.ai/api/v1/chat/completions"; - testModel = "openai/gpt-3.5-turbo"; - // Format OpenAI - jsonBody = "{\"model\":\"" + testModel + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Test\"}],\"max_tokens\":5}"; - break; - case ZAI: - testUrl = "https://api.z.ai/v1/messages"; - testModel = "claude-3-5-sonnet"; - // Format Anthropic - jsonBody = "{\"model\":\"" + testModel + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Test\"}],\"max_tokens\":5}"; - break; - case OPENAI: - default: - testUrl = "https://api.openai.com/v1/chat/completions"; - testModel = "gpt-3.5-turbo"; - jsonBody = "{\"model\":\"" + testModel + "\",\"messages\":[{\"role\":\"user\",\"content\":\"Test\"}],\"max_tokens\":5}"; - break; - } - - // Construire la requête - Request.Builder requestBuilder = new Request.Builder() - .url(testUrl) - .addHeader("Content-Type", "application/json"); - - // Ajouter les headers selon le provider - switch (selectedProvider) { - case OPENAI: - case OPENROUTER: - requestBuilder.addHeader("Authorization", "Bearer " + apiKey); - break; - case ZAI: - requestBuilder.addHeader("x-api-key", apiKey); - requestBuilder.addHeader("anthropic-version", "2023-06-01"); - break; - } - - // Headers spécifiques pour OpenRouter - if (selectedProvider == OpenAIService.AIProvider.OPENROUTER) { - requestBuilder.addHeader("HTTP-Referer", "https://boidelo.app"); - requestBuilder.addHeader("X-Title", "Boidelo"); - } - - Request request = requestBuilder - .post(okhttp3.RequestBody.create(jsonBody, okhttp3.MediaType.get("application/json"))) - .build(); - - // Exécuter la requête de test - client.newCall(request).enqueue(new Callback() { - @Override - public void onFailure(@NonNull Call call, IOException e) { - String operation = "Test de connexion API " + selectedProvider.getDisplayName(); - String details = "Échec de connexion lors du test de l'API"; - ErrorHandler.logErrorOnly("JeuxParametres", operation + " - " + details, e); - runOnUiThread(() -> { - String userMessage = "Échec de connexion " + selectedProvider.getDisplayName() + " : " + e.getMessage(); - Toast.makeText(getApplicationContext(), userMessage, Toast.LENGTH_SHORT).show(); - }); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - if (response.isSuccessful()) { - runOnUiThread(() -> { - Toast.makeText(getApplicationContext(), - "Connexion " + selectedProvider.getDisplayName() + " réussie !", - Toast.LENGTH_SHORT).show(); - }); - } else { - runOnUiThread(() -> { - Toast.makeText(getApplicationContext(), - "Erreur " + selectedProvider.getDisplayName() + " (HTTP " + response.code() + ")", - 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(); - int durationDefis = seekBarDuration.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_DURATION_DEFIS", durationDefis); - intent.putExtra("EXTRA_OPENAI", openAI); - final EditText editText = findViewById(R.id.editTextGPT); - intent.putExtra("EXTRA_KEY_OPENAI", editText.getText().toString()); - intent.putExtra("EXTRA_AI_PROVIDER", selectedProvider.name()); - - 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/MainActivity.java b/app/src/main/java/com/example/boidelov3/MainActivity.java deleted file mode 100644 index 8aa3c71..0000000 --- a/app/src/main/java/com/example/boidelov3/MainActivity.java +++ /dev/null @@ -1,339 +0,0 @@ -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, 0, 0, 12); // Marge identique aux champs statiques (12dp) - 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 - ); - // Plus d'espace pour le bouton poubelle (68dp au lieu de 52dp) - textInputParams.setMargins(0, 0, 68, 0); - textInputLayout.setLayoutParams(textInputParams); - textInputLayout.setBoxBackgroundMode(com.google.android.material.textfield.TextInputLayout.BOX_BACKGROUND_OUTLINE); - textInputLayout.setHint("Nom"); - - // Appliquer exactement les mêmes styles que le XML - // Créer un ColorStateList pour la bordure : grise par défaut, primaire quand focus - int[][] states = new int[][] { - new int[] { android.R.attr.state_focused}, - new int[] {} - }; - int[] colors = new int[] { - androidx.core.content.ContextCompat.getColor(this, R.color.primary), - androidx.core.content.ContextCompat.getColor(this, android.R.color.darker_gray) // Bordure grise par défaut - }; - android.content.res.ColorStateList strokeColorStateList = new android.content.res.ColorStateList(states, colors); - textInputLayout.setBoxStrokeColorStateList(strokeColorStateList); - textInputLayout.setBoxStrokeWidth(2); // Largeur de bordure comme dans le XML - textInputLayout.setBoxBackgroundColor(androidx.core.content.ContextCompat.getColor(this, R.color.surface)); - textInputLayout.setDefaultHintTextColor(androidx.core.content.ContextCompat.getColorStateList(this, R.color.text_hint)); - textInputLayout.setEndIconMode(com.google.android.material.textfield.TextInputLayout.END_ICON_CLEAR_TEXT); - - // 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 - style élégant avec fond circulaire - ImageButton deleteButton = new ImageButton(this); - int dp40 = (int) (40 * getResources().getDisplayMetrics().density); - FrameLayout.LayoutParams buttonParams = new FrameLayout.LayoutParams(dp40, dp40); - buttonParams.setMargins(0, 0, 8, 0); - buttonParams.gravity = android.view.Gravity.END | android.view.Gravity.CENTER_VERTICAL; - deleteButton.setLayoutParams(buttonParams); - - // Utiliser l'icône de poubelle Material (ic_menu_delete est une croix) - deleteButton.setImageResource(android.R.drawable.ic_menu_delete); - deleteButton.setColorFilter(androidx.core.content.ContextCompat.getColor(this, R.color.text_secondary)); - deleteButton.setScaleType(ImageButton.ScaleType.CENTER_INSIDE); - - // Fond circulaire blanc avec bordure fine - deleteButton.setBackgroundColor(androidx.core.content.ContextCompat.getColor(this, R.color.white)); - deleteButton.setPadding(8, 8, 8, 8); - - // Arrondir le bouton en cercle via un OutlineProvider - deleteButton.setOutlineProvider(new android.view.ViewOutlineProvider() { - @Override - public void getOutline(android.view.View view, android.graphics.Outline outline) { - outline.setOval(0, 0, view.getWidth(), view.getHeight()); - } - }); - deleteButton.setClipToOutline(true); - - 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(){ - // Vérifier s'il y a des noms en double (insensible à la casse) - List nomsNormauxes = new ArrayList<>(); - for (String nom : toutlesjoueurs) { - String nomNormalise = nom.trim().toLowerCase(); - if (nomsNormauxes.contains(nomNormalise)) { - // Nom en double détecté - Context context = getApplicationContext(); - CharSequence text = "Erreur : Le nom \"" + nom + "\" est utilisé plusieurs fois. Chaque joueur doit avoir un nom unique."; - int duration = Toast.LENGTH_LONG; - Toast toast = Toast.makeText(context, text, duration); - toast.show(); - return; // Ne pas continuer - } - nomsNormauxes.add(nomNormalise); - } - - //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 à 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 peut 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/res/layout/activity_jeux.xml b/app/src/main/res/layout/activity_jeux.xml deleted file mode 100644 index 6234bdf..0000000 --- a/app/src/main/res/layout/activity_jeux.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_jeux_parametres.xml b/app/src/main/res/layout/activity_jeux_parametres.xml deleted file mode 100644 index bca6050..0000000 --- a/app/src/main/res/layout/activity_jeux_parametres.xml +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 7fb38b0..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -