PROBLEMA Java, problema gestione round in un gioco

PSogeki

Utente Attivo
187
22
CPU
Ryzen 7 2700x
Dissipatore
Stock
Scheda Madre
Msi gaming plus max
HDD
Ssd 250gb + HDD 500gb + HDD 2tb
RAM
16 gb Viper steel 3600mhz
GPU
Powercolor Radeon rx 580 8gb
Monitor
Samsung 24" curvo
PSU
Riotoro 500w
Case
Cooler master Masterbox mb511 nero
OS
Win 10
Salve, per l'università sto facendo un progetto in cui devo ricreare il gioco del monopoli digitalizzato, in java (un po' semplificato rispetto il gioco originale).
Sto avendo però difficoltà nella gestione dei round per ogni giocatore: la mia idea era quella di creare un'unica finestra di gioco su cui per ogni turno veniva reso visibile il pannello relativo al turno di quel giocatore per poi sparire quando il turno è finito per far comparire quello del giocatore successivo, solo che il pannello del turno non compare mai.
Da quello che ho potuto capire dopo vari tentativi, modifiche e debug, è che è come se venisse ignorato il metodo "setVisible()" per poi essere eseguito solo alla fine del metodo principale "startRounds()" nonostante stia nel mezzo, quindi il "while(round.isVisible())" manda in loop infinito il codice.
Se qualcuno può aiutarmi, dirmi dove sbaglio, come correggere, perchè sono giorni che sono bloccato e non posso andare avanti con il progetto senza risolvere questo problema.
Se serve il codice di altre classi o altri chiarimenti basta chiedere. Grazie in anticipo.

Ecco il codice:
Java:
package it.unimol.monopoli.gui;

import java.awt.Dimension;
import java.io.IOException;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import it.unimol.monopoli.app.Contract;
import it.unimol.monopoli.app.Game;
import it.unimol.monopoli.app.Player;

public class GameFrame extends JFrame{
    private List<Player> players;
    private Game game;

    public GameFrame(Game game) {
        this.setTitle("Monopoli");
        this.setMinimumSize(new Dimension(1000,1000));
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        this.game = game;
        this.players = this.game.getPlayers();
    }

    public void startRounds() {
        boolean exit = false;
        do {
            for (Player player : players) {
                //problema:
                if(player.getPrison() == false) {
                    RoundPanel round = new RoundPanel(player, game.getContracts());
                    this.add(round);
                    round.setVisible(true);
                    while(round.isVisible());
                    this.remove(round);
                    }
                else {
                    RoundPrisonPanel roundPrison = new RoundPrisonPanel(player, game.getContracts());
                    this.add(roundPrison);
                    roundPrison.setVisible(true);
                    while(roundPrison.isVisible());
                    this.remove(roundPrison);
                }
                if(player.getMoney() <= 0) {
                    players.remove(player);
                    JOptionPane.showMessageDialog(
                        this,
                        "Il giocatore " + player.getName() + " è stato eliminato!",
                        "Eliminato",
                        JOptionPane.INFORMATION_MESSAGE
                    );
                }

            }
            if(players.size() > 1) {
                try {
                    game.saveGame();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                int result = JOptionPane.showConfirmDialog(null, "Round finito, continuare? ");
                if(result == 1)
                    exit = true;
            }
        } while(!exit && players.size() >= 1);

        String winner = "";
        if(players.size() == 1)
            winner = players.get(0).getName();
        else {
            int max = 0;
            for (Player player : players) {
                if(player.getMoney() > max)
                    winner = player.getName();
            }
        }
        JOptionPane.showMessageDialog(
            this,
            "Il vincitore è " + winner + "!",
            "Game Over",
            JOptionPane.INFORMATION_MESSAGE
        );
    }
}
 

Ibernato

Utente Èlite
4,330
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Salve, per l'università sto facendo un progetto in cui devo ricreare il gioco del monopoli digitalizzato, in java (un po' semplificato rispetto il gioco originale).
Sto avendo però difficoltà nella gestione dei round per ogni giocatore: la mia idea era quella di creare un'unica finestra di gioco su cui per ogni turno veniva reso visibile il pannello relativo al turno di quel giocatore per poi sparire quando il turno è finito per far comparire quello del giocatore successivo, solo che il pannello del turno non compare mai.
Da quello che ho potuto capire dopo vari tentativi, modifiche e debug, è che è come se venisse ignorato il metodo "setVisible()" per poi essere eseguito solo alla fine del metodo principale "startRounds()" nonostante stia nel mezzo, quindi il "while(round.isVisible())" manda in loop infinito il codice.
Se qualcuno può aiutarmi, dirmi dove sbaglio, come correggere, perchè sono giorni che sono bloccato e non posso andare avanti con il progetto senza risolvere questo problema.
Se serve il codice di altre classi o altri chiarimenti basta chiedere. Grazie in anticipo.

