Indice del forum Olimpo Informatico
I Forum di Zeus News
Leggi la newsletter gratuita - Attiva il Menu compatto
 
 FAQFAQ   CercaCerca   Lista utentiLista utenti   GruppiGruppi   RegistratiRegistrati 
 ProfiloProfilo   Messaggi privatiMessaggi privati   Log inLog in 

    Newsletter RSS Facebook Twitter Contatti Ricerca
[Java] Consigli progettuali per programmino
Nuovo argomento   Rispondi    Indice del forum -> Programmazione
Precedente :: Successivo  
Autore Messaggio
Lolz89
Comune mortale
Comune mortale


Registrato: 10/08/13 12:06
Messaggi: 3
Residenza: Fossacesia

MessaggioInviato: 10 Ago 2013 12:12    Oggetto: [Java] Consigli progettuali per programmino Rispondi citando

Salve a tutti Smile

Vorrei realizzare una semplice applicazione in cui due giocatori (un umano ed un computer) lanciano a turno un dado. Chi ottiene il numero più alto guadagna un punto. Il tutto per massimo 10 turni. Alla fine vince chi dei due ha ottenuto un punteggio più elevato (dato dalla somma dei risultati dei vari lanci del dado). L'applicazione deve essere interattiva, nel senso che deve essere presente un'interfaccia swing che permette all'utente di premere un tasto per lanciare il dado quando è il suo turno. Il computer ovviamente deve agire automaticamente e mettersi in attesa della mossa dell'utente.

Mi servivano consigli su come strutturare il tutto. Non ho ancora sviluppato la forma mentis per questi programmi un po più articolati Sad

Ps: La traccia l'ho inventata io, non è un esercizio assegnatomi.

Allora, ho creato il gioco automatico. Non c'è interattività. Dovrebbe funzionare bene, credo. Come posso modificarlo in modo da renderlo interattivo come ho detto?

Dado

Codice:

package giocodadi;


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 giocodadi;


import java.util.concurrent.locks.*;


public class Game {


    public static void main(String[] args) {
       
        //Credo il dado
        Dado dado = new Dado();
        //Oggetto per gestire il lock
        ReentrantLock lock = new ReentrantLock(true);
        //Creo i giocatori
        Giocatore giocatoreA = new Giocatore("Andrea",dado,lock);
        Giocatore giocatoreB = new Giocatore("Luca",dado,lock);
        //Creo il controllore
        Controllore c = new Controllore(giocatoreA,giocatoreB);
        giocatoreA.setControllore(c);
        giocatoreB.setControllore(c);
        //Creo i threads
        Thread gA = new Thread(giocatoreA);
        Thread gB = new Thread(giocatoreB);
        //Avvio i threads
        gA.start();
        gB.start();
    }
}


Giocatore

Codice:

package giocodadi;


import java.util.Random;
import java.util.concurrent.locks.Lock;


public class Giocatore implements Runnable {
   
    private Dado dado;
    private final Lock lock;
    private final String nome;
    private Random random;
    private Controllore controllore;
   
    public Giocatore(String nome,Dado dado, Lock lock) {
        this.dado = dado;
        this.lock = lock;
        this.nome = nome;
        random = new Random();
    }
   
    public void setControllore(Controllore c) {
        this.controllore = c;
    }
   
