import 'package:flutter/material.dart';
import 'package:mobile_tp/models/Difficulte.dart';
import 'package:mobile_tp/models/Niveau.dart';
import 'package:mobile_tp/models/Partie.dart';
import 'package:mobile_tp/screens/MysteryNumberScreen.dart';
import 'package:mobile_tp/services/AventureDB.dart';
import 'package:mobile_tp/services/DifficulteDB.dart';
import 'package:mobile_tp/services/EffectuerDB.dart';
import 'package:mobile_tp/services/NiveauDB.dart';
import 'package:mobile_tp/services/PartieDB.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:math';

class PageNiveaux extends StatefulWidget {
  final int totalNiveaux;
  final int idAventure;
  final Future<Database> database;

  PageNiveaux({
    Key? key,
    required this.totalNiveaux,
    required this.idAventure,
    required this.database,
  }) : super(key: key);

  @override
  _PageNiveauxState createState() => _PageNiveauxState();
}

class _PageNiveauxState extends State<PageNiveaux> {
  late List<Niveau> doneLevels = [];
  late AventureDB aventureDB;
  late PartieDB partieDB;
  late EffectuerDB effectuerDB;
  late NiveauDB niveauDB;
  late DifficulteDB difficulteDB;

  @override
  void initState() {
    super.initState();
    aventureDB = AventureDB(database: widget.database);
    partieDB = PartieDB(database: widget.database);
    effectuerDB = EffectuerDB(database: widget.database);
    niveauDB = NiveauDB(database: widget.database);
    difficulteDB = DifficulteDB(database: widget.database);
    loadLevels();
  }

  Future<void> loadLevels() async {
    final levels = await aventureDB.getLevelsWon(widget.idAventure);
    setState(() {
      doneLevels = levels;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Aventure'),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: FutureBuilder<List<Niveau>>(
            future: aventureDB.getLevelsWon(widget.idAventure),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                doneLevels = snapshot.data ?? [];
                return Column(
                  children: List.generate(widget.totalNiveaux * 2 - 1, (index) {
                    if (index % 2 == 0) {
                      int niveau = widget.totalNiveaux - index ~/ 2;
                      bool niveauGagne = doneLevels
                          .any((niveauGagne) => niveauGagne.palier == niveau);
                      bool niveauPrecedentGagne = niveau == 1 ||
                          doneLevels.any((niveauGagne) =>
                              niveauGagne.palier == niveau - 1);
                      return GestureDetector(
                        onTap: niveauPrecedentGagne
                            ? () async {
                                int idDifficulte;
                                if (niveau <= 3) {
                                  idDifficulte = 1;
                                } else if (niveau <= 7) {
                                  idDifficulte = 2;
                                } else {
                                  idDifficulte = 3;
                                }
                                Difficulte difficulte = await niveauDB
                                    .getDifficulteById(idDifficulte);
                                int mysteryNumber =
                                    Random().nextInt(difficulte.valeurMax) + 1;
                                Partie nouvellePartie = Partie(
                                  score: 0,
                                  nbMystere: mysteryNumber,
                                  nbEssaisJoueur: difficulte.nbTentatives,
                                  gagne: false,
                                  dateDebut: DateTime.now(),
                                  dateFin: DateTime.now(),
                                  idAventure: widget.idAventure,
                                  idNiveau: niveau,
                                );
                                int idNouvellePartie =
                                    await partieDB.add(nouvellePartie);
                                Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) => MysteryNumberScreen(
                                      database: widget.database,
                                      idPartie: idNouvellePartie,
                                      idNiveau: niveau,
                                      idDifficulte: difficulte.id,
                                      idAventure: widget.idAventure,
                                      effectuerDB: effectuerDB,
                                    ),
                                  ),
                                );
                                List<Partie> allParties =
                                    await partieDB.getAll();
                                print(allParties[allParties.length - 1].toString());
                              }
                            : null,
                        child: CircleAvatar(
                          backgroundColor:
                              niveauGagne ? Colors.green : Colors.grey,
                          child: Text(niveau.toString()),
                        ),
                      );
                    } else {
                      return SizedBox(height: 20);
                    }
                  }),
                );
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:mobile_tp/models/Effectuer.dart';
import 'package:mobile_tp/models/Partie.dart';
import 'package:mobile_tp/screens/PageNiveaux.dart';
import 'package:mobile_tp/services/EffectuerDB.dart';
import 'package:mobile_tp/services/PartieDB.dart';
import 'package:mobile_tp/services/SqliteService.dart';
import 'package:sqflite/sqflite.dart';

class MysteryNumberScreen extends StatefulWidget {
  final Future<Database> database;
  final int idPartie;
  final int idNiveau;
  final int idDifficulte;
  final int idAventure;
  final EffectuerDB effectuerDB;

  MysteryNumberScreen({
    Key? key,
    required this.database,
    required this.idPartie,
    required this.idNiveau,
    required this.idDifficulte,
    required this.idAventure,
    required this.effectuerDB,
  }) : super(key: key);

  @override
  _MysteryNumberScreenState createState() => _MysteryNumberScreenState();
}

class _MysteryNumberScreenState extends State<MysteryNumberScreen> {
  int _mysteryNumber = 0;
  int _number = 0;
  String _message = "";
  late PartieDB partieDB;

