I am usually programming in C++ and just started to write some easier programs for SPOJ to practice programming in Java.
I am making Hangman game where I initialize array to visualize current game state. At start you type how many times you want to play. After each defeat or victory, game state needs to go back to default one. So I tried initializing two dimensional array which I called initializedLevel. Later on, in loop, I make new two dimensional array and set its value to initialized one. I do the same with other values to reset them after each game. When I lose or win, state of the game didn't change but lives, guesses and words did. I changed scope and intialized first array in loop and it worked but I really would like to understand why it didn't work at first and what is best way to do it.
Before:
Scanner reader=new Scanner(System.in);
int n=reader.nextInt();
char initializedLevel [][]={
{'+','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','+'},
{'|',' ',' ',' ',' ','_','_','_','_','_','_','_','_','_','_','_','_',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|','/',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ','_','|','_',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'+','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','+'},
};
for(int i=0;i<n;i++)
{
char level[][]=initializedLevel;
String word=reader.next();
int maxAnswers=reader.nextInt();
int answers=0;
String encrypted=getEncryptedWord(word);
String guesses="-";
int lives=7;
System.out.println("Welcome to the Hangman Game!");
drawGameState(level,encrypted,lives,guesses);
while(lives>0 && answers<maxAnswers)
...
After:
Scanner reader=new Scanner(System.in);
int n=reader.nextInt();
for(int i=0;i<n;i++)
{
char initializedLevel [][]={
{'+','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','+'},
{'|',' ',' ',' ',' ','_','_','_','_','_','_','_','_','_','_','_','_',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|','/',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ',' ','|',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'|',' ',' ',' ','_','|','_',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','|'},
{'+','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','+'},
};
char level[][]=initializedLevel;
String word=reader.next();
int maxAnswers=reader.nextInt();
int answers=0;
String encrypted=getEncryptedWord(word);
String guesses="-";
int lives=7;
System.out.println("Welcome to the Hangman Game!");
drawGameState(level,encrypted,lives,guesses);
while(lives>0 && answers<maxAnswers)
There were functions which took two dimensional array as argument but they used level, not initializedLevel.
It's not an issue of scope. The problem with the first way is that you're copying a reference to the same array, whereas in the second way you're actually creating a new array each time.
An alternative is to initialize the array outside the loop and create a deep copy of the array. For example:
char[][] level = Arrays.stream(initializedLevel)
.map(char[]::clone)
.toArray(char[][]::new);
Or if you prefer, a simple loop equivalent:
char[][] level = new char[initializedLevel.length][];
for (int j = 0; j < level.length; j++) {
level[j] = initializedLevel[j].clone();
}