Java 中的范围和数组如何工作?
How do scopes and arrays in Java work?
我通常用 C++ 编程,刚开始为 SPOJ 编写一些更简单的程序来练习 Java 中的编程。
我正在制作 Hangman 游戏,我在其中初始化数组以可视化当前游戏状态。一开始你输入你想玩多少次。每次失败或胜利后,游戏状态需要回到默认状态。所以我尝试初始化二维数组,我称之为 initializedLevel。后来,在循环中,我创建了新的二维数组并将其值设置为初始化的一个。我对其他值做同样的事情以在每场比赛后重置它们。当我输或赢时,游戏状态不会改变,但生活、猜测和话语会改变。我更改了范围并在循环中初始化了第一个数组并且它起作用了,但我真的很想了解为什么它一开始不起作用以及最好的方法是什么。
之前:
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)
...
之后:
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)
有些函数将二维数组作为参数,但它们使用的是级别,而不是 initializedLevel。
这不是范围问题。第一种方法的问题是您将 reference 复制到同一个数组,而第二种方法实际上每次都创建了一个新数组。
另一种方法是在循环外初始化数组并创建数组的深层副本。例如:
char[][] level = Arrays.stream(initializedLevel)
.map(char[]::clone)
.toArray(char[][]::new);
或者,如果您愿意,一个简单的等效循环:
char[][] level = new char[initializedLevel.length][];
for (int j = 0; j < level.length; j++) {
level[j] = initializedLevel[j].clone();
}
我通常用 C++ 编程,刚开始为 SPOJ 编写一些更简单的程序来练习 Java 中的编程。
我正在制作 Hangman 游戏,我在其中初始化数组以可视化当前游戏状态。一开始你输入你想玩多少次。每次失败或胜利后,游戏状态需要回到默认状态。所以我尝试初始化二维数组,我称之为 initializedLevel。后来,在循环中,我创建了新的二维数组并将其值设置为初始化的一个。我对其他值做同样的事情以在每场比赛后重置它们。当我输或赢时,游戏状态不会改变,但生活、猜测和话语会改变。我更改了范围并在循环中初始化了第一个数组并且它起作用了,但我真的很想了解为什么它一开始不起作用以及最好的方法是什么。
之前:
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)
...
之后:
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)
有些函数将二维数组作为参数,但它们使用的是级别,而不是 initializedLevel。
这不是范围问题。第一种方法的问题是您将 reference 复制到同一个数组,而第二种方法实际上每次都创建了一个新数组。
另一种方法是在循环外初始化数组并创建数组的深层副本。例如:
char[][] level = Arrays.stream(initializedLevel)
.map(char[]::clone)
.toArray(char[][]::new);
或者,如果您愿意,一个简单的等效循环:
char[][] level = new char[initializedLevel.length][];
for (int j = 0; j < level.length; j++) {
level[j] = initializedLevel[j].clone();
}