This site requires JavaScript, please enable it in your browser!
Greenfoot back
student101
student101 wrote ...

2013/1/21

Reading questions from file

student101 student101

2013/1/21

#
Hi, I'm wondering if it's able to read questions (for my math game) from a file and the game displays it? There is a battle scene where the player gets asked maths question by an enemy and the player answers via multiple choice (another issue that I'm struggling on but I'll think about that later). I've searched around on google and came across the FileReader command in the java.io library but I'm confused on how to use it? This is what I have so far:
public void ReadQuestions() throws Exception
{
     String file = "Questions.txt";
     String line;
        while((line = in.readLine()) !=null)
            System.out.println(line);
    
}
Of course I'm also worried about whether reading questions from a file is actually a good idea. I'm wondering if it's better if I just store the questions (and answers) into the game itself.
Gevater_Tod4711 Gevater_Tod4711

2013/1/21

#
To read the text of a .txt file you can also use a BufferedReader. I like this reader better because it has got more methods and is faster if you got large texts (that will probably not be the case here). To use the BufferedReader you first have to import some classes from java.io
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.FileNotFoundException;
Then you can read the lines of the file like this:
try {
    String input;
    BufferedReader file = new BufferedReader(new FileReader("filename.txt"));
    while ((input = file.readLine()) != null) {
        System.out.println(input);//or whatever you want to do with the string;
    }
}
catch (FileNotFoundException fnfe) {//always catch the more specific Exceptions first; otherwhile the FileNotFoundException will be catched as a IOException because it's a subclass of IOException;
    //fnfe.printStackTrace();
    //Also you can add any other code you want to execute if the file is not found;
}
catch (IOException ioe) {
    //ioe.printStackTrace();
}
moobe moobe

2013/1/21

#
Greenfoot can display text, too. Wouldn't that be easier?
danpost danpost

2013/1/21

#
You could create an abstract class called 'Questions' and have a String array of the questions, choices and answers in it. Then, all you need to do is create an object of the class and retrieve the questions from it.
public class QnA
{
    String[][] data = 
    {
        { "Is this the first question?", "A", "Always", "Usually", "Sometimes", "Never" }, 
        { "Is this the final question?", "D", "Yes", "Possibly", "No", "Cannot tell" },
        // etc.
    }

    public String getQuestion(int qNum)
    {
        if(qNum<0 || qNum>=data.length) return "";
        return data[qNum][0];
    }

    public String getAnswer(int qNum)
    {
        if(qNum<0 || qNum>=data.length) return "";
        return data[qNum][1];
    }

    public String[] getChoices(int qNum)
    {
        if(qNum<0 || qNum>=data.length) return (new String[0]);
        int choiceCount=data[qNum].length-2;
        String[] choices=new String[choiceCount];
        System.arraycopy(data[qNum], 2, choices, 0, choiceCount);
        return choices;
    }

    public String getChoice(int qNum, int choiceNum)
    {
        if(qNum<0 || qNum>=data.length) return "";
        int choiceCount=data[qNum].length-2;
        if(choiceNum<0 || choiceNum>=choiceCount) return "";
        return data[qNum][choiceNum+2];
    }
 }
Whenever data is returned from the class, there is a possibility that the String returned will be empty. This will happen when any given value is out of range and this can be check for to indicate end of data. Remember counting starts at zero in Java, so I made it so with getChoice(qNum, choiceNum), the first choice is returned with choiceNum equal to zero; the second when equal to one; etc. Again, check for the return being an empty string to indicate no more choices.
student101 student101

2013/1/21

#
Thanks for your replies guys. I've decided to use Gevater's code because it fits with the plan I made earlier for this project I'm doing. I'm still trying to figure out your code danpost, but I'm liking the look of it nonetheless. I ran the code and it did what I wanted, which is to read from the file and give an output. The problem is that the reader just spams the contents of the file in another window? How do I make it so that it simply waits for the user's input?
danpost danpost

2013/1/21

#
You will have to keep track whether or not you are in wait mode for user input. You can use a boolean called 'waiting'. The act method should do the following: Check waiting; if not waiting, print the question (with choices), and change waiting to true; ELSE (if waiting was true), if 'getKey' returns null, do nothing, else compare key returned to the answer, print results, increment the question counter and change waiting to false.
student101 student101

2013/1/23