    public void run() {
        while (controllore.getTurniPassati() <= 10) {
            lock.lock();
            try {
                if(controllore.getContaTurni() < 2) {
                    System.out.println("E' il turno "
                            + controllore.getTurniPassati());
                    int giocata = giocaDado();
                    System.out.println(nome
                            + " ha lanciato il dado ed ha ottenuto " + giocata);
                    controllore.incrementaTurno();
                    controllore.incrementaContaTurni();
                    controllore.setPunti(this, giocata);
                    // Genera un'attesa random.
                    attendi();
                }
                else {
                    controllore.resetContaTurni();
                    controllore.fineMano();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
   
    public void attendi() {
        // Genero un'attesa tra 100 e 1000 millisecondi.
        int j = 100;
        int n = 1000 - j;
        int attesa = random.nextInt(n) + j;
        try {
            Thread.sleep(attesa);
        } catch (InterruptedException e) {
            System.out.println("Qualcosa è andato storto...");
        }
    }
   
    public int giocaDado() {
        int res = dado.getNumeroCasuale();
        return res;
    }
   
    public String toString() {
        return nome;
    }
}


Controllore

Codice:

package giocodadi;


public class Controllore {


    private int turniPassati;
    private Giocatore giocatoreA;
    private Giocatore giocatoreB;
    private int puntiA;
    private int puntiB;
    private int contaTurni;
    private int giocataA;
    private int giocataB;
   
    public Controllore(Giocatore gA, Giocatore gB) {
        turniPassati = 1;
        this.giocatoreA = gA;
        this.giocatoreB = gB;
        puntiA = 0;
        puntiB = 0;
        contaTurni = 0;
        giocataA = 0;
        giocataB = 0;
    }
   
    //Setta i valori intermedi ottenuti dal lancio del dado
    public void setPunti(Giocatore g, int giocata) {
        if(g.equals(giocatoreA)) {
            giocataA = giocata;
        }
        if(g.equals(giocatoreB)) {
            giocataB = giocata;
        }
    }
   
    //Sono passati due turni. E' finita la mano. Aggiorna il punteggio dei giocatori.
    public void fineMano() {
       
        if(giocataA == giocataB) {
            System.out.println("\nPareggio." + "\n");
            giocataA = 0;
            giocataB = 0;           
            if(this.getTurniPassati() == 10) {
                decretaVincitore();
            }
        }
        if(giocataA > giocataB) {
            System.out.println("\nVince la mano il giocatore " + giocatoreA.toString() + "\n");
            puntiA++;
            giocataA = 0;
            giocataB = 0;       
            if(this.getTurniPassati() == 10) {
                decretaVincitore();
            }
        }
        if(giocataA < giocataB) {
            System.out.println("\nVince la mano il giocatore " + giocatoreB.toString() + "\n");
            puntiB++;
            giocataA = 0;
            giocataB = 0;
            if(this.getTurniPassati() == 10) {
                decretaVincitore();
            }
        }
    }
   
    //La partita è finita. Stampa il vincitore
    public void decretaVincitore() {
        if(puntiA == puntiB) {
            System.out.println("Pareggio!");
        }
        if(puntiA > puntiB) {
            System.out.println("Vince il giocatore: " + giocatoreA.toString() + " " + puntiA + " a " + puntiB);
        }
        else
            System.out.println("Vince il giocatore: " + giocatoreB.toString() + " " + puntiB + " a " + puntiA);
    }
   
    public int getContaTurni() {
        return contaTurni;
    }
   
    public void incrementaContaTurni() {
        contaTurni++;
    }
   
    public void resetContaTurni() {
        this.contaTurni = 0;
    }
   
    public int getTurniPassati() {
        return turniPassati;
    }
   
    public void incrementaTurno() {
        turniPassati++;
    }
}
Top
Profilo Invia messaggio privato
Bruck
Comune mortale
Comune mortale


Registrato: 13/08/13 19:17
Messaggi: 4

MessaggioInviato: 14 Ago 2013 08:29    Oggetto: Rispondi citando

Questo livello è abbastanza semplice, quello che devi avere chiaro è il concetto di chi fa cosa, concetto che non hai ben chiaro.
Il giocatore è un oggetto che conosce il suo stato, ma, a differenza della vita reale, non è necessario che conosca le regole e soprattutto non deve controllare il controllore!
Hai utilizzato il multi-threading. In questo caso però non serve (infatti hai utilizzato il Lock per rendere sincronizzare!)! Non ci sono operazioni talmente lunghe da richiederne l'utilizzo, inoltre utilizzandolo andrai a metterti in difficoltà successivamente.

Ho ristrutturato un po' il codice, non sapendo a che livello sei, l'ho tenuto ad un livello abbastanza comprensibile (non ho utilizzato, ad esempio, le eccezioni) e comunque ci sono alcune decisioni ancora discutibili. Dovrebbe funzionare Razz

Codice:

package giocodadi;

//Per quello che fa questa classe, non avrebbe ragione di esistere poiché non ha nessuno stato ed ogni istanza sarà uguale
//a tutte le altre.
//Se proprio vuoi fare una classe dado, il metodo andrebbe static e la classe abstract, in modo tale che non possa
//essere instanziata.
//Discorso diverso sarebbe se il dado avesse il numero di facce variabili.
//Non sapendo cosa ci vuoi fare, lascio così.
public class Dado {

public int getNumeroCasuale() {
        return (int) (Math.random() * 6) + 1;
    }
}


Codice:
package giocodadi;

import giocodadi.Controllore.Giocatori;

public class Game {
    public static void main(String[] args) {
        //Credo il dado
        Dado dado = new Dado();
        //Creo i giocatori
        Giocatore giocatoreA = new Giocatore("Andrea", dado);
        Giocatore giocatoreB = new Giocatore("Luca", dado);
        //Creo il controllore, Che come dice il nome, controlla! Non viene controllato dai giocatori!
        //Hai mai sentito di un arbitro che obbedisce a qualche giocatore?
        Controllore c = new Controllore(giocatoreA, giocatoreB);
        c.gioca(Giocatori.GIOCATORE_A);
        c.gioca(Giocatori.GIOCATORE_B);
        c.gioca(Giocatori.GIOCATORE_A);
        c.gioca(Giocatori.GIOCATORE_B);
        c.gioca(Giocatori.GIOCATORE_A); //Il controllore non gliela farà fare
        c.gioca(Giocatori.GIOCATORE_B); //Il controllore non gliela farà fare
        c.fineMano(); //Decreta il vincitore di questa mano e prepara i giocatori al nuovo turno.
    }
}


Codice:
package giocodadi;

public class Controllore {
    private int turniMano = 2;
    private int turniGioco = 10;
    private int turniGiocoC = 1;
    public enum Giocatori {GIOCATORE_A, GIOCATORE_B} //L'enum serve per non dare visibilità dei giocatori all'esterno del controllore.
    //I giocatori non possono cambiare durante una partita!
    private final Giocatore giocatoreA;
    private final Giocatore giocatoreB;
   
    // Non serve che i giocatori sappiano del controllore, i giocatori sono ignoranti e conoscono solo il loro orticello.
    public Controllore(Giocatore gA, Giocatore gB) {
        giocatoreA = gA;
        giocatoreB = gB;
    }
   
    //Gioca la mano completamente in automatico.
    public void giocaMano(){
       for (int i = 1; i<=turniMano; i++){
          gioca(Giocatori.GIOCATORE_A);
          gioca(Giocatori.GIOCATORE_B);
       }
       fineMano();
    }
   
    public void gioca(Giocatori g){
       if (turniGiocoC == turniGioco){System.out.println("La partita è finita!"); return;}
       switch (g){
       case GIOCATORE_A:
          if (giocatoreA.getTurniManoFatti() < turniMano) {
             giocatoreA.gioca();
          } else {System.out.println(giocatoreA + " ha finito i suoi turni per questa mano!");}
          break;
       case GIOCATORE_B:
          if (giocatoreB.getTurniManoFatti()< turniMano) {
             giocatoreB.gioca();
          } else {System.out.println(giocatoreB + " ha finito i suoi turni per questa mano!");}
          break;
       }
    }
   
    public void fineMano(){
       if (giocatoreA.getTurniManoFatti() == turniMano && giocatoreB.getTurniManoFatti() == turniMano){
          decretaVincitore(giocatoreA.getGiocata(), giocatoreB.getGiocata(), "la mano");
           if (turniGiocoC == turniGioco){
              decretaVincitore(giocatoreA.getPunti(), giocatoreA.getPunti(), "il gioco");
              return;
           }
          giocatoreA.fineMano();
          giocatoreB.fineMano();
          turniGiocoC++;
       } else {
          System.out.println("Un giocatore non ha fatto tutti i turni in questa mano!");
       }
    }
   
    //Riutilizzo del codice. Evitare di scrivere due metodi molto simili è sconveniente, perché quando cambierai idea sarà un macello adattare il codice.
    public void decretaVincitore(int puntiA, int puntiB, String tipoGioco) {
       if(puntiA == puntiB) {
            System.out.println("Pareggio!"); return;
        }
       //Non serve mettere il toString(). Quando tenti di stampare un oggetto, qualsiasi esso sia, Java richiama automaticamente il metodo toString()
        if(puntiA > puntiB) {
            System.out.println("Vince " + tipoGioco + " il giocatore: " + giocatoreA + " " + puntiA + " a " + puntiB);
        }
        else
            System.out.println("Vince " + tipoGioco + " il giocatore: " + giocatoreB + " " + puntiB + " a " + puntiA);
    }
   
}


Codice:
package giocodadi;

//Ha tutte le informazioni riguardo il giocatore; nome, punteggio nel gioco e della giocata.
public class Giocatore{
   
    private final Dado dado;
    private final String nome;
    private int punti; //Quando istanzi una classe, i campi sono automaticamente inizializzati al valore predefinito (0 nel caso degli int)
    private int giocata;
    private int turniManoFatti;
   
    public Giocatore(String nome, Dado dado) {
        this.dado = dado;
        this.nome = nome;
    }
    //Tira il dado e si salva il punteggio della giocata.
    public void gioca(){
       giocata += dado.getNumeroCasuale();   
       turniManoFatti++;
    }
   
    //Somma i punti della mano a quelli totali   
    public void fineMano(){
       punti += giocata;
       giocata = 0;
       turniManoFatti = 0;
    }
   
    public int getTurniManoFatti(){
       return turniManoFatti;
    }
    @Override
    public String toString() {return nome;}

   public int getPunti() {return punti;}
   public void setPunti(int punti) {this.punti = punti;}
   public void addPunti(int punti) {this.punti += punti;}
   
   public int getGiocata() {return giocata;}
   public void setGiocata(int giocata) {this.giocata = giocata;}
   public void addGiocata(int giocata) {this.giocata += giocata;}
}
Top
Profilo Invia messaggio privato
Lolz89
Comune mortale
Comune mortale


Registrato: 10/08/13 12:06
Messaggi: 3
Residenza: Fossacesia

MessaggioInviato: 14 Ago 2013 10:41    Oggetto: Rispondi

Si grazie, è piuttosto chiaro, solo che non mi piace che fai giocare i giocatori dal main chiamando c.gioca(...). Preferirei che si chiamasse c.giocaPartita(), che avvia una qualche routine di gioco automatica.
Comunque, ho ricreato il gioco in modo interattivo. Lo posto e qualsiasi consiglio è ben accetto! Inoltre vorrei modificarlo.. poi dico come.

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.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

@SuppressWarnings("serial")
public class Game extends JFrame {
   
   JButton tiraDado;
   JTextArea textArea;
   private JPanel southPanel;
   private MyListener listener;
   private Partita partita;
   private Giocatore giocatoreA;
   private Giocatore giocatoreB;
   private JScrollPane scroller;
   private Dado dado;
   
   public static void main(String[]args) {
      //Creo la GUI nell'EDT
      java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Game().setVisible(true);
            }
        });
   }
   
   public Game() {
      initComponents();
   }
   
   public void initComponents() {
       
        //Inizializzo i dati per il gioco
      
        dado = new Dado();
        giocatoreA = new Giocatore("Andrea",dado);
        giocatoreB = new Giocatore("Loris",dado);
        partita = new Partita(giocatoreA,giocatoreB);
        partita.setGame(this);
       
        //Inizializzo i dati della gui
       
        Container c = this.getContentPane();
        c.setLayout(new BorderLayout());
       
        tiraDado = new JButton("Inizia Partita");
        textArea = new JTextArea("Andamento del gioco\n");
        textArea.setEditable(false);
        scroller = new JScrollPane(textArea);
       
        textArea.setText("NUOVA PARTITA");
       
        listener = new MyListener(this,partita);
        tiraDado.addActionListener(listener);
       
        southPanel = new JPanel();       
        scroller.setPreferredSize(new Dimension(300,250));
        southPanel.setPreferredSize(new Dimension(300,50));   
        southPanel.setLayout(new BorderLayout());
        southPanel.add(tiraDado, BorderLayout.CENTER);
       
        c.add(scroller, BorderLayout.CENTER);
        c.add(southPanel, BorderLayout.SOUTH);
       
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setTitle("Dadi - By Stefano Loris");
        setResizable(false);
        setSize(300,300);
        setVisible(true);
   }
}


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;
   }
}


