Wierd Compiler Error

Hey guys, I’ve got this little chunk of code I’m working on, and as far as I can tell it should work… but Eclipse reports a major compiler error from it for some reason.


private int combatOptionsCount = 0;
	String[] combatOptions =  new String[5];
	combatOptions[combatOptionsCount] = "Tackle it!";
	combatOptionsCount++;
	combatOptions[combatOptionsCount] = "Throw something!";
	combatOptionsCount++;
	//Keep to this format and it should all work out.


It says: “Syntax error on token “;”, { expected after this token”
for the third line down, but I have no idea why it would need that, it’s not a function, or the start of a block, just a declaration. Does anyone have an idea what’s going on here?

The syntax error is clearly not in the code you provided. Please post the full class.

Unfortunately the full class would be a little tricky to post as it’s over 5000 lines long (a lot of string literals). Still this might help, here, starting with line 3, is the entire region Eclipse underlined in red (ending at “public int getLargestChoice() {”):

	
	private int combatOptionsCount = 0;
	String[] combatOptions =  new String[5];
	combatOptions[combatOptionsCount] = "Tackle it!";
	combatOptionsCount++;
	combatOptions[combatOptionsCount] = "Throw something!";
	combatOptionsCount++;
	//Keep to this format and it should all work out.
	
	
	// Calls the method based on scene, also sets input to the passed parameter
	public String returnNewText(int currentInput) {
		input = currentInput;
		String newText = "";
		if (scene == 1) {
			newText = this.scene1();
		}
		if (scene == 2) {
			newText = this.scene2();
		}
		if (scene == 3) {
			newText = this.scene3();
		}
		if (scene == 4) {
			newText = this.scene4();
		}
		if (scene == 5) {
			newText = this.scene5();
		}
		if (scene == 6) {
			newText = this.scene6();
		}
		if (scene == 7) {
			newText = this.scene7();
		}
		if (scene == 8) {
			newText = this.scene8();
		}
		if (scene == 9) {
			newText = this.scene9();
		}
		if (scene == 10) {
			newText = this.scene10();
		}
		return newText;
	}

	// returns the largest choice based on how the int variable, largestChoice,
	// is modified
	public int getLargestChoice() {
		return largestChoice;
	}

you can’t have that code outside of a method block / static block / instance block (of whatever the name is).


class X
{
   private int combatOptionsCount = 0;
   String[] combatOptions =  new String[5];

+ { // it's like a static block, without the static part >_>
     combatOptions[combatOptionsCount] = "Tackle it!";
     combatOptionsCount++;
     combatOptions[combatOptionsCount] = "Throw something!";
     combatOptionsCount++;
+ }


}

Urgh! Break up your code into logical chunks, otherwise you’ll only be facing more and more nasties like this.

That code doesn’t make any sense:

  • the first line is (presumably) a class member since it’s declared as private.
  • the second line may or may not be a class member or a local variable, hard to tell (as previous posters says) without seeing the structure of the class.
  • the following lines appear to be statements that ought to be inside a method, so it’s no wonder the compiler doesn’t like it.

But I’ll re-iterate the point about the class, 5000 lines would have you sacked as a professional ;), break up the code as best as possible and therefore you only have to deal with smaller chunks that are easier to maintain, clearer to understand and simpler to fix when broke.

  • stride

It’s code for a text adventure. The problem is ascii art and String literals. When you have code like this:


		// image for the Clinic
		if (room == 1) {
			newText = newText + "CLINIC\n"
					+ "00000000_____000000000000000000000000000000000\n"
					+ "0       DOOR            U()U       |         0\n"
					+ "0                      WASH BASIN  |         0\n"
					+ "0                                  |CABINET  0\n";
			if (ura == 1) {
				newText = newText
						+ "0                     (URA)        |         0\n";
			} else if (ura != 1) {
				newText = newText
						+ "0                                  |         0\n";
			}
			newText = newText
					+ "0                                  ----------0\n"
					+ "0                                            0\n"
					+ "0                                            0\n";
			if (blueBlood == 1) {
				newText = newText
						+ "0                (BLUEBLOOD)                 0\n";
			} else {
				newText = newText
						+ "0                                            0\n";
			}
			newText = newText
					+ "0                                            0\n";
			if (hardKnock == 1) {
				newText = newText
						+ "0-------        --------      (HARD KNOCK)   0\n";
			} else {
				newText = newText
						+ "0-------        --------                     0\n";
			}
			newText = newText
					+ "0      |        |      |                     |\n";
			if (wind == 1) {
				newText = newText
						+ "0 YOUR | (WIND) |      |                 DOOR|\n";
			} else {
				newText = newText
						+ "0 YOUR |        |      |                 DOOR|\n";
			}
			newText = newText
					+ "0 COT  |        | COT  |                     |\n"
					+ "0      |        |      |                     0\n"
					+ "0      |        |      |                     0\n"
					+ "0000000000000000000000000000000000000000000000\n\n";
			newText = newText
					+ "You find yourself in a tidy, if somewhat bare clinic.\n"
					+ "It has a large medical cabinet and a wash basin with some \n"
					+ "sort of drain.\n";
			if (wind == 1) {
				newText = newText
						+ "A certain yellow earth pony mare in an orange vest\n"
						+ "resides here.\n\n";
			}

or this:


case 2:
		newText = newText
				+ "PEGASUS\n"
				+ "..................~()~()......\n"
				+ "..................(~000000............\n"
				+ "..............(~0/    _    ............\n"
				+ ".............(~0/     Q     __.....\n"
				+ "............(~0/             _D........\n"
				+ "...........(~0/             ___/.........\n"
				+ "..........(~0/          __/...................\n"
				+ "____________/           /.........................\n"
				+ "|||||||||>>             |..........................\n"
				+ "|||||||||>>             |...........................\n"
				+ "|||||||||>              |..........................\n"
				+ "|||||||||               |..........................\n"
				+ "|||||||||               |.........................\n"
				+ "|||||||||               .......................\n"
				+ "|||||||||                .......................\n"
				+ "|||||||||     |_____      .......................\n"
				+ "--------|     |......     ......................\n"
				+ "........|     |.......      .........................\n\n";
		break;

controlling your line count becomes a bit difficult. I swear I’m doing my best to break it up into methods at least, but there’s only so much I can do.

The array was not declared private simply because I removed the modifier to check if that was what was causing the bug. It was a blind grab I know, but I was comparing it to some copy pasted code.

But there’s something key I’m missing here, I feel like all I did there was declare a variable and modify it. What’s special about arrays that stops me from doing to them the same things that I do to ints and booleans?

Fair enough, but strongly suggest you investigate using files to store the character data and load them into classes representing the rooms, descriptions, etc. in your game. It will certainly be a whole load easier to edit text files than Java code.

[quote]The array was not declared private simply because I removed the modifier to check if that was what was causing the bug. It was a blind grab I know, but I was comparing it to some copy pasted code.

But there’s something key I’m missing here, I feel like all I did there was declare a variable and modify it. What’s special about arrays that stops me from doing to them the same things that I do to ints and booleans?
[/quote]
See the previous couple of posts, that code needs to be inside a method.

You can’t place statements inside the main class body which is what you are trying to do.


// these are statements, not declarations
   combatOptions[combatOptionsCount] = "Tackle it!";
   combatOptionsCount++;
   combatOptions[combatOptionsCount] = "Throw something!";
   combatOptionsCount++;

As Riven said, use an initializer block. You can read about them here.

Wow, good stuff to know. Thanks for the help!

You can also condense that statement down. (if you feel you need to)

combatOptions[combatOptionsCount++] = "Tackle it!";
combatOptions[combatOptionsCount++] = "Throw something!";

W00t. Oh god.

You said it’s ascii art, right?
It’s like if game programmers would start to define each color of each texture’s pixel in code. That’d be crazy.
So what do they do? They create image files. Mostly .png or a similar image saving format.

Now you have strings, not images. How’d you do that? Well, there are .txt files :wink:

So let’s imagine you have a method called [icode]readTextFromFile(File)[/icode], then you could simply do this:


// somewhere in initializer:
pegasus = readTextFromFile(new File("asciiart/pegasus.txt"));
// You can now simply use that pegasus here:
newText = newText + pegasus;
// That's it.

Problem. We haven’t got / implemented the method [icode]readTextFromFile[/icode] yet. I’ll give one implementation I wrote (a long time ago):


public static String readTextFromFile(File file) throws IOException {
    // opens the file and creates a readable stream of data:
    return readText(new FileInputStream(file));
}

public static String readText(InputStream stream) throws IOException {
    // Creates a Reader that can read an inputStream line by line:
    BufferedReader read = new BufferedReader(new InputStreamReader(stream));
    // Using a Stringbuilder we concatenate the individual lines
    // We could also use a String, but concatenating strings (with '+') is slower than with StringBuilders
    StringBuilder str = new StringBuilder();
    String line;
    // When the BufferedReader can't find any more lines, he returns 'null' instead of a line
    // While that's not the case we append the read line to our StringBuilder together with a line-break "\n"
    while ((line = read.readLine()) != null) {
        str.append(line + "\n");
    }
    // And in the end the together catenated lines are returned (as String, not StringBuilder!)
    return str.toString();
}

That should be it :slight_smile:

It’s not perfect, but it’s an improvement!

Note, you wouldn’t need the \n loading from a text file.

You do.

I just tested it. I’m pretty sure. If you can spot a mistake, please tell me:


package org.matheusdev;

import java.io.*;

/**
 * Created with IntelliJ IDEA.
 * Author: matheusdev
 * Date: 3/10/13
 * Time: 8:52 PM
 */
public class Main {

    public static void main(String... args) {
	    try {
	        System.out.println(readTextFromFile(new File("testfile.txt")));
	    } catch (IOException e) {
		    e.printStackTrace();
	    }
    }

	public static String readTextFromFile(File file) throws IOException {
		// opens the file and creates a readable stream of data:
		return readText(new FileInputStream(file));
	}

	public static String readText(InputStream stream) throws IOException {
		// Creates a Reader that can read an inputStream line by line:
		BufferedReader read = new BufferedReader(new InputStreamReader(stream));
		// Using a Stringbuilder we concatenate the individual lines
		// We could also use a String, but concatenating strings (with '+') is slower than with StringBuilders
		StringBuilder str = new StringBuilder();
		String line;
		// When the BufferedReader can't find any more lines, he returns 'null' instead of a line
		// While that's not the case we append the read line to our StringBuilder together with a line-break "\n"
		while ((line = read.readLine()) != null) {
			str.append(line + "\n");
		}
		// And in the end the together catenated lines are returned (as String, not StringBuilder!)
		return str.toString();
	}
}

The file content:

The output:

Oh, I meant in the file, sorry.

or do => [icode]String text = new String(Files.readAllBytes(Paths.get(“pegasus.txt”)), StandardCharsets.UTF_8);[/icode]