#
I'm wondering how I would make the code do nothing? Because I can do the getKey part but what would be the doing nothing part? Because I doing nothing would mean (i think) that the code stops reading from the file, but how would I make it stop reading?
public void ReadQuestion()
    {
       try {  
        String input;  
        BufferedReader file = new BufferedReader(new FileReader("Questions.txt"));  
        while ((input = file.readLine()) != null) {  
            System.out.println(input)
          if (Greenfoot.getKey()) = null


        }  
    }  
I don't even think the null part is correct. But that's all I could think of so far.
student101 student101

2013/1/23

#
sorry i forgot to add a line:
public void ReadQuestion()  
    {  
       try {    
        String input;    
        BufferedReader file = new BufferedReader(new FileReader("Questions.txt"));    
        while ((input = file.readLine()) != null) {    
            System.out.println(input)  
          if (Greenfoot.getKey()) = null  
          wait;
        
                      
  
  
        }    
    }  
student101 student101

2013/1/23

#
I updated the code however it keeps giving saying there's a try without a 'catch' or 'finally'
  public void ReadQuestion()
    {
       BufferedReader bufferedReader = null; 
       
       try {  
         bufferedReader = new BufferedReader(new FileReader("Questions.txt"));
   
        String line = null;
        while ((line = bufferedReader.readLine()) != null)
            System.out.println(line);
          
            //or whatever you want to do with the string;  
        }  
       
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            //Close the BufferedReader
            try {
                if (bufferedReader != null)
                    bufferedReader.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main().readFromFile("Questions.txt");
    }
}
Gevater_Tod4711 Gevater_Tod4711

2013/1/23

#
You are closing the first try block two times. If you delete line 13 it should work.
danpost danpost

2013/1/23

#
What I meant by doing nothing was basically to exit the method without processing a key because there is not yet a key to process (in other words, 'continue waiting'; but this involves more act cycles). What I could have said was "if 'key' is NOT null, compare it to the answer, print results, increment the question counter and change waiting to false." My frame of mind was to use 'if (key==null) return;' followed by the comparing.
student101 student101

2013/1/23

#
I decided to go back to the earlier code I was working on because the new one I had was too complicated for me to understand. I amended it with parts of the new code but it's still not working.
import greenfoot.*;  
import java.io.FileReader;  
import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.FileNotFoundException; 
// (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class BattleSnake here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class BattleSnake extends Snake
{
    /**
     * Act - do whatever the BattleSnake wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        ReadQuestion();
    }    
    
    public void ReadQuestion()
    {
        BufferedReader bufferedReader = null;
        String line = null;
        try {  
        String input;  
        BufferedReader file = new BufferedReader(new FileReader("Questions.txt"));  
        while ((input = file.readLine()) != null) 
        {  
            while ((line = bufferedReader.readLine()) != null)
            System.out.println(input);//or whatever you want to do with the string;  
        }  
    }  
    catch (FileNotFoundException fnfe) 
        {
        //always catch the more specific Exceptions first; otherwhile the FileNotFoundException will be catched as a IOException because it's a subclass of IOException;  
        //fnfe.printStackTrace();  
        //Also you can add any other code you want to execute if the file is not found;  
    }  
    catch (IOException ioe) 
    {  
        //ioe.printStackTrace();  
    }  
    
    }
}
danpost danpost

2013/1/23

#
public void ReadQuestion()  
{  
   try {    
    String input;    
    BufferedReader file = new BufferedReader(new FileReader("Questions.txt"));    
    while ((input = file.readLine()) != null) {    
        System.out.println(input)  
      if (Greenfoot.getKey()) = null  
      wait;

     }    
}
If you are going to use a file to read the questions in from, you should read them all in at once and put them in an array. The way you have it written above, the file will be opened and closed many times, which is unneccessary. For the 'getKey' part, you should never use 'if (Greenfoot.getKey()==null)' if you need to know what key was used. The reason being, once you execute the 'getKey' method and it returns a valid key, any subsequent calls will return 'null' until another key is pressed and released. That means that there is no code you could use after that line to retrieve what key was used. Therefore we need to retain the value returned as follows:
String key = Greenfoot.getKey(); //retaining key
if (key != null)
{
    if (key.equals(data[questionNum][answerIndex])  // sample condition for comparing
student101 student101

2013/1/23

#
Sorry danpost I missed your post earlier. I'm still trying to get my head around the array thing. I mean, I understand importing the contents of the text file into an array (I have no idea how to do that haha). I'm guessing that I would have to do the same thing if I wanted to do a Answers.txt file and then I would do a comparison with what the user inputs with the contents of the array.
danpost danpost

2013/1/23

#
Did you miss my abstract 'QnA' class posting of 2 days ago, also? If you look over the code, maybe you can get a better idea of how arrays work. A simple array is returned from the 'getChoices' method and is called from a statement something like the following:
// instance fields in the world
int questionNumber;
QnA qna=new QnA(); // the object holding all the data
// within the code
String[] choices=qna.getChoices(questionNumber);
This will create a simple array, or list, if you will, of choices. 'choices' is the first choice, 'choices' is the second, and so on, basically resulting in: String choices={ "Always", "Usually", "Sometimes", "Never" }; The double array 'String' just means you have a list of more than one simple array. It could be looked at as the following, which creates a list of the list of choices for all the questions String allChoices = { getChoices(0), getChoices(1), etc. }; It is an array of arrays. Anyway with the abstract class as it is given, you do not even have to worry about learning all about it. The methods provided -- 'getQuestion(questionNumber)', 'getAnswer(questionNumber)' and 'getChoice(questionNumber, choiceNumber)' -- allow easy access to all the data without ever using an array yourself (other than plugging your data into the data array at the top of the class; which would involve just following the format: { question, answer, choiceA, choiceB, choiceC, etc.] }.
You need to login to post a reply.