Saving Game Scores - java

i am trying to make a highscore for a hangman game. So i need to save it so it doesnt restart everytime u start the game or return to the menu.. so I have a playstate that records the wins and losses at the end of the game and if the user leaves before solving it adds a loss. I found a tutorial to save via a SavaData file.. the problem is it saves an empty file nothing in there but has 2 empty lines.. and so i get a numberformatexception null.. i had it working before but it still would not read the line and would return an error numberformatexception Integer.parseInt.. I know the problem is in reading lines and now i dont know what went wrong please help me .. whats wrong with the code?? thanx
this is the saving code...
private void createSaveData() {
File file = new File(saveDataPath, filename);
try {
FileWriter output = new FileWriter(file);
BufferedWriter writer = new BufferedWriter(output);
writer.write("" + 0);
writer.newLine();
writer.write("" + 0);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setScores() {
FileWriter output = null;
try {
File F = new File(saveDataPath, filename);
output = new FileWriter(F);
BufferedWriter writer = new BufferedWriter(output);
writer.write(wins);
writer.newLine();
writer.write(losses);
writer.close();
}catch (Exception e){
e.printStackTrace();
}
}
private void loadScores() {
try {
File F = new File(saveDataPath, filename);
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(F)));
String line = reader.readLine();
line = reader.readLine();
wins = Integer.parseInt(line);
line = reader.readLine();
losses = Integer.parseInt(line);
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
i then add loadScore(); at the begging of the playstate.. and setScore(); after a win++ or a loss++..
i have another highscorestate that calls on playstate and gets the wins and lossess as an integer and that works no problems cause it draws 0 , 0 .
in my render method i have this if the tries are too much or if the correct answer is guessed...
if (tries == 6) {
currentWord = ranWord;
execcurrentframe.setRegion(eman.ExecLoss.getKeyFrame(elapsedTime, false));
hangcurrentframe.setRegion(hman.hangdead.getKeyFrame(elapsedTime, false));
Wordsfont.draw(batch, "Game Over", eman.getPosition().x + 60, hman.getPosition().y + 70);
batch.draw(fu, 160, 510);
if (leverpressed == false){
bksound.stop();
lever.play();
leverpressed = true;
}
if (lossrecorded == false) {
losses += 1;
System.out.print("Losses = " + losses);
setScores();
lossrecorded = true;
}
}
else if (CorrectAnswer == true) {
hangcurrentframe.setRegion(hman.hangwin.getKeyFrame(elapsedTime, false));
Wordsfont.draw(batch, "You Won", eman.getPosition().x + 60, hman.getPosition().y + 70);
if (winrecorded == false) {
bksound.stop();
victory.play();
wins += 1;
System.out.print("Wins = " + wins);
setScores();
winrecorded = true;
}
}

I would suggest the following changes.
Use a single writeSaveData method. The code between createSaveData and setScores is largely duplicated. Also, use the Integer.toString() to write the output. Also, ensure the stream is closed (here using try with resources).
private void writeSaveData(int wins, int losses)
{
File file = new File(saveDataPath, filename);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write(Integer.toString(wins));
writer.newLine();
writer.write(Integer.toString(losses));
}
catch (Exception e) {
e.printStackTrace();
}
}
There is an extra readLine() in the loadScores() method. Remove that extra line. Change to use try with resources.
private void loadScores()
{
File file = new File(saveDataPath, filename);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
String line = reader.readLine();
// line = reader.readLine() <-- REMOVE THIS LINE
wins = Integer.parseInt(line);
line = reader.readLine();
losses = Integer.parseInt(line);
reader.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
EDIT: If one cannot use try with resources, then the following approach may be used instead.
private void loadScores()
{
File file = new File(saveDataPath, filename);
BufferedReader reader = null;
// try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = reader.readLine();
wins = Integer.parseInt(line);
line = reader.readLine();
losses = Integer.parseInt(line);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (reader != null) {
try {
reader.close();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
A similar modification may be made to the suggested writeSaveData() or other methods.

You have overlooked one important part of the original createSaveData method:
writer.write("" + 0);
See that "" + 0? It effectively converts the integer to a string (though there are more elegant ways of doing this).
BufferedWriter has overloaded write method. This means there is a different method that is called when the parameter is a String, and a different one when the parameter is an int.
You have called the version whose parameter is an int. Its documentation says:
public void write(int c) throws IOException
Writes a single character.
Overrides:
write in class Writer
Parameters:
c - int specifying a character to be
written
Throws:
IOException - If an I/O error occurs
This tells you that it considers the int that you passed as a character. That is, if you give it the int 65, it will be taken as the character A. If you give it the int 48, it will be taken as the character 0.
If you give it the integer 0, this is the NUL control character.
When you read that back as a string, it is taken as a single-character string containing the NUL character. Of course, that's not a valid string format for a number.
So replace
writer.write(wins);
With
writer.write(String.valueOf(wins));
And do the same for losses.

Related

How to make characters in Eclipse txt file visible?

I have a txt file "HighScoreList.txt" in my project.
The Problem is that there must be characters on that file, but when I open it in Eclipse, its empty. Removing it from eclipse and opening it with notepad removes all characters from that file.
My method writes on that file.
public void registerHighScore(Player p) {
int score = p.getScore();
String name = p.getName();
{
currentHighScores.add("X. "+name+" - "+score); //place doesnt matter as the actual place gets determined in formatHList
formatHList();
}
try {
BufferedWriter writer = new BufferedWriter(
new FileWriter(HighScoreManager.class.getResource("/highscore/HighScoreList.txt").getPath()));//persistancy
for (String s : currentHighScores) {
writer.write(s);
writer.newLine();
writer.flush();
}
writer.close();
} catch (IOException e) {
return;
}
}
I have checked that there must be characters in the textfile because
public ArrayList<String> getCurrentHighScores() {
ArrayList<String> result = new ArrayList<String>();
try {
BufferedReader bufferedReader = new BufferedReader(
new FileReader(HighScoreManager.class.getResource("/highscore/HighScoreList.txt").getPath()));
String line;
while ((line = bufferedReader.readLine()) != null) {
result.add(line);
}
bufferedReader.close();
return result;
} catch (IOException e) {
}
return null;
}
The ArrayList createt with that method actually contains Strings in the X. Name - Score format.

Read line n of a textfile in java then output result into an int

I am trying to write a program that will read line n of a provided text file, using a BufferedReader, and convert this line's contents into an int. This is the code I am currently using, but it fails to output an int:
BufferedReader reader = null;
int LineContent;
try {
File file = new File("C:\\Users\\Admin\\Desktop\\SAVEdata\\Save.txt");
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
LineContent = Integer.parseInt(line);
if (LineContent == 0) {
CHRSelectWorld w = new CHRSelectWorld();
Greenfoot.setWorld(w);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
You are trying to read and parse every line in your file. If you want nth line, you can use Files class
String line = Files.readAllLines(Paths.get("file.txt")).get(n);
It will work well for files of small-medium size.
long n = 42L;
Path path = Paths.get(
"C:\\Users\\Admin\\Desktop\\SAVEdata\\Save.txt");
Optional<String> line =
Files.lines(path, Charset.defaultCharset())
.skip(n - 1)
.findFirst();
if (line.isEmpty()) {
System.out.println("Insufficient lines, less than " + n);
}
System.out.println(line.orElse("(No line found)");
The class Files has many goodies, and with streams it is almost a one-liner.

Writing and reading int from file after loop

I'm writing an application that is supposed to act like a cafe clip card. In other words, for every n:th (10 in my case) coffee that a customer purchases, he/she is awarded a free beverage. So, I'm quite done with the loop and I've been working on writing and reading from a file since I need the program to remember where it last left off in order for the customer to be able to close the application once he/she has been in the store. However, I'm having a difficult time figuring out how to write and read from a file, the code I have doesn't seem to output any .txt file. I need the code to have a closing condition, and upon entering this condition, it should write the "count" to a .txt file, and shut down. Once the program is being run the next time it should read from this .txt file so it knows where the count is at.
Here's what I have so far:
public class FelixNeww {
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
entry = key.nextLine();
if(entry.compareTo(password) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
}
if(count == 10 && count != 0){
System.out.println("YOU'VE GOT A FREE COFFE!");
count = 0;
}
if(entry.compareTo(password) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
public void saveToFile(int count)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("countStorage.txt"))));
bw.write(count);
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bw != null)
{
try
{
bw.close();
}
catch(IOException e) {}
}
}
}
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(newInputStreamReader(newFileInputStream(new File("countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e) {}
}
}
return 0;
}
}
I see a few problems here. In your readFromFile() method, put a space after the keyword new. I also suggest putting a an absolute path for now (for debugging):
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
In your saveToFile() method, the constructor is wrong. Also put the full path to the file here:
bw = new BufferedWriter(new FileWriter("C:\\Temp\\countStorage.txt"));
Finally, in your saveToFile() method, write the count as a String. Writing it as an int refers to the Unicode character:
bw.write(Integer.toString(count)); //updated per Hunter McMillen
And invoke it...
FelixNeww f = new FelixNeww();
f.saveToFile(44);
System.out.println(f.readFromFile());
You need to invoke readFromFile or saveToFile in the place needed in order to become executed.
I suggest that you call readFromFile on the beginning of the Main method, use its returning contents, and saveToFile in the loop whenever the desired state changes and it needs to be saved.

Only prints out last line to the text file and not the rest in java

I am trying to print a file to the text file. Although I have managed to make it work, it only prints out the last line that is printed on the console. E.g. My console has around 8000 lines but it only prints out the last line in the text file, and I want to print all the lines into the text file.
This is the code:
try {
BufferedReader reader = new BufferedReader(new FileReader("JDT.txt"));
Writer output = null;
File file = new File("output.txt");
output = new BufferedWriter(new FileWriter(file));
String line = reader.readLine();
int count=0;
while(line !=null)
{
for(int i = 0 ; i<faults.length;i++){
if(line.contains(faults[i]))
System.out.println(line);
count++;
output.write(line +"Total: "+count);
//System.out.println("File Written");
}
line=reader.readLine();
}
System.out.println("Printed Lines =" +count);
output.close();
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
Thank you in advanced.
You are re-creating and overwriting your file in each loop. Create your file and your BufferedWriter before your loops, and close it after your loops finish.
You should place these lines before the beginning of the while loop.
Writer output = null;
File file = new File("output.txt");
output = new BufferedWriter(new FileWriter(file));
And close the Writer after while loop exits.
output.close();
Also the statement output.write(line +"Total: "+count); is trying to write every line at the end of another, resulting in one big line of output. Replace it with:
output.write(line + "Total: " + count + "\n");
This should result in each line getting printed on a new line.
Not sure if it's expected but in your code output.write might get executed multiple times for the same line depending on the length of your faults variable. This will result in same line getting printed more than once.
If the length of the faults is n the write will be called n times for the same line.
I think you need this:
while (line != null) {
for (int i = 0; i < faults.length; i++) {
if (line.contains(faults[i])) {
count++;
output.write(line + "Total: " + count + "\n");
System.out.println(line);
break;
}
}
// System.out.println("File Written");
line = reader.readLine();
}
I thought I'd put this here for reference. It's just a general approach for copying lines from an input file to an output file.
final class Sample
{
private static final String inputFile = "input_file.txt";
private static final String outputFile = "output_file.txt";
public void start()
{
BufferedReader bufferedReader;
BufferedWriter bufferedWriter;
try
{
bufferedReader = new BufferedReader(new FileReader(inputFile));
bufferedWriter = new BufferedWriter(new FileWriter(outputFile));
copyContents(bufferedReader, bufferedWriter);
bufferedReader.close();
bufferedWriter.close();
}
catch (final IOException e)
{
e.printStackTrace();
}
}
private void copyContents(final BufferedReader bufferedReader, final BufferedWriter bufferedWriter)
{
try
{
String line = bufferedReader.readLine();
while (null != line)
{
bufferedWriter.write(line + '\n');
line = bufferedReader.readLine();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}

Buffered Output Writing to File Wrong

I can't figure it out. I'm trying to write out text from my program. It's suppose to a word count program. Show me the number of lines, characters, word count. Then I display the results along with the word the user is searching for and that line.
(i.e. searching java)
line 5: the island of java contains Java
line 9: I love to drink java
It's not displaying text. Its displaying like heiroglyphics.
Line 2: DN{c�<���\$H�Uz�X����h4[����bA.�D��Ja�8^)|��k�ˠ����<Τ���QJ�����P˒��nI"�(��vc�Bi�"&�/�|qI�W6{pa�0��[���[M��;�FU�!}4�x�����{�-��(����V�k#�We֭Tʺ
Line 3: �N�U �������Ӣ ͇�?�
Line 4: Ӻ鬵�P��D<�}L>��o�V�Ex���Q|�)�'��g�I�B�3b�(�"3�T�7��� �=��s�g�F�;KN���r��_�� ʺ:�� �B�ۢ�s��sP����[6��; �� PK ! ��� N _rels/.rels �(�
public void readFromFile(String filename)
{
LineNumberReader lineNumberReader = null;
try {
lineNumberReader = new LineNumberReader(new FileReader(filename));
String line = null;
BufferedWriter output = new BufferedWriter(new FileWriter("output.txt"));
String ask = "Enter Word";
String find = JOptionPane.showInputDialog(ask);
Scanner scan = new Scanner(new File("test.txt"));
while ((line = lineNumberReader.readLine()) != null)
{
line = scan.nextLine();
if(line.indexOf(find) >= -1)
{
output.write("Line " + lineNumberReader.getLineNumber() +
": " + line);
output.newLine();
}
}// end of while
output.close();
} // end of try
catch (FileNotFoundException ex)
{
ex.printStackTrace();
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally {
try {
if (lineNumberReader != null)
{
lineNumberReader.close();
}
} // end of try
catch (IOException ex)
{
ex.printStackTrace();
}
}// end of finally
} // end of function
I don't get why you are doing this :
while ((line = lineNumberReader.readLine()) != null)
{
line = scan.nextLine();
if(line.indexOf(find) >= -1)
{
output.write("Line " + lineNumberReader.getLineNumber() +
": " + line);
output.newLine();
}
}// end of while
instead of this :
while ((line = lineNumberReader.readLine()) != null)
{
if(line.indexOf(find) >= -1)
{
output.write("Line " + lineNumberReader.getLineNumber() +
": " + line);
output.newLine();
}
}// end of while
You don't need 2 readers for this. And I don't understand why one of the reader is reading in a final file and the other one is reading from a file which name is coming from arg
The default OS encoding is used as set in System.getProperty("file.encoding").
You can explicitly pick one.
final String encoding = "UTF-16LE"; // Or "Cp1252" or "UTF-8"
lineNumberReader = new LineNumberReader(new InputStreamReader(new FileInputStream(filename), encoding));
...
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), encoding));
...
Scanner scan = new Scanner(new File("test.txt", encoding));

Categories

Resources