Hangman masking string, unhiding character - java

I'm writing a hangman application and I'm at the point where I have to write the code to Hide each char in the string (the word being guessed) with "-"... And I've posted a lot of questions on hoe to do it and one of my replies was:Hangman - hide String and then unhide each char if guessed correct
public class HangmanWord {
private static final char HIDECHAR = '_';
private String original;
private String hidden;
public HangmanWord(String original) {
this.original = original;
this.hidden = this.createHidden();
}
private String createHidden() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < this.original.length; i++) {
sb.append(HIDECHAR);
}
return sb.toString();
}
public boolean check(char input) {
boolean found = false;
for (int i = 0; i < this.original.length; i++) {
if (this.original[i].equals(input)) {
found = true;
this.hidden[i] = this.original[i];
}
}
return found;
}
//getter and setter
}
public class TestClass() {
public static void main(String[] args) {
String secret = "stackoverflow";
int wrongGuesses = 0;
HangmanWord hngm = new HangmanWord(secret);
System.out.println(hngm.getHidden()); // _____________
if (hngm.check('a')) {
System.out.println(hngm.getHidden()); // __a_________
}
else {
wrongGuesses++;
}
//... and so on...
}
}
I tried to use this code with mine and I had a lot of errors and conclusion it didn't work with my code. In my code i've created an array buttons where if the person clicks on a button I get an message saying if the letter is in the word or not... Now I want to replace this code with where it doesn't give me an message but unhides the char and if there's no char it has to change the image
If possible can anyone explain why it didn't work with my code or can anyone please explain to me what to do...
my button array:
public JButton getButton(final String text){
final JButton button = new JButton(text);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(original.toUpperCase().indexOf(button.getText())!=-1){
JOptionPane.showMessageDialog(null, "Your word does contain " + text );
}
else{
JOptionPane.showMessageDialog(null, "There is no " + text );
error++;
if(error >= 0) imageName = "hangman1.jpg";
if(error >= 1) imageName = "hangman2.jpg";
if(error >= 2) imageName = "hangman3.jpg";
if(error >= 3) imageName = "hangman4.jpg";
if(error >= 4) imageName = "hangman5.jpg";
if(error >= 5) imageName = "hangman6.jpg";
if(error >= 7) imageName = "hangman7.jpg";
}
}
});
return button;
}
my full code:
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.List;
public final class Hangman extends JFrame implements ActionListener{
String original = readWord();
int error;
String imageName;
JButton btnAddWord = new JButton("Add New Word");
JButton btnRestart = new JButton("Restart");
JButton btnHelp = new JButton("Help");
JButton btnExit = new JButton("Exit");
JLabel word = new JLabel(original);
static JPanel panel1 = new JPanel();
static JPanel panel2 = new JPanel();
static JPanel panel3 = new JPanel();
static JPanel panel4 = new JPanel();
public Hangman(){
Container content =getContentPane();
content.setLayout(new GridLayout(0,1));
btnAddWord.addActionListener(this);
btnRestart.addActionListener(this);
btnHelp.addActionListener(this);
btnExit.addActionListener(this);
ImageIcon icon = null;
if(imageName != null){
icon = new ImageIcon(imageName);
}
JLabel image = new JLabel();
image.setIcon(icon);
panel2.add(image);
panel3.add(word);
panel4.add(btnAddWord);
panel4.add(btnRestart);
panel4.add(btnHelp);
panel4.add(btnExit);
for(char i = 'A'; i <= 'Z'; i++){
String buttonText = new Character(i).toString();
JButton button = getButton(buttonText);
panel1.add(button);
}
}
public JButton getButton(final String text){
final JButton button = new JButton(text);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(original.toUpperCase().indexOf(button.getText())!=-1){
JOptionPane.showMessageDialog(null, "Your word does contain " + text );
}
else{
JOptionPane.showMessageDialog(null, "There is no " + text );
error++;
if(error >= 0) imageName = "hangman1.jpg";
if(error >= 1) imageName = "hangman2.jpg";
if(error >= 2) imageName = "hangman3.jpg";
if(error >= 3) imageName = "hangman4.jpg";
if(error >= 4) imageName = "hangman5.jpg";
if(error >= 5) imageName = "hangman6.jpg";
if(error >= 7) imageName = "hangman7.jpg";
}
}
});
return button;
}
public String readWord(){
try{
BufferedReader reader = new BufferedReader(new FileReader("Words.txt"));
String line = reader.readLine();
List<String> words = new ArrayList<String>();
while(line != null){
String[] wordsLine = line.split(" ");
boolean addAll = words.addAll(Arrays.asList(wordsLine));
line = reader.readLine();
}
Random rand = new Random(System.currentTimeMillis());
String randomWord = words.get(rand.nextInt(words.size()));
return randomWord;
}catch (Exception e){
return null;
}
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == btnAddWord){
try{
FileWriter fw = new FileWriter("Words.txt", true);
PrintWriter pw = new PrintWriter(fw, true);
String word = JOptionPane.showInputDialog("Please enter a word: ");
pw.println(word);
pw.close();
}
catch(IOException ie){
System.out.println("Error Thrown" + ie.getMessage());
}
}
if(e.getSource() == btnRestart){
}
if(e.getSource() == btnHelp){
String message = "The word to guess is represented by a row of dashes, giving the number of letters and category of the word."
+ "\nIf the guessing player suggests a letter which occurs in the word, the other player writes it in all its correct positions."
+ "\nIf the suggested letter does not occur in the word, the other player draws one element of the hangman diagram as a tally mark."
+ "\n"
+ "\nThe game is over when:"
+ "\nThe guessing player completes the word, or guesses the whole word correctly"
+ "\nThe other player completes the diagram";
JOptionPane.showMessageDialog(null,message, "Help",JOptionPane.INFORMATION_MESSAGE);
}
if(e.getSource() == btnExit){
System.exit(0);
}
}
public static void main (String [] args){
Hangman frame = new Hangman();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 600);
frame.add(panel1, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.add(panel3, BorderLayout.SOUTH);
frame.add(panel4, BorderLayout.SOUTH);
}
}

