Database/Compte
This commit is contained in:
13
.vscode/settings.json
vendored
Normal file
13
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"java.project.referencedLibraries": [
|
||||
"Projet-Dev/lib/**/*.jar"
|
||||
],
|
||||
"java.configuration.runtimes": [
|
||||
{
|
||||
"name": "JavaSE-24",
|
||||
"path": "C:\\Program Files\\Java\\jdk-24",
|
||||
"default": true
|
||||
}
|
||||
],
|
||||
"java.jdt.ls.java.home": "C:\\Program Files\\Java\\jdk-24"
|
||||
}
|
||||
BIN
lib/slf4j-api-2.0.13.jar
Normal file
BIN
lib/slf4j-api-2.0.13.jar
Normal file
Binary file not shown.
BIN
lib/slf4j-simple-2.0.13.jar
Normal file
BIN
lib/slf4j-simple-2.0.13.jar
Normal file
Binary file not shown.
BIN
lib/sqlite-jdbc-3.45.1.0.jar
Normal file
BIN
lib/sqlite-jdbc-3.45.1.0.jar
Normal file
Binary file not shown.
211
linea/DatabaseConnection.java
Normal file
211
linea/DatabaseConnection.java
Normal file
@@ -0,0 +1,211 @@
|
||||
package linea;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class DatabaseConnection {
|
||||
|
||||
private static final Path DB_PATH = resolveDbPath();
|
||||
private static final String DB_URL = "jdbc:sqlite:" + DB_PATH;
|
||||
private Connection conn;
|
||||
|
||||
private static Path resolveDbPath() {
|
||||
Path cwd = Paths.get("").toAbsolutePath().normalize();
|
||||
Path inProjetDev = cwd.resolve("Projet-Dev").resolve("Jeu.db");
|
||||
if (Files.exists(cwd.resolve("Projet-Dev"))) {
|
||||
return inProjetDev;
|
||||
}
|
||||
return cwd.resolve("Jeu.db");
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
try {
|
||||
Path parent = DB_PATH.getParent();
|
||||
if (parent != null) {
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
conn = DriverManager.getConnection(DB_URL);
|
||||
System.out.println("Connexion à la DB OK: " + DB_PATH);
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur de connexion DB: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
System.err.println("Erreur accès fichier DB: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (conn == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!conn.isClosed()) {
|
||||
conn.close();
|
||||
System.out.println("Déconnexion DB OK");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur à la fermeture DB: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void createTables() {
|
||||
if (conn == null) {
|
||||
System.err.println("DB non connectée, impossible de créer les tables.");
|
||||
return;
|
||||
}
|
||||
|
||||
String createCompte = """
|
||||
CREATE TABLE IF NOT EXISTS Compte (
|
||||
id_compte INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
pseudo TEXT NOT NULL
|
||||
);
|
||||
""";
|
||||
|
||||
String createNiveau = """
|
||||
CREATE TABLE IF NOT EXISTS Niveau (
|
||||
id_niveau INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
nom TEXT,
|
||||
nb_Objet INTEGER NOT NULL
|
||||
);
|
||||
""";
|
||||
|
||||
String createScore = """
|
||||
CREATE TABLE IF NOT EXISTS Score (
|
||||
id_score INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
valeur_score INTEGER,
|
||||
nb_mort INTEGER,
|
||||
temps_jeu INTEGER,
|
||||
id_compte INTEGER,
|
||||
id_niveau INTEGER,
|
||||
FOREIGN KEY(id_compte) REFERENCES Compte(id_compte),
|
||||
FOREIGN KEY(id_niveau) REFERENCES Niveau(id_niveau)
|
||||
);
|
||||
""";
|
||||
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
stmt.executeUpdate(createCompte);
|
||||
stmt.executeUpdate(createNiveau);
|
||||
stmt.executeUpdate(createScore);
|
||||
System.out.println("Tables créées / existantes OK");
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur création tables : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void sauvegarderScore(int valeur, int idCompte, int nbMort, int tempsJeuSec) {
|
||||
if (conn == null || idCompte <= 0) return;
|
||||
String sql = "INSERT INTO Score (valeur_score, nb_mort, temps_jeu, id_compte) VALUES (?, ?, ?, ?)";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setInt(1, valeur);
|
||||
ps.setInt(2, nbMort);
|
||||
ps.setInt(3, tempsJeuSec);
|
||||
ps.setInt(4, idCompte);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur sauvegarde score : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public int getMeilleurScoreParCompte(int idCompte) {
|
||||
if (conn == null || idCompte <= 0) return 0;
|
||||
String sql = "SELECT MAX(valeur_score) FROM Score WHERE id_compte = ?";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setInt(1, idCompte);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur lecture meilleur score : " + e.getMessage());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int creerCompte(String pseudo) {
|
||||
if (conn == null || pseudo == null || pseudo.isBlank()) return -1;
|
||||
String sql = "INSERT INTO Compte (pseudo) VALUES (?)";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
|
||||
ps.setString(1, pseudo.trim());
|
||||
ps.executeUpdate();
|
||||
try (ResultSet rs = ps.getGeneratedKeys()) {
|
||||
if (rs.next()) return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur création compte : " + e.getMessage());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getIdParPseudo(String pseudo) {
|
||||
if (conn == null || pseudo == null || pseudo.isBlank()) return -1;
|
||||
String sql = "SELECT id_compte FROM Compte WHERE pseudo = ? LIMIT 1";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setString(1, pseudo.trim());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) return rs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur lecture compte : " + e.getMessage());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void supprimerCompte(int idCompte) {
|
||||
if (conn == null || idCompte <= 0) return;
|
||||
try (PreparedStatement ps1 = conn.prepareStatement("DELETE FROM Score WHERE id_compte = ?");
|
||||
PreparedStatement ps2 = conn.prepareStatement("DELETE FROM Compte WHERE id_compte = ?")) {
|
||||
ps1.setInt(1, idCompte);
|
||||
ps1.executeUpdate();
|
||||
ps2.setInt(1, idCompte);
|
||||
ps2.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur suppression compte : " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getPseudos() {
|
||||
List<String> pseudos = new ArrayList<>();
|
||||
if (conn == null) return pseudos;
|
||||
String sql = "SELECT pseudo FROM Compte ORDER BY pseudo";
|
||||
try (Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(sql)) {
|
||||
while (rs.next()) {
|
||||
pseudos.add(rs.getString("pseudo"));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.err.println("Erreur lecture comptes : " + e.getMessage());
|
||||
}
|
||||
return pseudos;
|
||||
}
|
||||
|
||||
public String getStatsParCompte(int idCompte) {
|
||||
if (conn == null || idCompte <= 0) {
|
||||
return "Aucune statistique disponible.";
|
||||
}
|
||||
|
||||
String sql = "SELECT COALESCE(SUM(nb_mort),0) AS morts, "
|
||||
+ "COALESCE(SUM(temps_jeu),0) AS temps, "
|
||||
+ "COALESCE(MAX(valeur_score),0) AS meilleur "
|
||||
+ "FROM Score WHERE id_compte = ?";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setInt(1, idCompte);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
int morts = rs.getInt("morts");
|
||||
int temps = rs.getInt("temps");
|
||||
int meilleur = rs.getInt("meilleur");
|
||||
return "Nombre de morts : " + morts
|
||||
+ "\nTemps de jeu total : " + temps + " s"
|
||||
+ "\nMeilleur score : " + meilleur;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
return "Erreur lecture stats : " + e.getMessage();
|
||||
}
|
||||
return "Aucune statistique disponible.";
|
||||
}
|
||||
}
|
||||
|
||||
BIN
linea/Jeu.db
Normal file
BIN
linea/Jeu.db
Normal file
Binary file not shown.
130
linea/Jeu.java
130
linea/Jeu.java
@@ -1,14 +1,19 @@
|
||||
package linea;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.Timer;
|
||||
|
||||
public class Jeu implements KeyListener, ActionListener {
|
||||
|
||||
@@ -24,15 +29,88 @@ public class Jeu implements KeyListener, ActionListener {
|
||||
protected Timer horloge;
|
||||
protected double score = 0;
|
||||
protected JLabel labScore;
|
||||
protected JLabel labMeilleurScore;
|
||||
private DatabaseConnection db;
|
||||
private int idCompte;
|
||||
private int meilleurSansCompte = 0;
|
||||
private int mortsSansCompte = 0;
|
||||
private int tempsSansCompteSec = 0;
|
||||
private long debutPartieMs = 0;
|
||||
|
||||
private int meilleurActuel() {
|
||||
return idCompte > 0 ? db.getMeilleurScoreParCompte(idCompte) : meilleurSansCompte;
|
||||
}
|
||||
|
||||
private String statsActuelles() {
|
||||
if (idCompte > 0) {
|
||||
return db.getStatsParCompte(idCompte);
|
||||
}
|
||||
return "Nombre de morts : " + mortsSansCompte
|
||||
+ "\nTemps de jeu total : " + tempsSansCompteSec + " s"
|
||||
+ "\nMeilleur score : " + meilleurSansCompte;
|
||||
}
|
||||
|
||||
private void enregistrerPartie(int scoreActuel, int tempsPartieSec) {
|
||||
if (idCompte > 0) {
|
||||
db.sauvegarderScore(scoreActuel, idCompte, 1, tempsPartieSec);
|
||||
return;
|
||||
}
|
||||
meilleurSansCompte = Math.max(meilleurSansCompte, scoreActuel);
|
||||
mortsSansCompte += 1;
|
||||
tempsSansCompteSec += tempsPartieSec;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// CONSTRUCTEUR
|
||||
//-------------------------------------------------------------------------
|
||||
public Jeu() {
|
||||
public Jeu(DatabaseConnection db, int idCompte) {
|
||||
this.db = db;
|
||||
this.idCompte = idCompte;
|
||||
labScore = new JLabel();
|
||||
labScore.setText("<html><h3>score : 0</h3></html>");
|
||||
labScore.setBounds(20, 0, 200, 50);
|
||||
ecran.add(labScore);
|
||||
|
||||
labMeilleurScore = new JLabel();
|
||||
|
||||
JPanel panneauScores = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 0));
|
||||
panneauScores.setOpaque(false);
|
||||
panneauScores.add(labScore);
|
||||
panneauScores.add(labMeilleurScore);
|
||||
ecran.add(panneauScores, BorderLayout.NORTH);
|
||||
rafraichirMeilleurScore();
|
||||
}
|
||||
|
||||
private void rafraichirMeilleurScore() {
|
||||
labMeilleurScore.setText("<html><h3>meilleur : " + meilleurActuel() + "</h3></html>");
|
||||
}
|
||||
|
||||
private boolean choisirNouveauCompte() {
|
||||
List<String> pseudos = new ArrayList<>(db.getPseudos());
|
||||
pseudos.add(0, "Sans compte");
|
||||
|
||||
String choix = (String) JOptionPane.showInputDialog(
|
||||
null,
|
||||
"Choisissez le compte pour la prochaine partie :",
|
||||
"Changer de compte",
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
pseudos.toArray(String[]::new),
|
||||
pseudos.get(0)
|
||||
);
|
||||
|
||||
if (choix == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("Sans compte".equals(choix)) {
|
||||
idCompte = -1;
|
||||
meilleurSansCompte = 0;
|
||||
mortsSansCompte = 0;
|
||||
tempsSansCompteSec = 0;
|
||||
} else {
|
||||
idCompte = db.getIdParPseudo(choix);
|
||||
}
|
||||
rafraichirMeilleurScore();
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -79,6 +157,7 @@ public class Jeu implements KeyListener, ActionListener {
|
||||
// Création et lancement du timer
|
||||
horloge = new Timer(40, this);
|
||||
horloge.start();
|
||||
debutPartieMs = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void resetLevel() {
|
||||
@@ -88,6 +167,7 @@ public class Jeu implements KeyListener, ActionListener {
|
||||
|
||||
// Ré-initialisation des objets graphiques
|
||||
initialiserPartie();
|
||||
debutPartieMs = System.currentTimeMillis();
|
||||
|
||||
// Relance le timer existant et redonne le focus
|
||||
if (horloge != null) horloge.restart();
|
||||
@@ -104,17 +184,39 @@ public class Jeu implements KeyListener, ActionListener {
|
||||
|
||||
if (ecran.aCollision()) {
|
||||
horloge.stop();
|
||||
|
||||
Object[] options = {"Relancer", "Quitter"};
|
||||
int choix = JOptionPane.showOptionDialog(null,
|
||||
"Perdu\nScore : " + (int)score,
|
||||
"Game Over",
|
||||
JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.INFORMATION_MESSAGE,
|
||||
null, options, options[0]);
|
||||
|
||||
if (choix == 0) resetLevel();
|
||||
else System.exit(0);
|
||||
int scoreActuel = (int) score;
|
||||
int tempsPartieSec = (int) ((System.currentTimeMillis() - debutPartieMs) / 1000L);
|
||||
enregistrerPartie(scoreActuel, tempsPartieSec);
|
||||
|
||||
rafraichirMeilleurScore();
|
||||
|
||||
while (true) {
|
||||
Object[] options = {"Relancer", "Changer de compte", "Voir stats", "Quitter"};
|
||||
int choix = JOptionPane.showOptionDialog(null,
|
||||
"Perdu\nScore : " + scoreActuel + "\nMeilleur : " + meilleurActuel(),
|
||||
"Game Over",
|
||||
JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.INFORMATION_MESSAGE,
|
||||
null, options, options[0]);
|
||||
|
||||
if (choix == 0) {
|
||||
resetLevel();
|
||||
break;
|
||||
}
|
||||
if (choix == 1) {
|
||||
if (choisirNouveauCompte()) {
|
||||
resetLevel();
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (choix == 2) {
|
||||
JOptionPane.showMessageDialog(null, statsActuelles(), "Statistiques", JOptionPane.INFORMATION_MESSAGE);
|
||||
continue;
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,109 @@
|
||||
package linea;
|
||||
|
||||
import java.util.List;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
public class LineaAppli {
|
||||
|
||||
private static String choisirPseudo(DatabaseConnection db, String message, int messageType) {
|
||||
List<String> pseudos = db.getPseudos();
|
||||
if (pseudos.isEmpty()) {
|
||||
JOptionPane.showMessageDialog(null, "Aucun compte disponible.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return (String) JOptionPane.showInputDialog(
|
||||
null,
|
||||
message,
|
||||
"Comptes",
|
||||
messageType,
|
||||
null,
|
||||
pseudos.toArray(String[]::new),
|
||||
pseudos.get(0)
|
||||
);
|
||||
}
|
||||
|
||||
private static Integer menuComptes(DatabaseConnection db) {
|
||||
while (true) {
|
||||
Object[] options = {"Sélectionner", "Créer", "Supprimer", "Retour"};
|
||||
int choix = JOptionPane.showOptionDialog(
|
||||
null,
|
||||
"Gestion des comptes :",
|
||||
"Comptes",
|
||||
JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
options,
|
||||
options[0]
|
||||
);
|
||||
|
||||
if (choix == JOptionPane.CLOSED_OPTION || choix == 3) return null;
|
||||
|
||||
switch (choix) {
|
||||
case 0 -> {
|
||||
String pseudo = choisirPseudo(db, "Sélectionnez un compte :", JOptionPane.QUESTION_MESSAGE);
|
||||
if (pseudo != null) return db.getIdParPseudo(pseudo);
|
||||
}
|
||||
case 1 -> {
|
||||
String pseudo = JOptionPane.showInputDialog(null, "Nouveau pseudo :");
|
||||
if (pseudo == null || pseudo.trim().isEmpty()) continue;
|
||||
pseudo = pseudo.trim();
|
||||
int id = db.getIdParPseudo(pseudo);
|
||||
return id > 0 ? id : db.creerCompte(pseudo);
|
||||
}
|
||||
case 2 -> {
|
||||
String pseudo = choisirPseudo(db, "Sélectionnez le compte à supprimer :", JOptionPane.WARNING_MESSAGE);
|
||||
if (pseudo == null) continue;
|
||||
int confirm = JOptionPane.showConfirmDialog(
|
||||
null,
|
||||
"Supprimer le compte \"" + pseudo + "\" et toute sa progression ?",
|
||||
"Confirmation",
|
||||
JOptionPane.YES_NO_OPTION
|
||||
);
|
||||
if (confirm == JOptionPane.YES_OPTION) {
|
||||
int id = db.getIdParPseudo(pseudo);
|
||||
if (id > 0) db.supprimerCompte(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Classe de base de l'application, rien à modifier ici
|
||||
//-------------------------------------------------------------------------
|
||||
public static void main(String[] arg) {
|
||||
UIManager.put("OptionPane.cancelButtonText", "Retour");
|
||||
|
||||
Jeu jeu = new Jeu();
|
||||
|
||||
jeu.demarrer();
|
||||
DatabaseConnection db = new DatabaseConnection();
|
||||
db.connect();
|
||||
db.createTables();
|
||||
|
||||
while (true) {
|
||||
Object[] options = {"Comptes", "Sans compte", "Quitter"};
|
||||
int choix = JOptionPane.showOptionDialog(null,
|
||||
"Choisissez une action :",
|
||||
"Menu", JOptionPane.DEFAULT_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
|
||||
|
||||
if (choix == JOptionPane.CLOSED_OPTION || choix == 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (choix) {
|
||||
case 1 -> {
|
||||
new Jeu(db, -1).demarrer();
|
||||
return;
|
||||
}
|
||||
case 0 -> {
|
||||
Integer idCompte = menuComptes(db);
|
||||
if (idCompte != null) {
|
||||
new Jeu(db, idCompte).demarrer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
out/linea/Cercle.class
Normal file
BIN
out/linea/Cercle.class
Normal file
Binary file not shown.
BIN
out/linea/DatabaseConnection.class
Normal file
BIN
out/linea/DatabaseConnection.class
Normal file
Binary file not shown.
BIN
out/linea/Jeu.class
Normal file
BIN
out/linea/Jeu.class
Normal file
Binary file not shown.
BIN
out/linea/Ligne.class
Normal file
BIN
out/linea/Ligne.class
Normal file
Binary file not shown.
BIN
out/linea/LineaAppli.class
Normal file
BIN
out/linea/LineaAppli.class
Normal file
Binary file not shown.
BIN
out/linea/ObjetGraphique.class
Normal file
BIN
out/linea/ObjetGraphique.class
Normal file
Binary file not shown.
BIN
out/linea/Segment.class
Normal file
BIN
out/linea/Segment.class
Normal file
Binary file not shown.
BIN
out/linea/ZoneDessin.class
Normal file
BIN
out/linea/ZoneDessin.class
Normal file
Binary file not shown.
Reference in New Issue
Block a user