-1

We're supposed to use methods in our program, but I'm having trouble incorporating them into it. My program is like a math game, asking simple addition and addition/subtraction questions. I want all the calculations to be in methods but I'm having trouble returning a whole equation.

I need some assistance when it comes to the direction I need to go in order to use methods effectively in my program, and where I should do my calculations! As well as what should be in its own methods and what should be in the main method.

import javax.swing.*;
import java.io.*;


public class SummativeTwo {

  public static void main (String[] args) throws IOException {

    BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in)); {

      Object[] options = {"Yes! I'm Excited!","Im kind of nervous..","Now Way! Ewww!"};
      int n = JOptionPane.showOptionDialog(null, "Welcome Million Dollar Madness! "+ "Are you ready to play?","Welcome",JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,null,options,options[2]);
      if (n == JOptionPane.YES_OPTION) {
        JOptionPane.showMessageDialog(null,"Okie Dokie! Lets get started!", "Okie Dokie", JOptionPane.INFORMATION_MESSAGE);
      }
      if (n == JOptionPane.NO_OPTION) {
        JOptionPane.showMessageDialog(null,"Aw thats okay! Im sure you'll have fun!", "It's okay", JOptionPane.INFORMATION_MESSAGE);
      }
      if (n == JOptionPane.CANCEL_OPTION) {
        JOptionPane.showMessageDialog(null,"Well too bad so sad! You're going to have to play anyways!", "Too bad so sad", JOptionPane.INFORMATION_MESSAGE);
      }

      Object[] optionsA = {"Yes Please", "Nope! I'm good!"};
      int x = JOptionPane.showOptionDialog(null,"Would you like to know the instructions for this game?","INSTRUCTIONS?", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,optionsA,optionsA[0]); 
      if (x == JOptionPane.YES_OPTION) {
        JOptionPane.showMessageDialog(null,"There will be 3 levels in this game. As you go farther, the questions get harder and harder and each question \n. Each time you get a question right you will recieve a certain amount of money, which increases each time you pass each question. \n But be careful, because if you get 3 questions wrong in one level \n it's GAME OVER for you! Meaning you lose all your money. \n You may Cash Out at any point if you're not willing to risk losing the amount of money you have. Reach the end of \n the 3 levels and you take home all your money! \n GOOD LUCK!", "Instructions", JOptionPane.INFORMATION_MESSAGE);
      }
      if (x == JOptionPane.NO_OPTION) {
        JOptionPane.showMessageDialog(null,"Suit Yourself! Lets Start!", "Your Choice", JOptionPane.INFORMATION_MESSAGE);
      }
      JOptionPane.showMessageDialog(null,"Welcome to Level: 1 " ," level 1", JOptionPane.INFORMATION_MESSAGE);

      //LEVEL ONE
      int wrong = 0;
      int run = 1;
      int questionnum = 0;
      int amount = 0;

      while (run <= 6 && wrong != 3)
      {
        run ++;
        questionnum++;
        int increment = 150;
        amount += 150;

        int numOne = additionOne ();
        int numTwo = additionTwo ();
        int answer = numOne + numTwo;


        String useranswerA = JOptionPane.showInputDialog(null,"Question #" + questionnum + " is for: $" + increment + "\n" + numOne + " + " + numTwo + " = ?", "Question", JOptionPane.INFORMATION_MESSAGE);
        int useranswer = Integer.parseInt(useranswerA);

        if (useranswer != answer)
        {
          wrong ++;
          JOptionPane.showMessageDialog(null,"You got the wrong answer! \n The correct answer is: " + answer + " \n Questions Wrong: " + wrong, "Wrong Answer", JOptionPane.INFORMATION_MESSAGE);
          int y = JOptionPane.showOptionDialog(null,"CASH OUT with a total of $" + amount + "?","Cash Out?", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,optionsA,optionsA[0]);
          if (y == JOptionPane.YES_OPTION) {
            JOptionPane.showMessageDialog(null,"Thanks for Playing!", "Thank You!", JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);
          }
          if (y == JOptionPane.NO_OPTION) {}
        }
        else if (useranswer == answer)
        {
          JOptionPane.showMessageDialog(null,"Correct!", "Right Answer", JOptionPane.INFORMATION_MESSAGE);
          int y = JOptionPane.showOptionDialog(null,"CASH OUT with a total of $" + amount + "?","Cash Out?", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,optionsA,optionsA[0]);
          if (y == JOptionPane.YES_OPTION) {
            JOptionPane.showMessageDialog(null,"Thanks for Playing!", "Thank You!", JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);
          }
          if (y == JOptionPane.NO_OPTION) {}
        }
      }
      JOptionPane.showMessageDialog(null,"LEVEL ONE COMPLETE!", "LEVEL 1", JOptionPane.INFORMATION_MESSAGE);
      JOptionPane.showMessageDialog(null,"Cash on Hand: $ " + amount, "Cash", JOptionPane.INFORMATION_MESSAGE);


      //LEVEL TWO
      JOptionPane.showMessageDialog(null,"Welcome to Level: 2 " ," level 2", JOptionPane.INFORMATION_MESSAGE);
      int wrongB = 0;
      int runB = 1;
      int questionnumB = 0;


      while (runB <= 8 && wrongB != 3)
      {
        runB ++;
        questionnumB++;
        amount += 250;

        int increment = 250;

        int numOne = additionOne ();
        int numTwo = additionTwo ();
        int numThree = numThree ();
        int answer = numOne + numTwo - numThree;


        String useranswerA = JOptionPane.showInputDialog(null,"Question #" + questionnum + " is for: $" + increment + "\n" + numOne + " + " + numTwo + " - " + numThree + " = ?", "Question", JOptionPane.INFORMATION_MESSAGE);
        int useranswer = Integer.parseInt(useranswerA);

        if (useranswer != answer)
        {
          wrong ++;
          JOptionPane.showMessageDialog(null,"You got the wrong answer! \n The correct answer is: " + answer + " \n Questions Wrong: " + wrongB, "Wrong Answer", JOptionPane.INFORMATION_MESSAGE);
          int z = JOptionPane.showOptionDialog(null,"CASH OUT with a total of $" + amount + "?","Cash Out?", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,optionsA,optionsA[0]);
          if (z == JOptionPane.YES_OPTION) {
            JOptionPane.showMessageDialog(null,"Thanks for Playing!", "Thank You!", JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);
          }
          if (z == JOptionPane.NO_OPTION) {}
        }
        else if (useranswer == answer)
        {
          JOptionPane.showMessageDialog(null,"Correct!", "Right Answer", JOptionPane.INFORMATION_MESSAGE);
          int z = JOptionPane.showOptionDialog(null,"CASH OUT with a total of $" + amount + "?","Cash Out?", JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE,null,optionsA,optionsA[0]);
          if (z == JOptionPane.YES_OPTION) {
            JOptionPane.showMessageDialog(null,"Thanks for Playing!", "Thank You!", JOptionPane.INFORMATION_MESSAGE);
            System.exit(0);
          }
          if (z == JOptionPane.NO_OPTION) {}
        }
      }
      JOptionPane.showMessageDialog(null,"LEVEL TWO COMPLETE!", "LEVEL 2", JOptionPane.INFORMATION_MESSAGE);
      JOptionPane.showMessageDialog(null,"Cash on Hand: $ " + amount, "Cash",JOptionPane.QUESTION_MESSAGE);

    }
  }

  public static int additionOne ()
  {
    int x = (int)( Math.random () * 30);
    return x;
  }
  public static int additionTwo ()
  {
    int x = (int)( Math.random () * 30);
    return x;
  }
  public static int numThree ()
  {
    int x = (int) (Math.random () * 15);
    return x;
  }
}
giannis christofakis
  • 7,777
  • 4
  • 50
  • 64