You've had a good start with your code, but first you need to get the design clear in your mind, before writing code. Let's think about it, in steps:
When the application is launched, you load all the words in the file. So that's a step that is performed only once, and its result (the words in the file) should be saved.
The previous step does not seem to be related to your GUI code, so you may want to do it in your main method, and then pass the results to your GUI class. You can even extract this functionality into a separate class, along with choosing a random word.
Once the GUI is shown, you show a label symbolizing the hidden word. The text of this label should contain as many hidden characters ('-') as the word's characters.
Whenever a correct button is pressed, all matching characters in the word should be shown.
Whenever a wrong button is pressed, an error counter is incremented and an image is shown.
When the whole word is uncovered, character buttons should be disabled.
This leads to a design where you have a separate helper class with a method for reading the words file and another for choosing a random word. Possibly something along the lines of this:
class WordsReader {
public String[] readWords(String filename) {
// ...
}
public String chooseWord(String[] words) {
// ...
}
}
Once a new word is chosen, you should update the label. This is where the HangmanWord class suggested above comes in handy. It stores both the original word and its hidden representation. This allows you to call the check method in the buttons' handler, and update the label's text with the updated hidden representation. The rest of your code should work fine, although it can still be improved.

You could get the chars of the string, and replace the guessed letters with '-' in a new string, and display that (while behind the scenes you still have the full one)
public [static] String hideString(String string, int[] guessedLetterIndices) {
char[] chars = string.toCharArray();
for(int index : guessedLetterIndices)
chars[i] = '-';//Replace this with any letter
for(int i = 0; i < chars.length; i++) {
char c = '-';
for(int index : guessedLetterIndices)
if(index == i)
c = chars[i];
chars[i] = c;
}
return new String(chars);
}
or if you currently have an array of chars that they have chosen, as opposed to indices of characters...
public [static] String hideString(String string, char[] guessedLetters) {
char[] chars = string.toCharArray();
char[] hidden = (string.replaceAll("(.|\n)", "-").toCharArray();
for(int i=0;i<chars.length;i++) {
for(char c : guessedLetters)
if(chars[i] == c) {
hidden[i] = chars[i];
break;
}
]
return new String(chars);
}
That's what I'd do. As far as why yours does not work, could you tell me the errors you're getting? Make sure you're importing StringBuilder and stuff (whatever else they use)

Related

Checking to see if a JtextField is NOT equal to saved arrays

Hey guys I'm very new to Java and started in July with an intro to Java class.
I am currently working on a project which is a translator with arrays. The main applet shows 10 words in english that when typed into a JTextField outputs the spanish translation of that work. And vice versa. The program also shows a picture associated with that word.
The program is all done in that case, the only portion I am missing currently is that if a user inputs ANY other word than the 20 given words (10 spanish and 10 english) the JTextArea where translations are displayed is supposed to show "That word is not in the dictionary".
I'm having issues creating an ELSE statement that shows this error message. Here is the complete code. I'm not sure what to do to make it so eg
if (textFieldWord.!equals(englishWords[english])){
translate.setText("That word is not in the Dictionary");}
Here is the complete code - - - -
import java.awt.*;
import java.applet.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class DictionaryArrays extends JApplet implements ActionListener{
String[] spanishWords = {"biblioteca","reloj",
"alarma", "volcan", "ventana",
"autobus", "raton", "lago", "vaca", "encendedor"};
String[] englishWords = {"library", "clock", "alarm",
"volcano", "window", "bus", "rat",
"lake","cow","lighter"};
String textFieldWord;
Image[] photos;
ImageIcon icon;
ImageIcon icontwo;
JButton getTranslation;
JTextField entry;
JLabel imageviewer;
TextArea translate;
static int defaultX = 10;
static int defaultY = 10;
static int defaultW = 780;
static int defaultH = 50;
public void init() {
photos = new Image[10];
photos[0] = getImage(getCodeBase(), "library.jpg");
photos[1] = getImage(getCodeBase(), "clock.jpg");
photos[2] = getImage(getCodeBase(), "alarm.jpg");
photos[3] = getImage(getCodeBase(), "volcano.jpg");
photos[4] = getImage(getCodeBase(), "window.jpg");
photos[5] = getImage(getCodeBase(), "bus.jpg");
photos[6] = getImage(getCodeBase(), "rat.jpg");
photos[7] = getImage(getCodeBase(), "lake.jpg");
photos[8] = getImage(getCodeBase(), "cow.jpg");
photos[9] = getImage(getCodeBase(), "lighter.jpg");
final JPanel outer = new JPanel(new BorderLayout());
JPanel inner = new JPanel(new BorderLayout());
JPanel viewer = new JPanel(new BorderLayout());
JPanel visualviewer = new JPanel(new BorderLayout());
// here is the main component we want to see
// when the outer panel is added to the null layout
//JButton toSpanish = new JButton("English to Spanish");
//JButton toEnglish = new JButton("Spanish to English");
final JLabel list = new JLabel("<HTML><FONT COLOR=RED>English</FONT> - library, clock, alarm, volcano, window, bus, rat, lake, cow, lighter"
+"<BR><FONT COLOR=RED>Spanish</FONT> - biblioteca, reloj, alarma, volcan, ventana, autobus, raton, lago, vaca, encendedor<BR>");
translate = new TextArea("Your translation will show here");
imageviewer = new JLabel(icon);
viewer.add("West",translate);
visualviewer.add("East",imageviewer);
inner.add("Center",list);
//inner.add("West",toSpanish);
//inner.add("East", toEnglish);
outer.add("Center", inner);
JPanel c = (JPanel)getContentPane();
final JPanel nullLayoutPanel = new JPanel();
nullLayoutPanel.setLayout(null);
c.add("Center", nullLayoutPanel);
// set the bounds of the panels manually
nullLayoutPanel.add(outer);
nullLayoutPanel.add(viewer);
nullLayoutPanel.add(visualviewer);
outer.setBounds(defaultX, defaultY, defaultW, defaultH);
viewer.setBounds(20, 75, 300, 300);
visualviewer.setBounds(485, 75, 300, 300);
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
entry = new JTextField("Enter English or Spanish word to translate here");
entry.addActionListener(this);
entry.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
entry.setText("");
}});
getTranslation = new JButton("Translate");
getTranslation.addActionListener(this);
controlPanel.add(entry);
controlPanel.add(getTranslation);
c.add("South", controlPanel);
viewer.setBackground(Color.blue);
controlPanel.setBackground(Color.red);
inner.setBackground(Color.yellow);
visualviewer.setBackground(Color.black);
outer.setBackground(Color.black);
}
public void paint(Graphics g) {
super.paint(g);
}
public void actionPerformed (ActionEvent ae){
if(ae.getSource()==getTranslation){
textFieldWord=(entry.getText().toLowerCase());
for (int english = 0; english < spanishWords.length; english++){
if (textFieldWord.equals(englishWords[english])){
translate.setText(spanishWords[english]);
icon= new ImageIcon(photos[english]);
imageviewer.setIcon(icon);
break;
}
}
for (int spanish = 0; spanish < englishWords.length; spanish++){
if (textFieldWord.equals(spanishWords[spanish])){
translate.setText(englishWords[spanish]);
icontwo= new ImageIcon(photos[spanish]);
imageviewer.setIcon(icontwo);
break;
}
}
}
}
}
Any help would be appreciated guys. If the top paragraph was TLDR. Im trying to make it so typing in ANY other word in the JTextField (entry) other than the 10 english and 10 spanish words will output an error msg of "That word is not in the Dictionary" in the TextArea (translate)
This is (obviously) wrong...
if (textFieldWord.!equals(englishWords[english])){
and should be...
if (!textFieldWord.equals(englishWords[english])){
Try and think of it this way, String#equals returns a boolean, you want to invert the result of this method call, it would be the same as using something like...
boolean doesEqual = textFieldWord.equals(englishWords[english]);
if (!doesEqual) {...
You need to evaluate the result of the method call, but in oder to make that call, the syntax must be [object].[method], therefore, in order to invert the value, you must complete the method call first, then apply the modifier to it ... ! ([object].[method])
Updated...
Now having said all that, let's look at the problem from a different perspective...
You need to find a matching word, in order to do that, you must, at worse case, search the entire array. Until you've search the entire array, you don't know if a match exists.
This means we could use a separate if-else statement to manage the updating of the output, for example...
String translatedWord = null;
int foundIndex = -1;
for (int english = 0; english < spanishWords.length; english++){
if (textFieldWord.equals(englishWords[english])){
translatedWord = englishWords[english];
foundIndex = english;
break;
}
}
if (translatedWord != null) {
translate.setText(translatedWord);
icon= new ImageIcon(photos[foundIndex]);
imageviewer.setIcon(icon);
} else {
translate.setText("That word is not in the Dictionary");
}
translatedWord = null;
for (int spanish = 0; spanish < englishWords.length; spanish++){
if (textFieldWord.equals(spanishWords[spanish])){
translatedWord = englishWords[english];
foundIndex = spanish;
break;
}
}
if (translatedWord != null) {
translate.setText(translatedWord);
icontwo= new ImageIcon(photos[foundIndex]);
imageviewer.setIcon(icontwo);
} else {
translate.setText("That word is not in the Dictionary");
}
Basically, all this does is sets the translatedWord to a non null value when it finds a match in either of the arrays. In this, you want to display the results, else you want to display the error message...
Equally, you could merge your current approach with the above, so when you find a work, you update the output, but also check the state of the translatedWord variable, displaying the error message if it is null...
String translatedWord = null;
for (int english = 0; english < spanishWords.length; english++){
if (textFieldWord.equals(englishWords[english])){
translatedWord = spanishWords[english];
translate.setText(translatedWord);
icon= new ImageIcon(photos[english]);
imageviewer.setIcon(icon);
break;
}
}
if (translatedWord == null) {
translate.setText("That word is not in the Dictionary");
}
translatedWord = null;
for (int spanish = 0; spanish < englishWords.length; spanish++){
if (textFieldWord.equals(spanishWords[spanish])){
translatedWord = englishWords[spanish];
translate.setText(translatedWord);
icontwo= new ImageIcon(photos[spanish]);
imageviewer.setIcon(icontwo);
break;
}
}
if (translatedWord == null) {
translate.setText("That word is not in the Dictionary");
}
Updated
Okay, you have a logic problem. You're never quite sure which direction you are translating to.
The following basically changes the follow by not translating the work from Spanish IF it was translated to English
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == getTranslation) {
textFieldWord = (entry.getText().toLowerCase());
translate.setText(null);
String translatedWord = null;
for (int english = 0; english < spanishWords.length; english++) {
if (textFieldWord.equals(englishWords[english])) {
translatedWord = spanishWords[english];
translate.append(translatedWord + "\n");
icon = new ImageIcon(photos[english]);
imageviewer.setIcon(icon);
break;
}
}
if (translatedWord == null) {
for (int spanish = 0; spanish < englishWords.length; spanish++) {
if (textFieldWord.equals(spanishWords[spanish])) {
translatedWord = englishWords[spanish];
translate.append(translatedWord + "\n");
icontwo = new ImageIcon(photos[spanish]);
imageviewer.setIcon(icontwo);
break;
}
}
}
if (translatedWord == null) {
translate.append("A Spanish-English match is not in the Dictionary\n");
}
}
}
Now, I would suggest that you replace TextArea with a JTextArea, but you will need to wrap it in a JScrollPane
translate = new JTextArea("Your translation will show here");
viewer.add("West", new JScrollPane(translate));
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
Basically, this was really painful to try and use for this very reason...

if else -if unexpected Message

I have a swing application that involves a Container, a JButton, a JPanel, a JTextArea and an array. The array of String objects and contains 5 elements.
I want to return all elements in the array by a method and compare each of them with the element entered by end user in the text area, after pressing a JButton.
If they are same a JOptionPane message displaying the matched element should appear. If they are different a JoptionPane should show a message saying Number Entered is not found in myArray else, a message saying please Enter something" should appear
The problem I face is that when the end user enters a valid number a JOptionPane message saying: Number Entered is not found in myArray appear many times, e.g. when entering 4, a JoptionPane message saying
Number Entered is not found in myArray appear 3 times.
How do I prevent this message if the entered element is correct?
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Array_Search extends JFrame {
String myString[] = { "1", "2", "3", "4", "5" };
public String[] get_Element() {
String str[] = new String[myString.length];
str = myString;
return str;
}
public Array_Search() {
Container pane = getContentPane();
JPanel panel = new JPanel();
final JTextField txt = new JTextField(
" ");
JButton b = new JButton("Click Me ");
panel.add(b);
panel.add(txt);
pane.add(panel);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String[] str = get_Element();
String s2 = txt.getText().trim();
if (s2 != null && s2.length() > 0)
for (int i = 0; i < str.length; i++) {
if (s2.equals(str[i].trim())) {
JOptionPane option = new JOptionPane();
option.showInputDialog("" + str[i]);
} else {
JOptionPane option = new JOptionPane();
option.showInputDialog("Number Entered is not found in myArray");
}
}
else {
JOptionPane o = new JOptionPane();
o.showInputDialog("please Enter something");
}
}
});
}
public static void main(String[] args) {
Array_Search myArray = new Array_Search();
myArray.setSize(500, 500);
myArray.setVisible(true);
}
}
Your code shows message every time when non-matching element is found.
Instead, you need to look through all of the elements and display Not found message after that.
Something like this should work:
...
if (s2 != null && s2.length() > 0) {
boolean isFound = false;
for (int i = 0; i < str.length; i++) {
if (s2.equals(str[i].trim())) {
JOptionPane option = new JOptionPane();
option.showInputDialog("" + str[i]);
isFound = true;
break;
}
}
if(!isFound) {
JOptionPane option = new JOptionPane();
option.showInputDialog("Number Entered is not found in myArray");
}
} else
...
You return an empty Array in your get_Element method.
Can be fixed like that:
public void actionPerformed(ActionEvent ae) {
String [] str = get_Element(); // replace this
String [] str = myString; // with this
or change get_Element to:
public String[] get_Element() {
return myString;
}
Note: by Java code conventions use camel case for method names. getElement instead of get_Element.

for loop for array only processing one element in java?

I can't figure out why whenever I cycle through my array using the for-loop it only produces one element (the first) to console? I'm pretty sure it's a rookie-mistake I'm looking over, so any tips and suggestions would help.
I'm making a program for fun that compares two strings typed in a text field and if they don't exist in the array it produces a JOPtionPane message on the contrary. It's for a battle-hack I may produce in the future for vBulletin forum, but I'm messing around with algorithms before I move to that step. Thanks, guys!
package battleoptionspart1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.*;
import javax.swing.border.*;
public class BattleOptionsPart1 extends JFrame{
JButton newthread, previewpost;
JRadioButton battle1;
JTextField postcount, oppA, oppB;
JLabel battle2, max;
JPanel panel;
String [] array = {"Bill","Tom","Wendy", "Paula"};
public BattleOptionsPart1 () {
panel = new JPanel();
Toolkit tool = Toolkit.getDefaultToolkit();
Dimension dim = tool.getScreenSize();
this.setSize(500, 500);
this.setTitle("Battle Options");
GridLayout grid = new GridLayout(0,1,2,2);
this.setLayout(grid);
newthread = new JButton("Post New Thread");
previewpost = new JButton("Preview Post");
postcount = new JTextField("", 4);
oppA = new JTextField("",10);
oppB = new JTextField("",10);
battle1 = new JRadioButton();
battle2 = new JLabel("Would you like to start a recorded battle?");
max = new JLabel("Enter max post count user must have to vote");
ListenForButton listen = new ListenForButton();
newthread.addActionListener(listen);
previewpost.addActionListener(listen);
JPanel opponents = new JPanel();
Border oppBorder = BorderFactory.createTitledBorder("Battlers");
opponents.setBorder(oppBorder);
opponents.add(oppA);
opponents.add(oppB);
JPanel battle = new JPanel();
Border battleBorder = BorderFactory.createTitledBorder("Start Battle");
battle.setBorder(battleBorder);
battle.add(battle1);
battle.add(battle2);
JPanel buttons = new JPanel();
Border buttonBorder = BorderFactory.createTitledBorder("Create Thread");
buttons.setBorder(buttonBorder);
buttons.add(newthread);
buttons.add(previewpost);
JPanel restriction = new JPanel();
Border resBorder = BorderFactory.createTitledBorder("Restrictions");
restriction.setBorder(buttonBorder);
restriction.add(postcount);
restriction.add(max);
this.add(opponents);
this.add(battle);
this.add(restriction);
this.add(buttons);
this.add(panel);
int xPos = (dim.width / 2) - (this.getWidth() / 2);
int yPos = (dim.height / 2) - (this.getHeight() / 2);
this.setLocation(xPos,yPos); //places form in the middle
this.setVisible(true); // users can see form
this.setResizable(false); //users can't resize the form
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private class ListenForButton implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
String compareA = oppA.getText();
String compareB = oppB.getText();
if (e.getSource() == newthread)
{
System.out.println(compareA + "\n" + compareB);
for(int j = 0; j < array.length; j++)
{
System.out.println(array[j]);
if(!compareA.equals(array[j]))
{
JOptionPane.showMessageDialog(null, compareA + " doesn't exist!", "Error Message", JOptionPane.ERROR_MESSAGE);
oppA.requestFocus();
break;
}
if (!compareB.equals(array[j]))
{
JOptionPane.showMessageDialog(null, compareB + " doesn't exist!", "Error Message", JOptionPane.ERROR_MESSAGE);
oppB.requestFocus();
break;
}
else
{
JOptionPane.showMessageDialog(null, "New thread created successfully!", "Success", JOptionPane.INFORMATION_MESSAGE);
break;
}
}
}
else if (e.getSource() == previewpost)
{
System.exit(0);
}
}
}
public static void main(String[] args) {
BattleOptionsPart1 battle = new BattleOptionsPart1();
}
}
In each of the possible options in your loop, you use break, which leaves the loop immediately. If you remove those statements, you'll process each object in the array.
If you want to check if there's a match, you need to go through every element and do your processing after going through the whole array. Here is an example for an array of type int:
boolean contains = false;
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == searchKey)
{
contains = true;
break;
}
}
You're breaking out of the loop. with the break; command after the first array element

