import java.util.*; import java.io.*; public class jQuiz { static File source; QData qd; //static boolean addQ = false; can do without addQ? boolean moreQ = true; boolean mTime = true; static boolean keepOn = true; boolean rDone = false; //checks whether response is done in doQ() Console con = System.console(); Thread askAQ; int correct = 0; static int attempted = 0; int availQ; String seconds; int secs; Thread askIt; static String[] qAndA = new String[3]; String answer = ""; String question = ""; static boolean qDone = false; static boolean aDone = false; static boolean eDone = false; public static boolean OPEN_IN_ADD = false; String response = null; String input = ""; Scanner sc; BufferedReader userIn; ArrayList uInList = new ArrayList(); Thread UIn = new Thread () { public void run() { try { userIn = new BufferedReader(new InputStreamReader(System.in)); while (true) { uInList.add(userIn.readLine()); } }catch(IOException ioe) { System.err.println(ioe.getMessage()); } } }; jQuiz() { qd = new QData(source); if (qd.dbUp == false) { System.out.println("No database is present. Opening in ADD mode..."); OPEN_IN_ADD = true; } //duplicate code again...gah availQ = qd.getSize(); System.out.println("Total questions: " + availQ); } static List getDatFiles() { List datFiles = new ArrayList(); try { File datFile = null; File dir = new File("./"); String[] files = dir.list(); if (files.length == 0) return null; for (String file:files) if (file.indexOf(".jq") >=0) datFiles.add(new File(file)); }catch(Exception e) { System.err.println("Couldn't make a file: " + e.getMessage()); } return datFiles; } public static void main(String[] args) { String choice = "0"; //for the switch statement below... int fChoice = 0; List datFiles = getDatFiles(); if (datFiles != null) { System.out.println("\n*************************************************"); System.out.println(" WELCOME TO jQUIZ!"); System.out.println(""); for (int i=1;i<=datFiles.size();i++) System.out.println(i + ")" + datFiles.get(i-1).getName()); System.out.println("-------------------------------------------------"); Console cs = System.console(); String fileChoice = cs.readLine("Enter the number of the question file you wish to load: "); try { fChoice = Integer.parseInt(fileChoice); }catch(NumberFormatException nfe) { System.err.println("Choice not an integer: " + nfe.getMessage()); } source = datFiles.get(fChoice -1); } jQuiz jq = new jQuiz(); jq.qd.jq = jq; jq.UIn.start(); System.out.println("\n*************************************************"); if ((args.length > 0 && args[0].equalsIgnoreCase("add")) || OPEN_IN_ADD) jq.qd.addAQ(); //enter questions from the console while (jq.keepOn) { try { jq.doQ(); }catch(Exception e) { System.err.println(e.getMessage()); } System.out.println("Score: " + jq.correct + "/" + attempted); System.out.println("\n1)Quit\n2)More Questions\n3)Restart\nenter numerical choice:"); choice=null; jq.secs = 1;//tells getIn not to time input choice = jq.getIn(); choice = choice.trim(); int CHOICE = Integer.parseInt(choice); switch (CHOICE) { case 1: jq.keepOn = false; jq.moreQ = false; break; case 2: { jq.correct=0; attempted=0; jq.moreQ = true; jq.availQ = jq.qd.qNa.size(); jq.qd.asked = new ArrayList(); jq.keepOn = true; break; } case 3: { for(String theLine:jq.qd.asked) jq.qd.qNa.add(theLine); //took out 6/13 so only new questions after restart jq.correct=0; attempted=0; jq.moreQ = true; //jq.qd.qNa = jq.qd.data; //took this out: jq.moreQ = true; then put it back in! jq.availQ = jq.qd.qNa.size(); jq.qd.asked = new ArrayList(); jq.keepOn = true; } break; default: jq.keepOn = false; jq.moreQ = false; break; } } if (jq.qd.addedQ.size() > 0) { if (jq.qd.writeNew()) System.out.println(jq.qd.addedQ.size() + " questions added to database."); else System.out.println("Error writing new questions to database."); } System.out.println("Bye!"); //because the other thread, UIn, keeps blocking on standard in, I have to terminate //the program with system.exit(0); System.exit(0); } public synchronized String getIn() { String input = null; if (secs==1 || secs==0) { do { if (uInList.size() > 0) input = uInList.remove(uInList.size()-1); } while (input==null); } else { long time = 0l; long dTime = 0l; time = System.currentTimeMillis(); dTime = time + secs * 1000; do { if (uInList.size() > 0) input = uInList.remove(uInList.size()-1); time = System.currentTimeMillis(); } while (input==null && dTime > time); }//end else return input; } void doQ() { System.out.println("Open in 'add' mode by invoking jQuiz with 'add'"); System.out.println("as an argument. (ie java quiz.jQuiz add).\n"); System.out.println("Type only options presented in the question."); System.out.println("Type 'delete' to delete a question from the"); System.out.println("database.\n"); System.out.println("*************************************************"); while (moreQ && availQ >= 1) { qAndA = qd.getQ(); try { secs = Integer.parseInt(qAndA[2]); }catch(NumberFormatException nfe) { System.err.println("Bad number: you have 30 seconds."); secs = 30; } System.out.println("*************************************************"); System.out.println(++attempted + ")You have " + secs + " seconds for this question.\n"); availQ--; System.out.println(qAndA[0]); response = getIn(); if (response==null) { System.out.println("Time's up!"); System.out.println("\n\nThe correct answer was: "); System.out.println(qAndA[1]); System.out.println("\nHit to continue..."); secs = 0; getIn(); } else if (response.equalsIgnoreCase(qAndA[1])) { correct++; System.out.println("\n\nAnswer " + response + " is correct. \n\n"); response = null; } else if (!response.equalsIgnoreCase(qAndA[1]) && !response.equalsIgnoreCase("stop") && !response.equalsIgnoreCase("delete")) { System.out.println("\n\nIncorrect. The correct answer was " + qAndA[1] + "\n"); System.out.println("Your answer was " + response); response = null; } else if (response.indexOf("stop") >= 0) { moreQ = false; response = null; attempted--; } else if (response.equalsIgnoreCase("delete")) { qd.delQ = qAndA[0]; if (qd.doDel()) { System.out.println("Question deleted."); } else { System.out.println("Unable to delete question."); } } if (availQ==0) { System.out.println("You have completed all of the questions in the database!"); System.out.println("Open in ADD mode,choose Restart, or quit and open another database.\n"); } } //while end } //doQ (method) end } //class end class QData { ArrayList addedQ = new ArrayList(); ArrayList asked = new ArrayList(); ArrayList qNa = new ArrayList(); ArrayList data = new ArrayList(); String delQ = null; String line = ""; boolean dbUp = false; private int size; int rand = 0; String question = ""; String answer = ""; String nextBit = ""; public static final int SRC_ADD = 0; public static final int SRC_READ = 1; jQuiz jq; QData(File src) { try { readQ(new FileReader(src)); dbUp = true; size = qNa.size(); }catch(IOException ioe) { System.err.println("\n*************************************************"); System.err.println("File didn't open:" + ioe.getMessage()); } } public String[] getQ() { rand = (int)(Math.random()*size); String[] oneQ = new String[3]; asked.add(qNa.get(rand)); oneQ = qNa.get(rand).split("::"); qNa.remove(rand); size = qNa.size(); return oneQ; } public void addAQ() { String nBit = ""; System.out.println("Enter your question. Conclude with \'::\' on a new line."); System.out.println("Follow that line with your answer. When your answer"); System.out.println("is complete, add a line with \'??\' to complete your answer."); System.out.println("Put the number of seconds for the question on the next"); System.out.println("line to complete your entry.\n"); while (true) { nBit = jq.getIn(); //nBit = nBit.trim(); if (nBit.indexOf("stop") >= 0) { break; } parseQLine(nBit,SRC_ADD); } } //THIS METHOD NOW SUPPOSED TO HANDLE THE LINE BY LINE PARSING OF QUESTIONS-- //FROM BOTH THE FILE AND STANDARD IN public void parseQLine(String nextBit,int src) { if (nextBit.indexOf("::")< 0 && !jQuiz.qDone) { if (question.length() > 0) question += "\n"; question = question + nextBit; } else if (nextBit.indexOf("::") >= 0) { //removed '&& !jQuiz.qDone' jQuiz.qAndA[0] = question; jQuiz.qDone = true; } else if (nextBit.indexOf("??") < 0 && jQuiz.qDone && !jQuiz.aDone) { //for multi-line answer support, which I don't need answer = nextBit; } else if (nextBit.indexOf("??") >= 0) { jQuiz.aDone = true; jQuiz.qAndA[1] = answer; } else if (nextBit.indexOf("??") < 0 && jQuiz.aDone) { jQuiz.aDone = false; jQuiz.qDone = false; jQuiz.qAndA[2] = nextBit; String qNa_entry = question + "::" + answer + "::" + nextBit; qNa.add(qNa_entry); if (src==SRC_ADD) //put whatever shows this is from system.in as boolean test addedQ.add(qNa_entry); question = ""; answer = ""; nextBit = ""; // jQuiz.eDone = true; //THIS IS NEW if (src==SRC_ADD) //put whatever shows this is from system.in as boolean test System.out.println("Enter another question, or stop."); } } public void readQ(FileReader fr) { //this method is now strictly for reading questions.jq String nBit = ""; Scanner sc = new Scanner(fr); sc.useDelimiter("\n"); while (sc.hasNext()) { nBit = sc.next(); //nBit = nBit.trim(); parseQLine(nBit,SRC_READ); } if (data.size()==0) data.addAll(qNa); } boolean doDel() { String dEntry = ""; jQuiz.attempted--; try { PrintWriter pw = new PrintWriter("temp.txt"); for (String theEntry:data) { String[] theQ = theEntry.split("::"); if (theQ[0].indexOf(delQ) < 0) { pw.write(theQ[0] + "\n::\n" + theQ[1] + "\n??\n" + theQ[2] + "\n"); } else dEntry = theEntry; //theQ[0] + "::" + theQ[1] + "::" + theQ[2] ; didn't need to do this formatting? } pw.close(); File file = new File("temp.txt"); File newFile = new File("questions.jq"); file.renameTo(newFile); }catch(IOException ioe) { System.err.println(ioe.getMessage()); return false; } delQ = null; return true; } boolean writeNew() { String printQ[] = new String[3]; try { //assumes program is invoked from java\classes... FileWriter fw = new FileWriter("questions.jq",true); for (String aLine:addedQ) { printQ = aLine.split("::"); fw.write(printQ[0] + "\n::\n" + printQ[1] + "\n??\n" + printQ[2] + "\n"); } fw.close(); }catch(IOException ioe) { System.err.println(ioe.getMessage()); return false; } return true; } public int getSize() { return size; } }