H3ll0 H3ll0 - 29 days ago 4
Android Question

Score not increasing after new random array variable is read (Java) - Android Studio

There's a game with 9 colored squared. A random one of those colors is displayed on the screen, in one of those 9 colors (e.g: 'orange' in green). The user scores a point when they tap the colored square which corresponds with the word, ignoring the color of the word (e.g if 'orange' in any color and orange square is tapped, one point is added to score). All these color strings are stored in an array (colorString[]). When the score reaches 10, I introduce new values to the colorString array in the onClick method of each button. The values are ciphered versions of each color string. The issue is, even when the right color boxed is tapped for the ciphered value, the score goes no higher than 10. The newer array values are not working. All is explained in the code below:

int score = 0;
Random colStr = new Random();
int decider = colStr.nextInt(9);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game3);



final Button loseStarter3;

loseStarter3 = (Button) findViewById(R.id.Starter3);
loseStarter3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
infoG3.setVisibility(View.GONE);
loseStarter3.setVisibility(View.GONE);
final TextView word = (TextView) findViewById(R.id.word);
word.setVisibility(View.VISIBLE);
greenButton.setVisibility(View.VISIBLE);
purpleButton.setVisibility(View.VISIBLE);
blueButton.setVisibility(View.VISIBLE);
blackButton.setVisibility(View.VISIBLE);
redButton.setVisibility(View.VISIBLE);
whiteButton.setVisibility(View.VISIBLE);
brownButton.setVisibility(View.VISIBLE);
orangeButton.setVisibility(View.VISIBLE);
yellowButton.setVisibility(View.VISIBLE);

final String[] colorString = new String[9];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
word.setText(colorString[decider]);

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);

yellowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (word.getText() == colorString[0] || word.getText() == colorString[9] || word.getText() == colorString[10] || word.getText() == colorString[11]) {
score++;
}
Random colStr = new Random();
if (score<=9) {
int decider = colStr.nextInt(9);
final String[] colorString = new String[9];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
word.setText(colorString[decider]);
}
if (score>9) {
int decider = colStr.nextInt(27)+9;
final String[] colorString = new String[36];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
colorString[9] = "weyoll";
colorString[10] = "loyelw";
colorString[11] = "oelwyl";
colorString[12] = "erd";
colorString[13] = "der";
colorString[14] = "edr";
colorString[15] = "enrge";
colorString[16] = "regne";
colorString[17] = "nerge";
colorString[18] = "lcbka";
colorString[19] = "alkcb";
colorString[20] = "cbakl";
colorString[21] = "ihewt";
colorString[22] = "thewi";
colorString[23] = "ewthi";
colorString[24] = "relppu";
colorString[25] = "ulrpep";
colorString[26] = "leprpu";
colorString[27] = "ebul";
colorString[28] = "lbeu";
colorString[29] = "ulbe";
colorString[30] = "rbwno";
colorString[31] = "wobnr";
colorString[32] = "onwrb";
colorString[33] = "agonre";
colorString[34] = "negrao";
colorString[35] = "greaon";
word.setText(colorString[decider]);
}

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);
}
});

redButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (word.getText() == colorString[1]) {
score++;
}
Random colStr = new Random();
if (score<=9) {
int decider = colStr.nextInt(9);
final String[] colorString = new String[9];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
word.setText(colorString[decider]);
}
if (score>9) {
int decider = colStr.nextInt(27) + 9;
final String[] colorString = new String[36];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
colorString[9] = "weyoll";
colorString[10] = "loyelw";
colorString[11] = "oelwyl";
colorString[12] = "erd";
colorString[13] = "der";
colorString[14] = "edr";
colorString[15] = "enrge";
colorString[16] = "regne";
colorString[17] = "nerge";
colorString[18] = "lcbka";
colorString[19] = "alkcb";
colorString[20] = "cbakl";
colorString[21] = "ihewt";
colorString[22] = "thewi";
colorString[23] = "ewthi";
colorString[24] = "relppu";
colorString[25] = "ulrpep";
colorString[26] = "leprpu";
colorString[27] = "ebul";
colorString[28] = "lbeu";
colorString[29] = "ulbe";
colorString[30] = "rbwno";
colorString[31] = "wobnr";
colorString[32] = "onwrb";
colorString[33] = "agonre";
colorString[34] = "negrao";
colorString[35] = "greaon";
word.setText(colorString[decider]);
}

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);
}
});

greenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (word.getText() == colorString[2]) {
score++;
}
Random colStr = new Random();
if (score<=9) {
int decider = colStr.nextInt(9);
final String[] colorString = new String[9];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
word.setText(colorString[decider]);
}
if (score>9) {
int decider = colStr.nextInt(27) + 9;
final String[] colorString = new String[36];
colorString[0] = "yellow";
colorString[1] = "red";
colorString[2] = "green";
colorString[3] = "black";
colorString[4] = "white";
colorString[5] = "purple";
colorString[6] = "blue";
colorString[7] = "brown";
colorString[8] = "orange";
colorString[9] = "weyoll";
colorString[10] = "loyelw";
colorString[11] = "oelwyl";
colorString[12] = "erd";
colorString[13] = "der";
colorString[14] = "edr";
colorString[15] = "enrge";
colorString[16] = "regne";
colorString[17] = "nerge";
colorString[18] = "lcbka";
colorString[19] = "alkcb";
colorString[20] = "cbakl";
colorString[21] = "ihewt";
colorString[22] = "thewi";
colorString[23] = "ewthi";
colorString[24] = "relppu";
colorString[25] = "ulrpep";
colorString[26] = "leprpu";
colorString[27] = "ebul";
colorString[28] = "lbeu";
colorString[29] = "ulbe";
colorString[30] = "rbwno";
colorString[31] = "wobnr";
colorString[32] = "onwrb";
colorString[33] = "agonre";
colorString[34] = "negrao";
colorString[35] = "greaon";
word.setText(colorString[decider]);
}

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);
}
});

/*etc... for other buttons, same contents but different color name*/


I AM AWARE THAT I HAVE ONLY USED || OTHER ARRAY VALUES FOR YELLOW, THIS IS JUST AN EXAMPLE. I have also tried using individual if statements below the colorString[0] one to add scores when == to the other values, and else if. Neither worked, they just crashed the app. I've also tried different button, not that is should make a difference. I tried changing the order of where the if statement is, only to fail again. I've spent a while trying to resolve this, but have unfortunately not been able to resolve this.

Would appreciate it if someone could provide me with a fix, to ensure these other array values are accepted. If there is something I haven't made clear, all is shown in the code I have posted. Many thanks in advance.

UPDATED CODE:

final String[] colorString1 = new String[9];
colorString1[0] = "yellow";
colorString1[1] = "red";
colorString1[2] = "green";
colorString1[3] = "black";
colorString1[4] = "white";
colorString1[5] = "purple";
colorString1[6] = "blue";
colorString1[7] = "brown";
colorString1[8] = "orange";
word.setText(colorString1[decider]);

final String[] colorString2 = new String[36];

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);

yellowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (word.getText().equals(colorString1[0])) {
score++;
}
if (word.getText().equals(colorString2[9])) {
score++;
}
if (word.getText().equals(colorString2[10])) {
score++;
}
if (word.getText().equals(colorString2[11])) {
score++;
}
Random colStr = new Random();
if (score<=9) {
int decider = colStr.nextInt(9);
final String[] colorString1 = new String[9];
colorString1[0] = "yellow";
colorString1[1] = "red";
colorString1[2] = "green";
colorString1[3] = "black";
colorString1[4] = "white";
colorString1[5] = "purple";
colorString1[6] = "blue";
colorString1[7] = "brown";
colorString1[8] = "orange";
word.setText(colorString1[decider]);
}
if (score>9) {
int decider = colStr.nextInt(27)+9;
final String[] colorString2 = new String[36];
colorString2[0] = "yellow";
colorString2[1] = "red";
colorString2[2] = "green";
colorString2[3] = "black";
colorString2[4] = "white";
colorString2[5] = "purple";
colorString2[6] = "blue";
colorString2[7] = "brown";
colorString2[8] = "orange";
colorString2[9] = "weyoll";
colorString2[10] = "loyelw";
colorString2[11] = "oelwyl";
colorString2[12] = "erd";
colorString2[13] = "der";
colorString2[14] = "edr";
colorString2[15] = "enrge";
colorString2[16] = "regne";
colorString2[17] = "nerge";
colorString2[18] = "lcbka";
colorString2[19] = "alkcb";
colorString2[20] = "cbakl";
colorString2[21] = "ihewt";
colorString2[22] = "thewi";
colorString2[23] = "ewthi";
colorString2[24] = "relppu";
colorString2[25] = "ulrpep";
colorString2[26] = "leprpu";
colorString2[27] = "ebul";
colorString2[28] = "lbeu";
colorString2[29] = "ulbe";
colorString2[30] = "rbwno";
colorString2[31] = "wobnr";
colorString2[32] = "onwrb";
colorString2[33] = "agonre";
colorString2[34] = "negrao";
colorString2[35] = "greaon";
word.setText(colorString2[decider]);
}

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);
}
});

redButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (word.getText() == colorString1[1]) {
score++;
}
Random colStr = new Random();
if (score<=9) {
int decider = colStr.nextInt(9);
final String[] colorString1 = new String[9];
colorString1[0] = "yellow";
colorString1[1] = "red";
colorString1[2] = "green";
colorString1[3] = "black";
colorString1[4] = "white";
colorString1[5] = "purple";
colorString1[6] = "blue";
colorString1[7] = "brown";
colorString1[8] = "orange";
word.setText(colorString1[decider]);
}
if (score>9) {
int decider = colStr.nextInt(27)+9;
final String[] colorString2 = new String[36];
colorString2[0] = "yellow";
colorString2[1] = "red";
colorString2[2] = "green";
colorString2[3] = "black";
colorString2[4] = "white";
colorString2[5] = "purple";
colorString2[6] = "blue";
colorString2[7] = "brown";
colorString2[8] = "orange";
colorString2[9] = "weyoll";
colorString2[10] = "loyelw";
colorString2[11] = "oelwyl";
colorString2[12] = "erd";
colorString2[13] = "der";
colorString2[14] = "edr";
colorString2[15] = "enrge";
colorString2[16] = "regne";
colorString2[17] = "nerge";
colorString2[18] = "lcbka";
colorString2[19] = "alkcb";
colorString2[20] = "cbakl";
colorString2[21] = "ihewt";
colorString2[22] = "thewi";
colorString2[23] = "ewthi";
colorString2[24] = "relppu";
colorString2[25] = "ulrpep";
colorString2[26] = "leprpu";
colorString2[27] = "ebul";
colorString2[28] = "lbeu";
colorString2[29] = "ulbe";
colorString2[30] = "rbwno";
colorString2[31] = "wobnr";
colorString2[32] = "onwrb";
colorString2[33] = "agonre";
colorString2[34] = "negrao";
colorString2[35] = "greaon";
word.setText(colorString2[decider]);
}

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);
}
});

greenButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (word.getText() == colorString1[2]) {
score++;
}
Random colStr = new Random();
if (score<=9) {
int decider = colStr.nextInt(9);
final String[] colorString1 = new String[9];
colorString1[0] = "yellow";
colorString1[1] = "red";
colorString1[2] = "green";
colorString1[3] = "black";
colorString1[4] = "white";
colorString1[5] = "purple";
colorString1[6] = "blue";
colorString1[7] = "brown";
colorString1[8] = "orange";
word.setText(colorString1[decider]);
}
if (score>9) {
int decider = colStr.nextInt(27)+9;
final String[] colorString2 = new String[36];
colorString2[0] = "yellow";
colorString2[1] = "red";
colorString2[2] = "green";
colorString2[3] = "black";
colorString2[4] = "white";
colorString2[5] = "purple";
colorString2[6] = "blue";
colorString2[7] = "brown";
colorString2[8] = "orange";
colorString2[9] = "weyoll";
colorString2[10] = "loyelw";
colorString2[11] = "oelwyl";
colorString2[12] = "erd";
colorString2[13] = "der";
colorString2[14] = "edr";
colorString2[15] = "enrge";
colorString2[16] = "regne";
colorString2[17] = "nerge";
colorString2[18] = "lcbka";
colorString2[19] = "alkcb";
colorString2[20] = "cbakl";
colorString2[21] = "ihewt";
colorString2[22] = "thewi";
colorString2[23] = "ewthi";
colorString2[24] = "relppu";
colorString2[25] = "ulrpep";
colorString2[26] = "leprpu";
colorString2[27] = "ebul";
colorString2[28] = "lbeu";
colorString2[29] = "ulbe";
colorString2[30] = "rbwno";
colorString2[31] = "wobnr";
colorString2[32] = "onwrb";
colorString2[33] = "agonre";
colorString2[34] = "negrao";
colorString2[35] = "greaon";
word.setText(colorString2[decider]);
}

