I'm trying to figure out where I made mistakes in my code but I can't get out of it.
I'm writing a simple Hangman game code. It seems to work until a wrong letter is typed in the JTextArea. The error appears to be located in my "gioca()" method.
Here's my code:
package giocoimpiccato;
//Frame in cui si visualizza il gioco. Qui c'è il metodo main.
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
//Composto da 1 JLABEL per la foto, 1 JLABEL per il titolo, 1 JLABEL per il
risultato, 1 JLABEL per le lettere inserite, 1 JLABEL per la parola e 1
JTEXTAREA per inserire le lettere
public class GiocoImpiccatoFrame extends javax.swing.JFrame
{
public String parolaDaIndovinare;
public ArrayList<String> lettereUsate; //uso un vettore perchè ha grandezza variabile
public int tentativi = 6;
public ArrayList<Integer> lettereTrovate;
public int sfondoCount = 0;
public ImageIcon[] sfondi; //uso un array perchè ha grandezza fissa
public int sfondoUsato = 0;
public String lettUsate = "";
//costruttore
public GiocoImpiccatoFrame()
{
lettereTrovate = new ArrayList<Integer>();
lettereUsate = new ArrayList<String>();
parolaDaIndovinare = leggiParola();
sfondi = new ImageIcon[sfondoCount + 1];
for(int i=0; i<sfondoCount; i++)
{
ImageIcon file = new javax.swing.ImageIcon(getClass().getResource("/albero" + i + ".jpg"));
sfondi[i] = file;
}
initComponents();
setLocationRelativeTo(null); //per far apparire il frame in centro allo schermo
labelSfondo.setIcon(sfondi[0]);
}
//metodo che estrae casualmente una parola dall'array
public String leggiParola()
{
Random r = new Random();
int idx = 0;
String parola = "";
String[] parole = new String[10];
parole[0] = "cane";
parole[1] = "gatto";
parole[2] = "pescespada";
parole[3] = "frutta";
parole[4] = "videogioco";
parole[5] = "sentinella";
parole[6] = "oviparo";
parole[7] = "ateneo";
parole[8] = "poltrona";
parole[9] = "fucina";
idx = r.nextInt(parole.length - 1);
parola = parole[idx];
return parola;
}
//controlla le lettere inserite, le confronta con quelle della parola e le inserisce (tramite metodo visualizzazioneParola) e segna gli errori
public void gioca(String c)
{
boolean fine = false;
boolean nonUsato = true;
boolean trovato = false;
if (c.length() == 1)
{
for (String lettUsata : lettereUsate) //ciclo for che percorre tutto un array e assegna alla variabile lettUsata ogni volta un valore dell'array fino a farli tutti
{
if ((c.toUpperCase()).equals(lettUsata.toUpperCase())) // equals per le stringhe - toUpperCase trasforma tutto in maiuscole per il confronto
{
nonUsato = false;
break;
}
}
if (nonUsato)
{
lettereUsate.add(c);
lettUsate = lettUsate + " " + c;
trovato = cerca(c.charAt(0));
if (trovato)
{
labelParola.setText(visualizzazioneParola());
fine = haiVinto();
}
else
{
tentativi--;
labelSfondo.setIcon(sfondi[++sfondoUsato]);
}
}
}
}
//metodo che restituisce una variabile booleana dopo aver confrontato il carattere in ingresso con quelli della parola da indovinare
public boolean cerca(char c)
{
boolean trovato = false;
for (int i = 0; i < parolaDaIndovinare.length(); i++)
{
if (Character.toLowerCase(parolaDaIndovinare.charAt(i)) == Character.toLowerCase(c))
{
lettereTrovate.add(i);
trovato = true;
}
}
return trovato;
}
//metodo che restituisce una variabile booleana per la vittoria
public boolean haiVinto()
{
if (parolaDaIndovinare.length() == lettereTrovate.size())
{
labelParola.setText(visualizzazioneParola());
labelRisultato.setText("Hai Vinto!");
txtInput.setEnabled(false);
return true;
}
else
{
return false;
}
}
// inserisce le lettere alla posizione corretta o la lineetta in caso di lettera ancora da indovinare
public String visualizzazioneParola()
{
String str = "";
boolean trovato = false;
for (int i = 0; i < parolaDaIndovinare.length(); i++)
{
trovato = false;
for (int j : lettereTrovate)
{
if (j == i)
{
str = str + parolaDaIndovinare.charAt(i);
trovato = true;
break;
}
}
if (trovato == false)
{
str = str + "_";
}
if (i != parolaDaIndovinare.length()-1)
{
str = str + " ";
}
}
return str;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
labelTitolo = new javax.swing.JLabel();
labelLettere = new javax.swing.JLabel();
labelParola = new javax.swing.JLabel();
labelRisultato = new javax.swing.JLabel();
txtInput = new javax.swing.JTextField();
labelSfondo = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Il Gioco dell'Impiccato");
setMinimumSize(new java.awt.Dimension(1000, 600));
setSize(new java.awt.Dimension(1000, 600));
getContentPane().setLayout(null);
labelTitolo.setFont(new java.awt.Font("Copperplate Gothic Light", 1, 36)); // NOI18N
labelTitolo.setForeground(new java.awt.Color(255, 0, 0));
labelTitolo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelTitolo.setText("Il Gioco dell'Impiccato");
getContentPane().add(labelTitolo);
labelTitolo.setBounds(156, 6, 662, 94);
labelLettere.setFont(new java.awt.Font("Arial", 1, 24)); // NOI18N
labelLettere.setForeground(new java.awt.Color(255, 0, 0));
labelLettere.setText(lettUsate);
getContentPane().add(labelLettere);
labelLettere.setBounds(6, 146, 470, 64);
labelParola.setFont(new java.awt.Font("Copperplate Gothic Light", 1, 36)); // NOI18N
labelParola.setForeground(new java.awt.Color(255, 0, 0));
labelParola.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelLettere.setText(visualizzazioneParola());
labelLettere.setToolTipText(parolaDaIndovinare);
getContentPane().add(labelParola);
labelParola.setBounds(6, 410, 651, 78);
labelRisultato.setFont(new java.awt.Font("Copperplate Gothic Light", 1, 36)); // NOI18N
labelRisultato.setForeground(new java.awt.Color(255, 0, 0));
labelRisultato.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
getContentPane().add(labelRisultato);
labelRisultato.setBounds(6, 506, 812, 88);
txtInput.setFont(new java.awt.Font("Arial", 1, 24)); // NOI18N
txtInput.setForeground(new java.awt.Color(255, 0, 0));
txtInput.setHorizontalAlignment(javax.swing.JTextField.CENTER);
txtInput.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtInputActionPerformed(evt);
}
});
getContentPane().add(txtInput);
txtInput.setBounds(6, 262, 142, 91);
labelSfondo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
getContentPane().add(labelSfondo);
labelSfondo.setBounds(0, 0, 1000, 600);
pack();
}// </editor-fold>
private void txtInputActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
gioca(txtInput.getText());
if(tentativi==0)
{
labelRisultato.setText("HAI PERSO: la parola era '" + parolaDaIndovinare.toUpperCase() + "'");
txtInput.setEnabled(false);
}
txtInput.setText("");
labelLettere.setText(lettUsate);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GiocoImpiccatoFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel labelLettere;
private javax.swing.JLabel labelParola;
private javax.swing.JLabel labelRisultato;
private javax.swing.JLabel labelSfondo;
private javax.swing.JLabel labelTitolo;
private javax.swing.JTextField txtInput;
// End of variables declaration
}
And here's the exception it generates when I type a wrong letter:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1
at giocoimpiccato.GiocoImpiccatoFrame.gioca(GiocoImpiccatoFrame.java:97)
at giocoimpiccato.GiocoImpiccatoFrame.txtInputActionPerformed(GiocoImpiccatoFrame.java:240)
It's like the wrong letter can't be added to my ArrayList lettereUsate.
I'd appreciate a tip. Thank you!
HERE'S LINE 97:
labelSfondo.setIcon(sfondi[++sfondoUsato]);