Ecco il codice:
Java:
package it.unimol.monopoli.gui;

import java.awt.Dimension;
import java.io.IOException;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import it.unimol.monopoli.app.Contract;
import it.unimol.monopoli.app.Game;
import it.unimol.monopoli.app.Player;

public class GameFrame extends JFrame{
    private List<Player> players;
    private Game game;

    public GameFrame(Game game) {
        this.setTitle("Monopoli");
        this.setMinimumSize(new Dimension(1000,1000));
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        this.game = game;
        this.players = this.game.getPlayers();
    }

    public void startRounds() {
        boolean exit = false;
        do {
            for (Player player : players) {
                //problema:
                if(player.getPrison() == false) {
                    RoundPanel round = new RoundPanel(player, game.getContracts());
                    this.add(round);
                    round.setVisible(true);
                    while(round.isVisible());
                    this.remove(round);
                    }
                else {
                    RoundPrisonPanel roundPrison = new RoundPrisonPanel(player, game.getContracts());
                    this.add(roundPrison);
                    roundPrison.setVisible(true);
                    while(roundPrison.isVisible());
                    this.remove(roundPrison);
                }
                if(player.getMoney() <= 0) {
                    players.remove(player);
                    JOptionPane.showMessageDialog(
                        this,
                        "Il giocatore " + player.getName() + " è stato eliminato!",
                        "Eliminato",
                        JOptionPane.INFORMATION_MESSAGE
                    );
                }

            }
            if(players.size() > 1) {
                try {
                    game.saveGame();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                int result = JOptionPane.showConfirmDialog(null, "Round finito, continuare? ");
                if(result == 1)
                    exit = true;
            }
        } while(!exit && players.size() >= 1);

        String winner = "";
        if(players.size() == 1)
            winner = players.get(0).getName();
        else {
            int max = 0;
            for (Player player : players) {
                if(player.getMoney() > max)
                    winner = player.getName();
            }
        }
        JOptionPane.showMessageDialog(
            this,
            "Il vincitore è " + winner + "!",
            "Game Over",
            JOptionPane.INFORMATION_MESSAGE
        );
    }
}
Scusa, perchè metti quel loop quando sei in prigione?
Mostri semplicemente il pannello della prigione e poi fai finire il turno direttamente.
Quando il player non è più in prigione, setti a false il flag e rimuovi il pannello

Facendo while(roundPrison.isVisible()); sei in un loop infinito e non ne esci più.
Dovresti usare un thread semai, ma devi gestire tutta la sincronizzazione poi.
 

PSogeki

Utente Attivo
187
22
CPU
Ryzen 7 2700x
Dissipatore
Stock
Scheda Madre
Msi gaming plus max
HDD
Ssd 250gb + HDD 500gb + HDD 2tb
RAM
16 gb Viper steel 3600mhz
GPU
Powercolor Radeon rx 580 8gb
Monitor
Samsung 24" curvo
PSU
Riotoro 500w
Case
Cooler master Masterbox mb511 nero
OS
Win 10
Scusa, perchè metti quel loop quando sei in prigione?
Mostri semplicemente il pannello della prigione e poi fai finire il turno direttamente.
Quando il player non è più in prigione, setti a false il flag e rimuovi il pannello

Facendo while(roundPrison.isVisible()); sei in un loop infinito e non ne esci più.
Dovresti usare un thread semai, ma devi gestire tutta la sincronizzazione poi.
Ho usato il loop, sia per il round in prigione che per il round normale, perchè secondo la mia idea, quando inizia il round parte il loop e questo fa in modo che non vengano caricati i pannelli relativi ai round successivi (quindi il ciclo principale è come si bloccasse momentaneamente mentre il pannello del round è attivo), e quando l'utente nella schermata del round schiaccia sul pulsante per terminare il round, il pannello scompare, facendo quindi in modo che il "while(round.isVisble())" diventa false, quindi esce da quel ciclo e carica il pannello del round successivo.
Ma come già detto questo sembra non funzionare.
Ho già provato a farlo senza loop ma succede una cosa strana: compaiono prima i messaggi di fine round e fine gioco, come se venisse prima eseguito tutto il ciclo di generazione dei pannelli e poi venisse eseguita l'istruzione "round.setVisible()", per questo cercavo qualcosa che bloccasse il ciclo e ho messo quel while
 
Ultima modifica:

Andretti60

Utente Èlite
6,440
5,091
Non si mette mai un loop in una applicazione GUI, mai, in quanto le interfacce grafiche vengono gestite da eventi di sistema che blocchi se metti un ciclo.
Forse sarebbe meglio se pubblicassi uno screenshot della tua applicazione per farci capire cosa intendi fare.
PS in un’ultra discussione abbiamo parlato di diagrammi UML, tali diagrammi sono utilissimi in casi come questi dove gli “agenti” sono svariati, per capire come strutturare la applicazione.
 