user101
  • 33
  • 1
  • 6
  • can you be more specific and point in your code what is the problem? – fmodos Jun 15 '13 at 17:20
  • @fmodos he is having trouble separating the code into methods – pinkpanther Jun 15 '13 at 17:23
  • @fmodos My code works, but my problem is using the methods effectively. Because I could easily make this code without the usage of methods. Im confused with what should be in its own method and what should be in the main method. – user101 Jun 15 '13 at 17:27
  • Check out my answer. I would like to help you further, but I need more specific information of what you want. This is not the place where people write and comment on a whole project, but more specific and small requests. – İsmet Alkan Jun 15 '13 at 17:27
  • @pinkpanther he already has the addition methods – fmodos Jun 15 '13 at 17:27
  • possible duplicate of [How do I compare strings in Java?](http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – jlordo Jun 15 '13 at 17:43
  • I think should migrated to `Code Review`. – giannis christofakis Jun 15 '13 at 17:47

5 Answers5

1

General rules of thumb when it comes to program design:

  • If you find yourself writing a lot of the same code over and over, it's a good idea to put that code in its own method. This way, it's easier to figure out what's going on, and if you need to change the code, you just have to change it in one place. It also makes it easier to unit test your code when you can divide things up into easily testable methods. Methods also allow you to make use of encapsulation e.g. some of the code can be marked private or protected.
  • I like to keep my main method as simple as possible. Ideally, it should just be an entry point for the program and kick off the real code. I don't have a lot to back me up on this, but it helps promote code re-use. The main method is inherently coupled to the command line that launches it; if you want to migrate your desktop application to a web app, for example, you would have to decouple it.

In your code, you have 2 levels, each of which does something pretty similar. That might be a good place to start looking at putting that code into its own method. Then if you wanted to add, say, level 3, it wouldn't require a lot of additional code.

austin
  • 5,778
  • 2
  • 30
  • 39
0

Your question is too vague, but I think this would help you a bit.

You have three functions: additionOne, additionTwo and numThree which are very similar. You can reduce them to a function like this:

public static int myFunction(int multiplier)
{
    int x = (int)(Math.random () * multiplier);
    return x;
}

and use it like:

int numOne = myFunction(30);
int numTwo = myFunction(30);
int numThree = myFunction(15);
int answer = numOne + numTwo - numThree;
Alexis C.
  • 87,500
  • 20
  • 164
  • 172
İsmet Alkan
  • 5,231
  • 3
  • 39
  • 64
0

One of the purpose of writing a method is reducing duplicate code. In your code it seems that you need to invove JOptionPange.showMessageDialog many times. So you can write a method in put all your message display code in it and pass the message you want to display as parameters.

public void someMethod(String message, String anotherMessage){
          JOptionPane.showMessageDialog(null,message , anotherMessage, JOptionPane.INFORMATION_MESSAGE);
// some more code to run
}

After writing, you need to just call this method in your if conditions.

Right now it won't look much useful but if you want some code to be executed after message id displayed, then you can just add in this method.

Always try to write your main method as simple as possible. Just try to call other methods from it.

Prasad Kharkar
  • 13,107
  • 3
  • 36
  • 55
  • 1
    JOptionPane.showMessageDialog is already a one-line method call itself. It is good for readability, but definitely not the suggestion that should be given to a starter. – İsmet Alkan Jun 15 '13 at 17:35
  • @IsmetAlkan Yes I understand that, thats why I edited the post to convey a message that it won't be useful right now but it will be useful if there is some more operation to be performed after showing dialog and you can write it in the method only. Thanks for your suggestion :) – Prasad Kharkar Jun 15 '13 at 17:37
  • This custom method should be [`private`](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html), not `public`. That’s because showing message dialogs is only weakly related to the main purpose of the `SummativeTwo` class. Thus, other classes should not depend on `SummativeTwo` having this method. – Rory O'Kane Jun 15 '13 at 17:58
0

To start with, pull out anything that is duplicated. So for the 2 sets of blocks:

if (useranswer != answer)

and

else if (useranswer == answer)

I would have the contents of those blocks be a method where any differences are the parameters to the method - or just have one boolean right/wrong parameter and adjust which set of strings inside the method are called. Do whichever way has less code. If the same strings are used in sets 1 and 3 and also in 2 and 4, then instead of sending them as params 4 times (declaring them 4 times), just declare them twice - so that would mean inside the method.

After you remove duplicate code, the next step would be starting at smallish blocks of code (perhaps 10-20 lines), often inside braces, and preferably where new variables are used that aren't needed elsewhere.

After removing smaller blocks, you may find that you have new "small" blocks that you can remove. Level 1 and Level 2 could be in different methods.

Ideally just try to keep methods smaller so that a reader doesn't have to scroll, and they can look over the whole code of the method easily, run it all in their head, and know what it is doing.

AngelWarrior
  • 430
  • 4
  • 11
0

The 1. level and 2. level were almost identical. So extracting first level to separate method will break the code for the next level. The broken syntax guides what information is required from level one to level 2. It seemed that only amount required necessary.

Following this way of refactoring also suggested that the original wrongB and questionnumB were not used properly. I took the liberty to assume that both round have separate wrong- and questionnum-variables.

Problem in this approach is that if code is not well understood and fragile without tests it is likely it will broke. However I have found it to be effective in cases where smaller refactoring steps are not obvious.

In general all methods should be clear to read. Because main method is the most top method it should clearly state what goes on in program. Methods should be on the same level of abstraction and very short.

The information is passed using State-object but in this case simple amount could be returned from runLevel and passed as a parameter to the next.

I don't know if the dialog thing was meant to be cleaned up but I took some steps to reduce repeated code. Whole thing could be polished a lot more more. I hope this might give some guidance...

Clean code (http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882) is very good book about refactoring and making methods and code in genera readable.

Here is my two cents:

public class SummativeTwo {

public static void main(String[] args) throws IOException {
    BufferedReader myInput = new BufferedReader(new InputStreamReader(System.in));
    {
        showYesNoCancelDialogWithFollowUp(
                "Welcome",
                "Welcome Million Dollar Madness! " + "Are you ready to play?",
                new DialogOption("Yes! I'm Excited!", new InformationDialog("Okie Dokie! Lets get started!", "Okie Dokie")),
                new DialogOption("Im kind of nervous..", new InformationDialog("Aw thats okay! Im sure you'll have fun!", "It's okay")),
                new DialogOption("Now Way! Ewww!", new InformationDialog("Well too bad so sad! You're going to have to play anyways!", "Too bad so sad")));

        showYesNoDialogWithFollowUp("INSTRUCTIONS?",
                "Would you like to know the instructions for this game?",
                new InformationDialog("There will be 3 levels in this game. As you go farther, the questions get harder and harder and each question \n. Each time you get a question right you will recieve a certain amount of money, which increases each time you pass each question. \n But be careful, because if you get 3 questions wrong in one level \n it's GAME OVER for you! Meaning you lose all your money. \n You may Cash Out at any point if you're not willing to risk losing the amount of money you have. Reach the end of \n the 3 levels and you take home all your money! \n GOOD LUCK!", "Instructions"),
                new InformationDialog("Your Choice", "Suit Yourself! Lets Start!"));


        showInformationMessage("Welcome to Level: 1 ", " level 1");

        State state = new State();
        runLevel1(state);
        showInformationMessage("LEVEL ONE COMPLETE!", "LEVEL 1");
        showInformationMessage("Cash on Hand: $ " + state.amount, "Cash");
        showInformationMessage("Welcome to Level: 2 ", " level 2");
        runLevel2(state);
        showInformationMessage("LEVEL TWO COMPLETE!", "LEVEL 2");
        JOptionPane.showMessageDialog(null, "Cash on Hand: $ " + state.amount, "Cash", JOptionPane.QUESTION_MESSAGE);

    }
}

static class State {

    int amount;
}

private static void runLevel1(State state) {
    int maxRuns = 6;
    int maxWrongs = 3;
    int increment = 150;
    runLevel(increment, maxRuns, maxWrongs, state);
}

private static void runLevel2(State state) {
    int maxRuns = 8;
    int maxWrongs = 3;
    int increment = 150;
    runLevel(increment, maxRuns, maxWrongs, state);
}

private static void runLevel(int increment, int maxRuns, int maxWrongs, State state) throws NumberFormatException, HeadlessException {
    int run = 1;
    int questionnum = 0;
    int wrong = 0;
    while (run <= maxRuns && wrong != maxWrongs) {
        run++;
        questionnum++;
        state.amount += increment;

        int numOne = additionOne();
        int numTwo = additionTwo();
        int answer = numOne + numTwo;

        String useranswerA = JOptionPane.showInputDialog(null, "Question #" + questionnum + " is for: $" + increment + "\n" + numOne + " + " + numTwo + " = ?", "Question", JOptionPane.INFORMATION_MESSAGE);
        int useranswer = Integer.parseInt(useranswerA);

        if (useranswer != answer) {
            wrong++;
            showInformationMessage("You got the wrong answer! \n The correct answer is: " + answer + " \n Questions Wrong: " + wrong, "Wrong Answer");
            askForCashOut(state.amount);
        } else if (useranswer == answer) {
            showInformationMessage("Correct!", "Right Answer");
            askForCashOut(state.amount);
        }
    }
}

public static int additionOne() {
    int x = (int) (Math.random() * 30);
    return x;
}

public static int additionTwo() {
    int x = (int) (Math.random() * 30);
    return x;
}

public static int numThree() {
    int x = (int) (Math.random() * 15);
    return x;
}

private static void askForCashOut(int amount) throws HeadlessException {
    if (askYesNo("Cash Out?", "CASH OUT with a total of $" + amount + "?")) {
        showInformationMessage("Thanks for Playing!", "Thank You!");
        System.exit(0);
    }
}

private static void showYesNoCancelDialogWithFollowUp(String title, String text, DialogOption yes, DialogOption no, DialogOption cancel) {
    DialogOption[] options = new DialogOption[]{yes, no, cancel};
    int n = JOptionPane.showOptionDialog(null, text, title, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
    options[n].dialog.show();
}

private static void showYesNoDialogWithFollowUp(String title, String text, InformationDialog afterYes, InformationDialog afterNo) {
    if (askYesNo(text, title)) {
        afterYes.show();
    } else {
        afterNo.show();
    }
}
private static final String[] YES_NO_OPTIONS = new String[]{"Yes Please", "Nope! I'm good!"};

private static boolean askYesNo(String text, String title) throws HeadlessException {
    int n = JOptionPane.showOptionDialog(null, text, title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, YES_NO_OPTIONS, YES_NO_OPTIONS[0]);
    return n == JOptionPane.YES_OPTION;
}

private static void showInformationMessage(String text, String title) throws HeadlessException {
    JOptionPane.showMessageDialog(null, text, title, JOptionPane.INFORMATION_MESSAGE);
}

static class InformationDialog {

    private String text;
    private String title;

    public InformationDialog(String text, String title) {
        this.text = text;
        this.title = title;
    }

    public void show() {
        showInformationMessage(text, title);
    }
}

static class DialogOption {

    String text;
    InformationDialog dialog;

    public DialogOption(String text, InformationDialog dialog) {
        this.text = text;
        this.dialog = dialog;
    }

    @Override
    public String toString() {
        return text;
    }
}

}

Panu
  • 362
  • 3
  • 13