int[] androidColors = getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);
}
});
/* same for other colored buttons */

Answer

If I strip down your code and change final String[] colorString declarations into colorString1, colorString2, colorString3, ... it looks like this:

...
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    loseStarter3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ...
            final String[] colorString1 = new String[9];
            ...
            yellowButton.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
                     if (word.getText().equals(colorString1[0]) ... ) {
                         score++;
                     }
                     Random colStr = new Random();
                     if (score<=9) {
                         final String[] colorString2 = new String[9];
                         ...
                     }
                     if (score>9) {
                         final String[] colorString3 = new String[36];
                         ...
                     }

So if yellowButton is clicked - with checks according to Zarki - it will check with word.getText().equals(colorString1[0]) which will never check on colorString3 with 36 entries.

There are multiple ways to solve this.

  • make colorString a member variable of the most outer class which is probably the activity in your case, it won't need to be final and can be set with string array (fast solution)
  • a good idea in general is to pull out all the duplicated array initializations into a separate class, it could have switchX methods to switch between 9 and 36 names like

    public class ColorField {
       private String[] colorString = new String[36];
       private int length = 9;
       public ColorField() {
         // init colorString
       }
    
       public void switchTo9() {
         this.length = 9;
       }
    
       public void switchTo36() {
         this.length = 36;
       }
    
       public int getLength() {
         return this.length;
       }
    
       public String getField(int idx) {
         // sanity checks omitted
         return colorString[idx];
       }
    
       // more stuff
    }
    

UPDATE:

Ok, your update is another possibility. Now you can remove the inner colorString since you have them in the outer closure already - that may not help against bugs, but it shortens code and makes it more readable. Notice how colorString1 is useless too, you could remove it completely and only use colorString2.

Anyway, I added some comments on what happens now in the code and some changes for the decider - removed the inner declaration too - and word setting.

// declare "colorString2"
final String[] colorString2 = new String[36];
// initialize with values
colorString2[0] = "yellow";
colorString2[1] = "red";
colorString2[2] = "green";
colorString2[3] = "black";
colorString2[4] = "white";
colorString2[5] = "purple";
colorString2[6] = "blue";
colorString2[7] = "brown";
colorString2[8] = "orange";
colorString2[9] = "weyoll";
colorString2[10] = "loyelw";
colorString2[11] = "oelwyl";
colorString2[12] = "erd";
colorString2[13] = "der";
colorString2[14] = "edr";
colorString2[15] = "enrge";
colorString2[16] = "regne";
colorString2[17] = "nerge";
colorString2[18] = "lcbka";
colorString2[19] = "alkcb";
colorString2[20] = "cbakl";
colorString2[21] = "ihewt";
colorString2[22] = "thewi";
colorString2[23] = "ewthi";
colorString2[24] = "relppu";
colorString2[25] = "ulrpep";
colorString2[26] = "leprpu";
colorString2[27] = "ebul";
colorString2[28] = "lbeu";
colorString2[29] = "ulbe";
colorString2[30] = "rbwno";
colorString2[31] = "wobnr";
colorString2[32] = "onwrb";
colorString2[33] = "agonre";
colorString2[34] = "negrao";
colorString2[35] = "greaon";