Java hangman game with gui, problems with incrementing/decrementing numbers

The following part of the code doesn't work, as the won/lost count keeps incrementing by more than 1 for each word, and sometimes I get a nullpointerexception with the string length. Moreover, although the player is supposed to get 7 tries(int no), sometimes he gets more, sometimes less. The Strings are taken from a text file "Hangeng.txt". The whole game is inside a keyboard keytyped listener that is inside a button listener. Any tips on how the layout of the game should generally be arranged so as to avoid errors are welcome, as I am only beginning to work with swing and gui stuff.
public class test{
static int won = 0;
static int lost = 0;
static String key = "";
static String word = null;
static int no = 0;
static StringBuffer toguess;
public static void main(String[] args) throws IOException{
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(3,1));
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
JPanel panel3 = new JPanel();
JButton button = new JButton();
JLabel label = new JLabel();
JLabel label2 = new JLabel();
panel1.add(label);
panel2.add(button);
panel3.add(label2);
frame.setSize(800,600);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.setVisible(true);
//the button that starts the game or gets a new word
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.requestFocus();
no = 0;
label2.setText("won " + won + ", lost " + lost);
button.setText("Next");
//get random word from file
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(
"hangeng.txt"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
int lineno = (int) (Math.random() * 100);
for (int i = 0; i < lineno; i++) {
try {
reader.readLine();
} catch (IOException e1) {
e1.printStackTrace();
}
}
try {
word = reader.readLine().replace(" ", "");
} catch (IOException e1) {
e1.printStackTrace();
}
String missing = "";
for (int u = 0; u < (word.length() - 2); u++) {
missing = missing + "*";
}
final String guess = word.charAt(0) + missing
+ word.charAt((word.length() - 1));
toguess = new StringBuffer(guess);
label.setText(toguess.toString());
final ArrayList<String> tried = new ArrayList<String>();
//keylistener that listens to key clicks by the user
frame.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent arg0) {
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
key = "" + arg0.getKeyChar();
String guessing = null;
boolean k = false;
if ((no < 6)) {
guessing = key;
System.out.println(guessing);
if (!(tried.contains(guessing))) {
tried.add(guessing);
for (int length = 1; length < (guess
.length() - 1); length++) {
if (guessing.equals(String.valueOf(word.charAt(length)))) {
toguess.replace(length,
(length + 1),
String.valueOf(word.charAt(length)));
k = true;
}
}
if (k == true) {
label.setText(toguess.toString());
} else {
no = no + 1;
}
k = false;
}
label.setText(toguess.toString());
if (toguess.toString().equals(word)) {
label.setText("Correct! The word was " + word);
no = 6;
won = won + 1;
}
}
else if ((no == 6)
&& (!(toguess.toString().equals(word)))) {
label.setText("Sorry, but the word was " + word);
lost = lost + 1;
}
}
});
}
});
}
}
+1 to all comments....
Adding to them:
Do not use KeyListener use a KeyAdapter however as you are using Swing and not AWT you should use KeyBindings for Swing see here for example.
Dont forget to create and manipulate Swing components on Event Dispatch Thread via SwingUtiltities.invokeLater(..) block see here for more.
Check class naming schemes they shuld start with capital letter, i.e test should be Test and every new word after that should be capitalized.
Do not call setSize on JFrame rather use appropriate LayoutManager and/or override getPreferredSize() of JPanel and return a size which fits its content and call pack() on JFrame instance after adding all components.
Also SSCCE should be compilable from copy and paste this is not.... i.e variables needed to be changed to final and I dont have a sample of Hangeng.txt so cant test
Lastly use the #Override annotation to ensure you are overriding the correct methods, i.e
#Override
public void actionPerformed(ActionEvent e) {
}