  @override
  void initState() {
    super.initState();
    partieDB = PartieDB(database: widget.database);
    _reset();
  }

  void _reset() async {
    Partie partie = await partieDB.getById(widget.idPartie);
    _mysteryNumber = partie.nbMystere;
    _number = 0;
    _message = 'Trouve le nombre';
  }

  void _check() async {
    if (_number == 0) {
      _message = 'Entrez un nombre :';
    } else if (_number < _mysteryNumber) {
      _message = 'Trop petit !';
    } else if (_number > _mysteryNumber) {
      _message = 'Trop grand !';
    } else {
      _message = 'Vous avez trouvé le nombre !';
      Effectuer effectuer = Effectuer(
        idAventure: widget.idAventure,
        idNiveau: widget.idNiveau,
        idPartie: widget.idPartie,
        complete: true,
      );
      await widget.effectuerDB.add(effectuer);
      Partie oldPartie = await partieDB.getById(widget.idPartie);

      oldPartie.gagne = true;

      await partieDB.update(oldPartie);
    }
    setState(() {
      _number = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mystery Number'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              _message,
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            TextField(
              keyboardType: TextInputType.number,
              onChanged: (value) {
                setState(() {
                  _number = int.tryParse(value) ?? 0;
                });
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _check,
              child: Text('Valider'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _reset,
              child: Text('Recommencer'),
            ),
            if (_message == 'Vous avez trouvé le nombre !')
              Column(
                children: [
                  SizedBox(height: 20),
                  ElevatedButton(
                    onPressed: () => Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                        builder: (context) => PageNiveaux(
                          totalNiveaux: 10,
                          idAventure: widget.idAventure,
                          database: widget.database,
                        ),
                      ),
                    ),
                    child: Text('Retour'),
                  ),
                ],
              ),
          ],
        ),
      ),
    );
  }
}
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class SqliteService {
  Future<void> onCreate(Database db, int version) async {
    await db.execute("""
          CREATE TABLE Aventure (
            idAventure INTEGER PRIMARY KEY AUTOINCREMENT, 
            nomJoueur TEXT NOT NULL
          )
        """);
    await db.execute("""
          CREATE TABLE Difficulte (
            idDifficulte INTEGER PRIMARY KEY AUTOINCREMENT, 
            nom TEXT NOT NULL, 
            nbTentative INTEGER NOT NULL, 
            valeurMax INTEGER NOT NULL
          )
        """);
    await db.execute("""
          CREATE TABLE Niveau (
            idNiveau INTEGER PRIMARY KEY AUTOINCREMENT, 
            palier INTEGER NOT NULL, 
            idDifficulte INTEGER NOT NULL,
            FOREIGN KEY(idDifficulte) REFERENCES Difficulte(idDifficulte)
          )
        """);
    await db.execute("""
          CREATE TABLE Partie (
            idPartie INTEGER PRIMARY KEY AUTOINCREMENT, 
            score INTEGER NOT NULL, 
            nbMystere INTEGER NOT NULL, 
            nbEssaisJoueur INTEGER NOT NULL, 
            gagne INTEGER NOT NULL, 
            dateDebut TEXT NOT NULL, 
            dateFin TEXT NOT NULL,
            idAventure INTEGER,
            idNiveau INTEGER,
            FOREIGN KEY(idAventure) REFERENCES Aventure(idAventure),
            FOREIGN KEY(idNiveau) REFERENCES Niveau(idNiveau)
          )
        """);
    await db.execute("""
          CREATE TABLE Effectuer (
            idAventure INTEGER NOT NULL, 
            idPartie INTEGER NOT NULL, 
            idNiveau INTEGER NOT NULL, 
            complete INTEGER NOT NULL,
            PRIMARY KEY(idAventure, idPartie, idNiveau),
            FOREIGN KEY(idAventure) REFERENCES Aventure(idAventure),
            FOREIGN KEY(idPartie) REFERENCES Partie(idPartie),
            FOREIGN KEY(idNiveau) REFERENCES Niveau(idNiveau)
          )
        """);
  }

  Future<Database> initializeDB() async {
    return openDatabase(
      join(await getDatabasesPath(), 'aventure.db'),
      onCreate: onCreate,
      onUpgrade: (db, oldVersion, newVersion) async {
        await db.execute("""
        DROP TABLE IF EXISTS Aventure;
        DROP TABLE IF EXISTS Difficulte;
        DROP TABLE IF EXISTS Niveau;
        DROP TABLE IF EXISTS Partie;
        DROP TABLE IF EXISTS Effectuer;
      """);
        await onCreate(db, newVersion);
      },
      version: 2,
    );
  }
}
tu vois j'ai une bd et des pages. en gros, je crée une aventure, ensuite j'ai 10 niveaux. à chaque fois que je joue sur un niveau, ça crée une nouvelle partie. une partie est considérée dans la table effectuer comme complétée si je l'ai gagnée ou perdue. sauf que j'ai un problème : je n'arrive pas à gérer avec la bd le fait que des niveaux soient gagnés selon une aventure, et en gros dans PageNiveaux il faut qu'un niveau soit en vert lorsqu'il a été gagné, comme ça je peux passer au niveau suivant. mais ça ne fonctionne pas et je ne comprends pas pourquoi, je ne sais pas si c'est à cause de ma requête ou alors si c'est la bd qui est mal faite. comment faire ?