[Java] Consigli progettuali per una semplice applicazione

Discussione in 'Java' iniziata da Lollo89, 9 Agosto 2013.

  1. Lollo89

    Lollo89 Nuovo Utente

    Registrato:
    9 Agosto 2013
    Messaggi:
    5
    Mi Piace Ricevuti:
    4
    Punteggio:
    0
    Salve :)

    Tempo fa ho realizzato una briscola in java priva di interfaccia grafica. Dunque funziona solo in modo testuale. Ho provato a creare la grafica e ad integrarcela ma non ho avuto successo. Allora ho deciso di fare un passo indietro, perché credo che il problema sia la mancanza della giusta progettazione del codice, che ora come ora non si presta ad una facile modifica per renderlo interattivo.

    Ora voglio realizzare un'altra cosa che potrebbe aiutarmi. Vorrei realizzare un giochino (interattivo, che usa una semplicissima interfaccia swing) in cui due giocatori devono lanciare un dado a turno, e chi dei due ottiene il numero più alto guadagna un punto. Il tutto per 10 turni. Un giocatore agirà automaticamente, l'altro sarà l'utente, che per lanciare un dato premerà su un JButton, ovviamente quando è il suo turno.

    Ovviamente non voglio la soluzione del codice, ma solo dei consigli generali. Vorrei separare la logica dalla grafica e magari sfruttare i threads.
    Ad esempio, come posso organizzarmi per le classi? Devo usare swingWorker per processare i dati?
     
    A ottofonsuppost piace questo elemento.
  2. Slyfer

    Slyfer Utente Attivo

    Registrato:
    4 Dicembre 2010
    Messaggi:
    65
    Mi Piace Ricevuti:
    21
    Punteggio:
    0
    A ottofonsuppost piace questo elemento.
  3. Lollo89

    Lollo89 Nuovo Utente

    Registrato:
    9 Agosto 2013
    Messaggi:
    5
    Mi Piace Ricevuti:
    4
    Punteggio:
    0
    Ok, si, lo prometto :elvis:

    Però, ho buttato giù del codice. Il problema è che non riesco a modificare la grafica runtime. Mi genera eccezione! Quello che so a riguardo è che il problema sta nel fatto che le swing non sono thread safe. Dovrei farla modificare dall'edt, se non ho capito male.
    Comunque, il codice è questo:

    Dado

    Codice:
    package giocodatiinterattivo;
    
    public class Dado {
    	
    	private int[] valori;
    	
    	public Dado() {
    		valori = new int[6];
    		valori[0] = 1;
    		valori[1] = 2;
    		valori[2] = 3;
    		valori[3] = 4;
    		valori[4] = 5;
    		valori[5] = 6;
    	}
    	
    	public int getNumeroCasuale() {
    		int indice = (int) (Math.random()*6);
    		return valori[indice];
    	}
    }
    
    Game

    Codice:
    package giocodatiinterattivo;
    
    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.Dimension;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    
    @SuppressWarnings("serial")
    public class Game extends JFrame {
    	
    	private JButton tiraDado;
    	private JLabel datiGioco;
    	private JPanel northPanel;
    	private JPanel centralPanel;
    	private JPanel southPanel;
    	private JTextArea textArea;
    	private MyListener listener;
    	private Partita partita;
    	private Giocatore giocatoreA;
    	private Giocatore giocatoreB;
    	private Interfaccia interfaccia;
    	private Dado dado;
    	
    	public static void main(String[]args) {
    		java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new Game().setVisible(true);
                }
            });
    	}
    	
    	public Game() {
    		System.out.println("NUOVA PARTITA\n");
    		initComponents();
    	}
    	
    	public void initComponents() {
            
            //Inizializzo i dati per il gioco
    		
            dado = new Dado();
            giocatoreA = new Giocatore("Andrea",dado);
            giocatoreB = new Giocatore("Loris",dado);
            Partita partita = new Partita(giocatoreA,giocatoreB);
            interfaccia = new Interfaccia(this,partita);
            partita.setInterfaccia(interfaccia);
            
            //Inizializzo i dati per l'interfaccia 
            
            Container c = this.getContentPane();
            c.setLayout(new BorderLayout());
            
            tiraDado = new JButton("Tira Dado");
            datiGioco = new JLabel();
            textArea = new JTextArea("Andamento del gioco\n");
            textArea.setEditable(false); 
            
            listener = new MyListener(this,partita);
            tiraDado.addActionListener(listener);
            
            northPanel = new JPanel();
            centralPanel = new JPanel();
            southPanel = new JPanel();
            
            northPanel.setPreferredSize(new Dimension(300,50));
            centralPanel.setPreferredSize(new Dimension(300,200));
            southPanel.setPreferredSize(new Dimension(300,50));
            
            northPanel.setLayout(new BorderLayout());
            centralPanel.setLayout(new BorderLayout());
            southPanel.setLayout(new BorderLayout());
            
            northPanel.add(datiGioco, BorderLayout.CENTER);
            centralPanel.add(textArea, BorderLayout.CENTER);
            southPanel.add(tiraDado, BorderLayout.CENTER);
            
            c.add(northPanel, BorderLayout.NORTH);
            c.add(centralPanel, BorderLayout.CENTER);
            c.add(southPanel, BorderLayout.SOUTH);
            
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setTitle("Dadi - By Stefano Loris");
            setResizable(false);
            setSize(300,300);
            setVisible(true);
    	}
    	
    	public Partita getPartita() {
    		return partita;
    	}
    	
    	public JLabel getLabelDatiGioco() {
    		return datiGioco;
    	}
    	
    	public JTextArea getTextArea() {
    		return textArea;
    	}
    	
    	public JButton getButton() {
    		return tiraDado;
    	}
    }
    
    Partita

    Codice:
    package giocodatiinterattivo;
    
    import javax.swing.JOptionPane;
    
    public class Partita {
    
    	private int turniPassati;          
        private Giocatore giocatoreA;
        private Giocatore giocatoreB;
        private int puntiA;
        private int puntiB;
        private int giocataA;
        private int giocataB;
        private Interfaccia interfaccia;
        private int turno;                 //0: turno computer, 1: turno utente
        private boolean userHavePlayed;
    	
    	public Partita(Giocatore a, Giocatore b) {
    		turniPassati = 0;
        	giocatoreA = a;
        	giocatoreB = b;
        	puntiA = 0;
        	puntiB = 0;
        	giocataA = 0;
        	giocataB = 0;
        	turno = 0;
        	userHavePlayed = false;
        	//Chiamo la routine principale del gioco
        	game();
    	}
    	
    	public void setInterfaccia(Interfaccia interfaccia) {
    		this.interfaccia = interfaccia;
    	}
    	
    	private void game() {
    
    		if (isTurnoComputer()) {
    			/* user non ha giocato (inizio della mano) */
    			if (!userHavePlayed) {
    				giocoPc();
    			}
    			/* user ha già risposto al gioco pc: calcolo punti e vincitore */
    			else {
    				fineMano();
    			}
    		}
    		/* turno user */
    		else {
    			/* user non ha giocato (inizio della mano) */
    			if (!userHavePlayed) {
    				/*
    				 * non accade nulla serve il gioco dell'utente
    				 */
    			}
    			/* user ha giocato e attende risposta pc */
    			else {
    				giocoPc(); /* risposta pc */
    				fineMano(); /* punti e vincitore */
    			}
    		}
    	}
    	
    	private void giocoPc() {
    		int risultato = giocatoreA.giocaDado();
    		turniPassati++;
    		System.out.println("Sono passati " + turniPassati + " turni.");
    		//interfaccia.aggiornaTextArea("Il computer tira il dado ed ottiene " + risultato);
    		System.out.println("Il computer tira il dado ed ottiene " + risultato);
    		setPunti(0,risultato);
    		setTurnoUtente();
    	}
    	
    	public void giocoUtente() {
    		int risultato = giocatoreB.giocaDado();
    		turniPassati++;
    		System.out.println("Sono passati " + turniPassati + " turni.");
    		//interfaccia.aggiornaTextArea("Hai tirato il dado ed hai ottenuto " + risultato);
    		System.out.println("Hai tirato il dado ed hai ottenuto " + risultato);
    		setPunti(1,risultato);
    		setUserHavePlayed();
    		setTurnoPc();
    		game();
    	}
    	
    	//Setta i valori intermedi ottenuti dal lancio del dado
        public void setPunti(int giocatore, int giocata) {
        	if(giocatore == 0) {
        		giocataA = giocata;
        	}
        	if(giocatore == 1) {
        		giocataB = giocata;
        	}
        }
        
      //Sono passati due turni. E' finita la mano. Aggiorna il punteggio dei giocatori.
        public void fineMano() {
        	
        	if(giocataA == giocataB) {
        		//interfaccia.aggiornaTextArea("Pareggio");
        		System.out.println("\nPareggio\n");
        		giocataA = 0;
        		giocataB = 0;   	
        		checkPartita();
        		userHavePlayed = false;
        	}
        	if(giocataA > giocataB) {
        		//interfaccia.aggiornaTextArea("\nVince la mano il giocatore " + giocatoreA.toString() + "\n");
        		System.out.println("\nIl computer ha vinto la mano.\n");
        		puntiA++;
        		giocataA = 0;
        		giocataB = 0;	
        		checkPartita();
        		userHavePlayed = false;
        	}
        	if(giocataA < giocataB) {
        		//interfaccia.aggiornaTextArea("\nVince la mano il giocatore " + giocatoreB.toString() + "\n");
        		System.out.println("\nHai vinto la mano.\n");
        		puntiB++;
        		giocataA = 0;
        		giocataB = 0;
        		checkPartita();
        		userHavePlayed = false;
        	}
        	
        	//Richiamo la routine principale del gioco
        	game();
        }
        
        private void checkPartita() {
        	if(this.getTurniPassati() == 10) {
    			decretaVincitore();		
    			int risposta = JOptionPane.showConfirmDialog(null,"Vuoi fare una nuova partita?",
    					"Fine Partita",JOptionPane.YES_NO_OPTION);
    			if(risposta == JOptionPane.YES_OPTION) {
    				Game game = new Game();
    			}
    			if(risposta == JOptionPane.NO_OPTION) {
    				System.exit(0);
    			}
    		}
        }
        
        //La partita è finita. Stampa il vincitore
        public void decretaVincitore() {
        	if(puntiA == puntiB) {
        		//interfaccia.aggiornaLabel("Pareggio!");
        		System.out.println("Pareggio\n");
        	}
        	if(puntiA > puntiB) {
        		//interfaccia.aggiornaLabel("Vince il giocatore: " + giocatoreA.toString() + " " + puntiA + " a " + puntiB);
        		System.out.println("Vince il computer " + puntiA + " a " + puntiB + "\n");
        	}
        	else
        		//interfaccia.aggiornaLabel("Vince il giocatore: " + giocatoreB.toString() + " " + puntiB + " a " + puntiA);
        		System.out.println("Hai vinto " + puntiB + " a " + puntiA + "\n");
        }
        
        public void setUserHavePlayed() {
        	userHavePlayed = true;
        }
        
        private int getTurniPassati() {
        	return turniPassati;
        }
        
        public Interfaccia getInterfaccia() {
        	return interfaccia;
        }
        
        private void setTurnoUtente() {
        	turno = 1;
        }
        
        private void setTurnoPc() {
        	turno = 0;
        }
        
        public boolean isTurnoComputer() {
        	return turno == 0;
        }
    }
    
    Interfaccia

    Codice:
    package giocodatiinterattivo;
    
    public class Interfaccia {
    	
    	private Partita partita;
    	private Game game;
    	
    	public Interfaccia(Game g, Partita p) {
    		game = g;
    		partita = p;
    	}
    	
    	public void aggiornaLabel(String text) {
    		game.getLabelDatiGioco().setText(text);
    	}
    	
    	public void aggiornaTextArea(String text) {
    		game.getTextArea().append(text);
    	}
    	
    	public void aggiornaButton(String text) {
    		game.getButton().setText(text);
    	}
    	
    	public void setButtonEnabled() {
    		game.getButton().setEnabled(true);
    	}
    	
    	public void setButtonNotEnabled() {
    		game.getButton().setEnabled(false);
    	}
    	
    	public void updateGame() {
    		game.repaint();
    	}
    	
    	public Game getGame() {
    		return game;
    	}
    }
    
    MyListener

    Codice:
    package giocodatiinterattivo;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class MyListener implements ActionListener {
    
    	private Partita partita;
    	private Game game;
    	
    	public MyListener(Game g, Partita p) {
    		partita = p;
    		game = g;
    	}
    	
    	public void actionPerformed(ActionEvent e) {
    		partita.giocoUtente();
    	}
    }
    
    Giocatore

    Codice:
    package giocodatiinterattivo;
    
    public class Giocatore {
    	
    	private String nome;
    	private Dado dado;
    	
    	public Giocatore(String nome, Dado dado) {
    		this.nome = nome;
    		this.dado = dado;
    	}
    	
    	public int giocaDado() {
    		int res = dado.getNumeroCasuale();
    		return res;
    	}
    	
    	public String toString() {
    		return nome;
    	}
    }
    
    Al posto delle stampe, vorrei chiamare i metodi della classe interfaccia per modificare il testo della JTextArea e della JLabel!
     
    A ottofonsuppost piace questo elemento.
  4. Slyfer

    Slyfer Utente Attivo

    Registrato:
    4 Dicembre 2010
    Messaggi:
    65
    Mi Piace Ricevuti:
    21
    Punteggio:
    0
    Ciao, se non scrivi l'eccezione è difficile aiutarti.....
     
    A ottofonsuppost piace questo elemento.
  5. Lollo89

    Lollo89 Nuovo Utente

    Registrato:
    9 Agosto 2013
    Messaggi:
    5
    Mi Piace Ricevuti:
    4
    Punteggio:
    0
    Ho risolto.
     
    A ottofonsuppost piace questo elemento.
  6. Slyfer

    Slyfer Utente Attivo

    Registrato:
    4 Dicembre 2010
    Messaggi:
    65
    Mi Piace Ricevuti:
    21
    Punteggio:
    0
    Sarebbe carino dire quale era il problema e come hai risolto, in modo che possa essere di aiuto anche ad altri...
     
    A ottofonsuppost piace questo elemento.
  7. Lollo89

    Lollo89 Nuovo Utente

    Registrato:
    9 Agosto 2013
    Messaggi:
    5
    Mi Piace Ricevuti:
    4
    Punteggio:
    0
    Intanto ho migliorato un po la strutturazione del codice. Per risolvere il problema specifico ho inserito uno StringBuffer nella classe Partita nella quale vado a mettere il testo che voglio visualizzare nella textArea. Accedo al contenuto del buffer ogni volta che clicco sul pulsante per tirare il dado, quindi tramite actionListener, e sempre da esso setto il testo della textArea. Avrei bisogno di un consiglio per espandere o migliorare ulteriormente il codice. Faccio un'altra discussione oppure continuo da qui?
     
    A ottofonsuppost piace questo elemento.
Sto caricando...

Condividi questa Pagina