MyListener

Codice:

package giocodatiinterattivo;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MyListener implements ActionListener {
   
   private Game game;
   private Partita partita;
   
   public MyListener(Game game, Partita partita) {
      this.game = game;
      this.partita = partita;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      if(!game.tiraDado.getText().equals("Tira Dado")) {
         game.tiraDado.setText("Tira Dado");
      }
      partita.giocoUtente();
      game.textArea.setText(partita.getBuffer().toString());
       game.textArea.setCaretPosition(partita.getBuffer().toString().length());
   }
}


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 int turno;                 //0: turno computer, 1: turno utente
    private boolean userHavePlayed;
    private Game game;
    private StringBuffer sbf = new StringBuffer(200);
   
   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 setGame(Game game) {
      this.game = game;
   }
   
   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++;
      sbf.append("Il computer ha tirato il dado ed ha ottenuto " + risultato + "\n");
      setPunti(0,risultato);
      setTurnoUtente();
   }
   
   public void giocoUtente() {
      int risultato = giocatoreB.giocaDado();
      turniPassati++;
      sbf.append("Hai tirato il dado ed hai ottenuto " + risultato + "\n");
      setPunti(1,risultato);
      setUserHavePlayed();
      setTurnoPc();
      //Chiamo la routine del gioco principale
      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) {
          sbf.append("\nPareggio\n\n");
          giocataA = 0;
          giocataB = 0;      
          checkPartita();
          userHavePlayed = false;
       }
       if(giocataA > giocataB) {
          sbf.append("\nIl computer ha vinto la mano.\n\n");
          puntiA++;
          giocataA = 0;
          giocataB = 0;   
          checkPartita();
          userHavePlayed = false;
       }
       if(giocataA < giocataB) {
          sbf.append("\nHai vinto la mano.\n\n");
          puntiB++;
          giocataA = 0;
          giocataB = 0;
          checkPartita();
          userHavePlayed = false;
       }
       
       //Richiamo la routine principale del gioco
       game();
    }
   
    private void checkPartita() {
       if(this.getTurniPassati() == 20) {
         decretaVincitore();      
         int risposta = JOptionPane.showConfirmDialog(null,"Vuoi fare una nuova partita?",
               "Fine Partita",JOptionPane.YES_NO_OPTION);
         if(risposta == JOptionPane.YES_OPTION) {
            game.dispose();
            @SuppressWarnings("unused")
            Game game = new Game();
         }
         if(risposta == JOptionPane.NO_OPTION) {
            System.exit(0);
         }
      }
    }
   
    //La partita è finita. Stampa il vincitore
    public void decretaVincitore() {
       if(puntiA == puntiB) {
          JOptionPane.showMessageDialog(null, "PAREGGIO!");
       }
       if(puntiA > puntiB) {
          JOptionPane.showMessageDialog(null, "Vince il computer " + puntiA + " a " + puntiB);
       }
       if(puntiA < puntiB) {
          JOptionPane.showMessageDialog(null, "Hai vinto " + puntiB + " a " + puntiA);
       }
    }
   
    public void setUserHavePlayed() {
       userHavePlayed = true;
    }
   
    private int getTurniPassati() {
       return turniPassati;
    }
   
    private void setTurnoUtente() {
       turno = 1;
    }
   
    private void setTurnoPc() {
       turno = 0;
    }
   
    public boolean isTurnoComputer() {
       return turno == 0;
    }
   
    public StringBuffer getBuffer() {
       return sbf;
    }
}
Top
Profilo Invia messaggio privato
Mostra prima i messaggi di:   
Nuovo argomento   Rispondi    Indice del forum -> Programmazione Tutti i fusi orari sono GMT + 1 ora
Pagina 1 di 1

 
Vai a:  
Non puoi inserire nuovi argomenti
Non puoi rispondere a nessun argomento
Non puoi modificare i tuoi messaggi
Non puoi cancellare i tuoi messaggi
Non puoi votare nei sondaggi