// select first color string to be used for as word
word.setText(colorString2[decider]);
// select first visual color to be used for word
int[] androidColors =getResources().getIntArray(R.array.androidcolors);
int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
word.setTextColor(randomAndroidColor);

// create click listener for yellow button
yellowButton.setOnClickListener(new View.OnClickListener() {
    @Override
        public void onClick(View v) {
            // on click, check if word color is matching
            // this buttons color and increase score
            if (word.getText().equals(colorString2[0])) {
                score++;
            }
            if (word.getText().equals(colorString2[9])) {
                score++;
            }
            if (word.getText().equals(colorString2[10])) {
                score++;
            }
            if (word.getText().equals(colorString2[11])) {
                score++;
            }
            // select new color string with difficulty level
            // depending on score
            Random colStr = new Random();
            if (score<=9) {
                decider = colStr.nextInt(9);
            }
            if (score>9) {
                decider = colStr.nextInt(27)+9;
            }
            word.setText(colorString2[decider]);
            // set new visual color
            int[] androidColors = getResources().getIntArray(R.array.androidcolors);
            int randomAndroidColor = androidColors[new Random().nextInt(androidColors.length)];
            word.setTextColor(randomAndroidColor);
        }
    });

/* same for other colored buttons */

IN DEPTH EXPLANATION:

For the beginning, since I don't know on which knowledge level you are, I'll clear up some Words - very short and only in Java context - with references so you can find much more information if needed.

(Variable) Declaration: A variable declaration introduces a variable with its name, type and other attributes - not to be mixed up with definition and use:

// Declaration: declares variable colorString of type String[]
String[] colorString;
// Definition: define/set/assign the "content" of variable colorString
colorString = new String[36];
// Use: access the "content" of variable colorString
if (word.equals(colorString[6]) { }

NOTE: final means that the variable can only be defined once so - the first definition is called initalization and so on:

final String[] colorString = new String[36];
// now this should be an error
colorString = new String[9];

Scope: I can't say it any less complex as this sentence from English Wikipedia:

The scope of a variable describes where in a program's text the variable may be used ..."

In the above example of Declaration, Definition and Use this all happens in the same Scope. Scopes can be nested which means that you can define/use variables from multiple scopes like:

// SCOPE0 - contains "Sample" and all classes/interfaces... available
class Sample {
     // SCOPE1 - contains all from SCOPE0 and "Variable1" and "something"
     private Integer Variable1 = 0;
     function void something() {
         // now here it gets special, a variable is only visible after
         // declaration so java basically has a new local scope for each definition
         // SCOPE2 - contains all from SCOPE1 and some specials like `this`
         Integer Variable2 = 1;
         // SCOPE3 - contains all from SCOPE1 and "Variable2"
         if(Variable1.equals(Variable2)) {
            // SCOPE4 - contains all from SCOPE3 
            Integer Variable3 = 2;
            // SCOPE5 - contains all from SCOPE4 and "Variable3" 

            // END OF SCOPE5 and SCOPE4
         }
         // now this will give an error because "Variable3" is not visible anymore
         Variable2 = Variable3;
         // END OF SCOPE3 and SCOPE2
     }
}

Scopes are tied to static binding. The compiler can statically - meaning on compilation - collect all information needed to know which name at which position in code means which variable, method, class and so on.

The differences in the scopes are defined by the language or static binding mechanism. For example in SCOPE1 all members declared in that class are visible. Whereas in SCOPE3 the declaration creates a new scope and the variable is only visible within this scope.

As you see a variable is in general declared only in one Scope but defined/used in the same and nested Scopes. Now it gets more funny when a Programming language allows to override a name in nested scopes:

class Sample {
     private Integer Variable1 = 0;
     function void something() {
         // Local variable gets the same name as the member "Variable1"
         Integer Variable1 = 1;
         // now we need to use "this.Variable1" to access the "outer"
         // scopes "Variable1" because the name "Variable1" is bound to
         // the local variable "Variable1"
         if(Variable1.equals(this.Variable1)) {
            // Local - meaning in the method body - Scope overrides are not allowed so this gives an error 
            Integer Variable1 = 2;
         }
     }
}

Closure: TODO:

Java local Classes (Closure): TODO:

Comments