Precedente :: Successivo |
Autore |
Messaggio |
Lolz89 Comune mortale
Registrato: 10/08/13 12:06 Messaggi: 3 Residenza: Fossacesia
|
Inviato: 10 Ago 2013 12:12 Oggetto: [Java] Consigli progettuali per programmino |
|
|
Salve a tutti
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
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 |
|
|
Bruck Comune mortale
Registrato: 13/08/13 19:17 Messaggi: 4
|
Inviato: 14 Ago 2013 08:29 Oggetto: |
|
|
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
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 |
|
|
Lolz89 Comune mortale
Registrato: 10/08/13 12:06 Messaggi: 3 Residenza: Fossacesia
|
Inviato: 14 Ago 2013 10:41 Oggetto: |
|
|
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 |
|
|
|
|
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
|
|