Character Array needs to display in certain order and place

Trying to get the final part of this game to work. Its a hangman game, I just need it to display correct guesses where they are in the word.
This is the snippet of code of when a correct guess is given
else
{
int alreadyGuessed = guesses.indexOf(guess);
if (alreadyGuessed == -1)
{
guesses = guesses + guess + "";
jlbWord.setText("Word: " + charWord[currentGuess]);
}
else{}
}
Right now it simply shows each letter. I can also set it, so it shows each one as they are typed in but its not in the right order, which makes it much more difficult for the user to guess what the word is.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.Dimension;
public class RightPanel extends JPanel implements KeyListener
{
JLabel jlbMissed, jlbWord, jlbTimer;
Color btnColor;
JComboBox jcbDifficulty;
JButton jbtStart, jbtQuit;
String[] difficulties = {"Easy", "Medium", "Hard"};
String[] words = {"First", "Next", "Hello", "World"};
char guess;
String word, guesses = "";
char[] charWord;
public static int incorrectGuesses = 0;
boolean clockIsRunning = false;
boolean gameInPlay = false;
int sec = 0;
int min = 0;
public RightPanel()
{
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
Random ran = new Random(); //
int rand = ran.nextInt(4); // Generates random number then selects word from words array
word = words[rand]; //
charWord = word.toCharArray();
ActionHandler actionHandler = new ActionHandler();
jlbMissed = new JLabel("Missed: ");
jlbWord = new JLabel("Word: ");
jlbTimer = new JLabel("Time: " + "0:00");
jbtStart = new JButton("Start");
jbtQuit = new JButton("Quit");
jcbDifficulty = new JComboBox();
jbtStart.addActionListener(actionHandler);
jbtQuit.addActionListener(actionHandler);
jcbDifficulty.addKeyListener(this);
jbtStart.addKeyListener(this);
for (int i = 0; i < 3; i++)
{
jcbDifficulty.addItem(difficulties[i]); // Creates Difficutly ComboBox
}
this.add(jcbDifficulty, getConstraints(0,0,1,1, GridBagConstraints.WEST));
this.add(jlbMissed, getConstraints(0,1,1,1, GridBagConstraints.WEST));
this.add(jlbWord, getConstraints(0,2,1,1, GridBagConstraints.WEST));
this.add(jlbTimer, getConstraints(0,4,1,1, GridBagConstraints.WEST));
this.add(jbtStart, getConstraints(0,6,1,1, GridBagConstraints.WEST));
this.add(jbtQuit, getConstraints(0,7,1,1, GridBagConstraints.WEST));
}
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e)
{
guess = e.getKeyChar();
if (gameInPlay == false)
{
JOptionPane.showMessageDialog(this, "You have not started the game yet!", "Game has not Started", JOptionPane.ERROR_MESSAGE);
System.out.println("Game Not in Play");
}
else
{
if (Character.isLetter(guess))
{
if (incorrectGuesses > 11)
{
clockIsRunning = false;
gameInPlay = false;
JOptionPane.showMessageDialog(this, "You Killed Him! \nThe word was " + word, "He Ceases to Exist", JOptionPane.ERROR_MESSAGE);
jbtStart.setText("Retry?");
jbtStart.setBackground(Color.RED);
}
else
{
int currentGuess = word.indexOf(guess);
if (currentGuess == -1)
{
int alreadyGuessed = guesses.indexOf(guess);
if (alreadyGuessed == -1)
{
guesses = guesses + guess + "";
System.out.println(alreadyGuessed);
System.out.println(guesses);
String temp = jlbMissed.getText();
jlbMissed.setText(temp + guess + ", ");
incorrectGuesses++;
leftPanel.hangmanPic.setIcon(leftPanel.image[RightPanel.incorrectGuesses]);
}
else {}
}
else
{
int alreadyGuessed = guesses.indexOf(guess);
if (alreadyGuessed == -1)
{
guesses = guesses + guess + "";
jlbWord.setText("Word: " + charWord[currentGuess]);
}
else{}
}
}
}
else
JOptionPane.showMessageDialog(this, "That is not a valid guess!\n Please enter a character from A-Z", "Invalid Guess", JOptionPane.ERROR_MESSAGE);
}
}
private GridBagConstraints getConstraints(int gridx, int gridy, int gridwidth, int gridheight, int anchor)
{
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5,5,5,5);
c.ipadx = 0;
c.ipady = 0;
c.gridx = gridx;
c.gridy = gridy;
c.gridwidth = gridwidth;
c.gridheight = gridheight;
c.anchor = anchor;
return c;
}
class ActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if (source == jbtStart)
{
if (clockIsRunning == true){}
else
{
if (jbtStart.getText() == "Start")
{
btnColor = jbtStart.getBackground();
clockIsRunning = true;
MyTimer timer = new MyTimer();
timer.start();
gameInPlay = true;
}
else if (jbtStart.getText() == "Retry?")
{
jbtStart.setText("Start");
jbtStart.setBackground(btnColor);
jlbTimer.setText("Time: " + "0:00");
sec = 0;
min = 0;
MyTimer timer = new MyTimer();
timer.start();
clockIsRunning = true;
gameInPlay = true;
incorrectGuesses = 0;
guesses = "";
jlbMissed.setText("Missed: ");
jlbWord.setText("Word: ");
leftPanel.hangmanPic.setIcon(leftPanel.image[RightPanel.incorrectGuesses]);
Random ran = new Random();
int rand = ran.nextInt(4);
word = words[rand];
}
}
}
else if (source == jbtQuit)
{
System.exit(0);
}
}
}
class MyTimer extends Thread
{
public void run()
{
while(true)
{
if(!clockIsRunning)
break;
try
{
Thread.sleep(1000);
}
catch (InterruptedException ecp)
{
}
if (sec == 59)
{
min++;
sec = 0;
}
else
sec++;
if(sec < 10)
jlbTimer.setText("Time:" + min+":0"+sec);
else
jlbTimer.setText("Time:" + min+":"+sec);
}
}
}
}
Yikes.
You should refactor your code and keep the guesses in a TreeSet<Character> data structure. It assures, that each character is stored only once and that an iterator returns all stored chars in ascending order.
Snippet:
Set<Character> guesses = new HashSet<Character>();
// add a guess
guesses.add('e');
guesses.add('r');
guesses.add('a');
guesses.add('e'); // will not be added, already in the set
// test
if (guesses.contains('e')) { ... }
// test if a word is "guessed"
boolean foundIt = true;
for (char c:word.toCharArray()) {
if (!guesses.contains(c)) {
foundIt = false;
break;
}
}
// foundIt is true if all chars of word have been guessed
// print
for (char c:guesses)
System.out.print(c); // prints: aer

Categories

Resources