views:

286

answers:

3

Here's the relevant code:

public static String[] runTeams (String CPUcolor) 
{  
    boolean z = false ; 
    //String[] a = new String[6] ; 
    boolean CPU = false ; 
    while (z == false) 
    { 
        while (CPU==false) 
        {
            String[] a = assignTeams () ; 
            printOrder (a) ;

            for (int i = 1; i<a.length; i++) 
            { 
                if (a[i].equals(CPUcolor)) CPU = true ;
            }
            if (CPU==false) 
            {
                System.out.println ("ERROR YOU NEED TO INCLUDE THE COLOR OF THE CPU IN THE TURN ORDER") ; 
            }
        }
        System.out.println ("is this turn order correct? (Y/N)") ; 
        String s = getIns () ; 
        while (!((s.equals ("y")) || (s.equals ("Y")) || (s.equals ("n")) || (s.equals ("N")))) 
        {
            System.out.println ("try again") ; 
            s = getIns () ; 
        } 
        if (s.equals ("y") || s.equals ("Y") ) 
        z = true ; 
    } 
    return a ; 
}

the error i get is:

Risk.java:416: cannot find symbol
symbol  : variable a
location: class Risk
        return a ; 
               ^

Why did i get this error? It seems that a is clearly defined in the line String[] a = assignTeams () ; and if anything is used by the lineprintOrder (a) ;` it seems to me that if the symbol a really couldn't be found then the compiler should blow up there and not at the return statment.

(also the method assignTeams returns an array of Strings.)

+7  A: 

The variable a is defined within the scope of the while (CPU==false) loop -- it's not accessible outside of that while loop's scope. You need to define a inside the outermost scope (the same scope that the return statement is in). You can either keep the assignment where it is, or if it's possible, do it at the same time as definition.

public static String[] runTeams (String CPUcolor) 
{  
    boolean z = false ; 
    String[] a = null; // define a here, assign to null value
    boolean CPU = false ; 
    while (z == false) 
    { 
        while (CPU==false) 
        {
            a = assignTeams () ; // assign a here
            printOrder (a) ;

            for (int i = 1; i<a.length; i++) 
            { 
                if (a[i].equals(CPUcolor)) CPU = true ;
            }
            if (CPU==false) 
            {
                System.out.println ("ERROR YOU NEED TO INCLUDE THE COLOR OF THE CPU IN THE TURN ORDER") ; 
            }
        }
        System.out.println ("is this turn order correct? (Y/N)") ; 
        String s = getIns () ; 
        while (!((s.equals ("y")) || (s.equals ("Y")) || (s.equals ("n")) || (s.equals ("N")))) 
        {
            System.out.println ("try again") ; 
            s = getIns () ; 
        } 
        if (s.equals ("y") || s.equals ("Y") ) 
        z = true ; 
    } 
    return a ; 
}
Kaleb Brasee
That answers the question
Romain Hippeau
+2  A: 

JLS 14.4.2 Scope of Local Variable Declarations:

The scope of a local variable declaration in a block is the rest of the block in which the declaration appears, starting with its own initializer and including any further declarators to the right in the local variable declaration statement.

JLS 14.2 Blocks

A block is a sequence of statements, local class declarations and local variable declaration statements within braces.

The way you declared and initialized a, it's actually a local variable to the while (CPU==false) block, and it goes immediately out of scope at the end of that block.

Similar questions


It should also be pointed out that the habit of explicitly comparing with boolean constants is a bad one. That is, instead of:

while (z == false)
while (CPU==false) 
if (CPU==false) 

You should've used:

while (!z)
while (!CPU) 
if (!CPU) 

You can also rename the variables for better readability (isXXX is usually a good descriptive name), but the least you can do is to always do the following rewrites:

b == true  ---> b
b == false ---> !b
b != true  ---> !b
b != false ---> b

As a last tip, learning a bit of regex doesn't hurt. That is, instead of:

((s.equals ("y")) || (s.equals ("Y")) || (s.equals ("n")) || (s.equals ("N")))

You can simply write the following:

s.matches("y|Y|n|N")

Learning resources

polygenelubricants
Since when is comparing against booleans bad? `!v` will return true for many values of v other than `false`. That's not much of a problem with a strongly typed language, but comparing against booleans also tells more about the code.
Wallacoloo
Precisely because the intention in other languages aren't clear that Java decides to just simplify the treatment of `boolean`, where `!v` is `true` _only_ if `v` is `false`. It's much more consistent, concise, clear. It's better.
polygenelubricants
Concise is good. But `!0` isn't `true` in Java? Is it even legal code then? If it's illegal, then I suppose `if(!v)` *is* much better.
Wallacoloo
@wallacoloo: yes, `!0` is illegal in Java =) A wise decision on the designer's part.
polygenelubricants
A: 

These kind of problems are obviously solved with IDEs like Eclipse. Which IDE are you using?

Ram