  • Mi piace
Reazioni: Ibernato

PSogeki

Utente Attivo
187
22
CPU
Ryzen 7 2700x
Dissipatore
Stock
Scheda Madre
Msi gaming plus max
HDD
Ssd 250gb + HDD 500gb + HDD 2tb
RAM
16 gb Viper steel 3600mhz
GPU
Powercolor Radeon rx 580 8gb
Monitor
Samsung 24" curvo
PSU
Riotoro 500w
Case
Cooler master Masterbox mb511 nero
OS
Win 10
Non si mette mai un loop in una applicazione GUI, mai, in quanto le interfacce grafiche vengono gestite da eventi di sistema che blocchi se metti un ciclo.
Forse sarebbe meglio se pubblicassi uno screenshot della tua applicazione per farci capire cosa intendi fare.
PS in un’ultra discussione abbiamo parlato di diagrammi UML, tali diagrammi sono utilissimi in casi come questi dove gli “agenti” sono svariati, per capire come strutturare la applicazione.
Ah ok grazie mille infatti ho modificato in modo da non usare il ciclo e ora funziona correttamente.
Però ho riscontrato un altro problemino, se nel codice ho la creazione di una nuova istanza di un pannello che funziona correttamente, ma se nello stesso blocco di codice inserisco un JOptionPane per far visualizzare un semplice messaggio di informazione, la costruzione del pannello fallisce e la finestra rimane vuota (sia se il joptionpanel lo metto prima della nuova istanza che dopo non cambia il risultato, basta che viene eseguito nello stesso blocco di codice e si blocca tutto).
Se sapreste spiegarmi il perchè e come risolverlo
 

Ibernato

Utente Èlite
4,330
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Ah ok grazie mille infatti ho modificato in modo da non usare il ciclo e ora funziona correttamente.
Però ho riscontrato un altro problemino, se nel codice ho la creazione di una nuova istanza di un pannello che funziona correttamente, ma se nello stesso blocco di codice inserisco un JOptionPane per far visualizzare un semplice messaggio di informazione, la costruzione del pannello fallisce e la finestra rimane vuota (sia se il joptionpanel lo metto prima della nuova istanza che dopo non cambia il risultato, basta che viene eseguito nello stesso blocco di codice e si blocca tutto).
Se sapreste spiegarmi il perchè e come risolverlo
Dovresti darci un log di quali errori accadono o condividere su github il progetto in modo da poterlo testare
 

PSogeki

Utente Attivo
187
22
CPU
Ryzen 7 2700x
Dissipatore
Stock
Scheda Madre
Msi gaming plus max
HDD
Ssd 250gb + HDD 500gb + HDD 2tb
RAM
16 gb Viper steel 3600mhz
GPU
Powercolor Radeon rx 580 8gb
Monitor
Samsung 24" curvo
PSU
Riotoro 500w
Case
Cooler master Masterbox mb511 nero
OS
Win 10
Dovresti darci un log di quali errori accadono o condividere su github il progetto in modo da poterlo testare
Scusami se non ho risposto prima, credevo di averlo fatto.
Di errori non me ne da perché con il debug ho visto che entra in un loop infinito dentro qualche metodo interno di java. Appena riesco condivido il progetto di github
 
  • Mi piace
Reazioni: Ibernato

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!