如何防止`嵌套`
How to prevent `nesting`
我编写了一个有效的代码,但我的老师告诉我我在“嵌套”,因为他看到了很多 if/else 语句,我尝试缩短我的代码,但我只是不知道如何才能得到删除这些 if/else 语句。
这是我的代码,一个简短的总结:
该代码是 nxn 块的网格,只能与 'blank' 块交换,因此我的代码如下所示:
grd.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// This statement prevents the player from playing the game
// if the timer is counting down.
if (timer == true) {
Toast.makeText(getApplicationContext(),
"The game has not started yet!", Toast.LENGTH_SHORT)
.show();
} else {
clickcounter++;
// Because difficulty's are 0,1,2 the row/column dimensions
// are difficulty + 3, here i create the texview of the moves
// as well.
size = (int) difficulty + 3;
TextView movesText = (TextView) findViewById(R.id.textView2);
// Checks if click is even or odd. Even is firstclick odd is
// secondclick
if (clickcounter % 2 == 1) {
firstimg = (ImageView) view;
firstclick = position;
firsttag = (int) firstimg.getTag();
} else if (clickcounter % 2 == 0) {
ImageView secondimg = (ImageView) view;
scndtag = (int) secondimg.getTag();
// To prevent cheaters to press twice on the same tile
// we set this if statement
if (position == firstclick) {
clickcounter = 1;
// Next we check whether one of the clicked images
// is the blank one, if that's not the case do
// nothing!
} else if (firsttag != crops.size() - 1
&& scndtag != crops.size() - 1) {
// This else statements checks what happens if one has clicked the
// blank tile
} else {
// This statement below is the same as an switch/case statement
// but because of the fact that the switch/case statement gave the
// following error i chose for this method:
// case expressions must be constant expressions
int i = firstclick - position;
if (i == -1) {
if(firstclick % size == size - 1){
} else {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
} else if (i == 1) {
if(firstclick % size == 0){
} else {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
} else if (i == size) {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
} else if (i == -size) {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
}
}
}
}
});
}
我试图做一个switch/case语句来防止这个if/else语句的总和,但是它说它不能将大小识别为常数(因为难度是玩家选择的变量), 所以如果我能做到这一点,也许 if/else 语句的重载就会消失。
有什么建议吗?我已经做了一些工作来使代码更具可读性,原始代码如下所示:
grd.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (timer == true) {
Toast toast = new Toast(getApplicationContext());
toast.makeText(getApplicationContext(),
"The game has not started yet!", Toast.LENGTH_SHORT)
.show();
} else {
clickcounter++;
// Because difficulty's are 0,1,2 the row/column dimensions
// are difficulty + 3
size = (int) difficulty + 3;
TextView movesText = (TextView) findViewById(R.id.textView2);
// Checks if click is even or odd. Even is firstclick odd is
// secondclick
if (clickcounter % 2 == 1) {
firstimg = (ImageView) view;
firstclick = position;
firsttag = (int) firstimg.getTag();
} else if (clickcounter % 2 == 0) {
ImageView secondimg = (ImageView) view;
Bitmap swapImage = crops.get(position);
Integer swapID = ID.get(position);
scndtag = (int) secondimg.getTag();
// To prevent cheaters to press twice on the same tile
// we set this if statement
if (position == firstclick) {
clickcounter = 1;
// These next if/else if statements are a summation
// of all kinds of
// rules that need to be implemented in the game!
// First we check whether one of the clicked images
// is the blank one
} else if (firsttag != crops.size() - 1
&& scndtag != crops.size() - 1) {
// Here we check if the tiles are neighbors of each
// other
} else if ((position - 1 != firstclick)
&& (position + 1 != firstclick)
&& (position + size) != firstclick
&& ((position - size) != firstclick)) {
// Check when secondclick on the right of firstclick
} else if (position - 1 == firstclick) {
// This prevents the game to swap tiles on the
// edges, like
// starting from 0, 2 with 3.
if (position % size != 0) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
// Check when secondclick on the left of firstclick
} else if (position + 1 == firstclick) {
if (position % size != (size - 1)) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
// Check when secondclick is above first
} else if ((position + size) == firstclick) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
// Check when secondclick is above first
} else if ((position - size) == firstclick) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
// This useful command rebuilds the imageviews
grd.invalidateViews();
}
}
}
});
}
谨致问候,
基斯蒂尔
首先,"too much nesting" 的内在问题是代码维护。所以,学习如何减少它是一个很好的做法。
当您有嵌套时 loops/if-else 可以采取一些措施来消除它。这里有一些提示:
如果您在代码中看到重复的模式,在您的情况下是这样的:
交换(第一次点击,位置);
移动++;
movesText.setText("Moves: " + 移动);
checkwin2();
您应该创建一个方法。然后,如果由于任何原因它发生变化,它都在一个地方。此外,这允许您将 "logic" (if-else) 与过程分开。
您的代码非常"procedural",这有时是必要的,但却破坏了面向对象编程的好处。要改变这一点,请考虑创建一个对象来处理它。使 "logic variables" 像这样:
int i = firstclick - position;
并使用此示例,将 "firstclick" 和 "position" 设为私有对象属性并创建 "getters" 和 "setters"。然后根据get/set执行逻辑。这将使您能够专注于“对象”是如何根据对它的更改而受到影响的。然后,如果您执行了第 1 步,则可以将这些方法合并到您的新对象中。
此外,您可以尝试采用最深的嵌套逻辑,将其变成 "object",然后尝试对下一个最深的嵌套逻辑执行相同的操作,依此类推。这可以揭示不明显的逻辑模式,同时还有助于使您的代码更易于阅读和维护。
检查您的 "flag" 变量。也许应该将它们归为一个或多个对象。您甚至可以将对象用作 "flag" - 但即使是标志也可以成为代码中的两个或多个变量,而不是正确地成为单个对象。
注意:不要"afraid"只有一种或两种方法的小或简单的对象。另外,不要犹豫使用单行方法。重要的是将动作(方法)和属性(变量)放在对象中,因为它们 相关。
我编写了一个有效的代码,但我的老师告诉我我在“嵌套”,因为他看到了很多 if/else 语句,我尝试缩短我的代码,但我只是不知道如何才能得到删除这些 if/else 语句。
这是我的代码,一个简短的总结: 该代码是 nxn 块的网格,只能与 'blank' 块交换,因此我的代码如下所示:
grd.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// This statement prevents the player from playing the game
// if the timer is counting down.
if (timer == true) {
Toast.makeText(getApplicationContext(),
"The game has not started yet!", Toast.LENGTH_SHORT)
.show();
} else {
clickcounter++;
// Because difficulty's are 0,1,2 the row/column dimensions
// are difficulty + 3, here i create the texview of the moves
// as well.
size = (int) difficulty + 3;
TextView movesText = (TextView) findViewById(R.id.textView2);
// Checks if click is even or odd. Even is firstclick odd is
// secondclick
if (clickcounter % 2 == 1) {
firstimg = (ImageView) view;
firstclick = position;
firsttag = (int) firstimg.getTag();
} else if (clickcounter % 2 == 0) {
ImageView secondimg = (ImageView) view;
scndtag = (int) secondimg.getTag();
// To prevent cheaters to press twice on the same tile
// we set this if statement
if (position == firstclick) {
clickcounter = 1;
// Next we check whether one of the clicked images
// is the blank one, if that's not the case do
// nothing!
} else if (firsttag != crops.size() - 1
&& scndtag != crops.size() - 1) {
// This else statements checks what happens if one has clicked the
// blank tile
} else {
// This statement below is the same as an switch/case statement
// but because of the fact that the switch/case statement gave the
// following error i chose for this method:
// case expressions must be constant expressions
int i = firstclick - position;
if (i == -1) {
if(firstclick % size == size - 1){
} else {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
} else if (i == 1) {
if(firstclick % size == 0){
} else {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
} else if (i == size) {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
} else if (i == -size) {
swap(firstclick,position);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
}
}
}
}
});
}
我试图做一个switch/case语句来防止这个if/else语句的总和,但是它说它不能将大小识别为常数(因为难度是玩家选择的变量), 所以如果我能做到这一点,也许 if/else 语句的重载就会消失。
有什么建议吗?我已经做了一些工作来使代码更具可读性,原始代码如下所示:
grd.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (timer == true) {
Toast toast = new Toast(getApplicationContext());
toast.makeText(getApplicationContext(),
"The game has not started yet!", Toast.LENGTH_SHORT)
.show();
} else {
clickcounter++;
// Because difficulty's are 0,1,2 the row/column dimensions
// are difficulty + 3
size = (int) difficulty + 3;
TextView movesText = (TextView) findViewById(R.id.textView2);
// Checks if click is even or odd. Even is firstclick odd is
// secondclick
if (clickcounter % 2 == 1) {
firstimg = (ImageView) view;
firstclick = position;
firsttag = (int) firstimg.getTag();
} else if (clickcounter % 2 == 0) {
ImageView secondimg = (ImageView) view;
Bitmap swapImage = crops.get(position);
Integer swapID = ID.get(position);
scndtag = (int) secondimg.getTag();
// To prevent cheaters to press twice on the same tile
// we set this if statement
if (position == firstclick) {
clickcounter = 1;
// These next if/else if statements are a summation
// of all kinds of
// rules that need to be implemented in the game!
// First we check whether one of the clicked images
// is the blank one
} else if (firsttag != crops.size() - 1
&& scndtag != crops.size() - 1) {
// Here we check if the tiles are neighbors of each
// other
} else if ((position - 1 != firstclick)
&& (position + 1 != firstclick)
&& (position + size) != firstclick
&& ((position - size) != firstclick)) {
// Check when secondclick on the right of firstclick
} else if (position - 1 == firstclick) {
// This prevents the game to swap tiles on the
// edges, like
// starting from 0, 2 with 3.
if (position % size != 0) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
// Check when secondclick on the left of firstclick
} else if (position + 1 == firstclick) {
if (position % size != (size - 1)) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
// Check when secondclick is above first
} else if ((position + size) == firstclick) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
// Check when secondclick is above first
} else if ((position - size) == firstclick) {
crops.set(position, crops.get(firstclick));
ID.set(position, ID.get(firstclick));
crops.set(firstclick, swapImage);
ID.set(firstclick, swapID);
moves++;
movesText.setText("Moves: " + moves);
checkwin2();
}
// This useful command rebuilds the imageviews
grd.invalidateViews();
}
}
}
});
}
谨致问候,
基斯蒂尔
首先,"too much nesting" 的内在问题是代码维护。所以,学习如何减少它是一个很好的做法。
当您有嵌套时 loops/if-else 可以采取一些措施来消除它。这里有一些提示:
如果您在代码中看到重复的模式,在您的情况下是这样的:
交换(第一次点击,位置); 移动++; movesText.setText("Moves: " + 移动); checkwin2();
您应该创建一个方法。然后,如果由于任何原因它发生变化,它都在一个地方。此外,这允许您将 "logic" (if-else) 与过程分开。
您的代码非常"procedural",这有时是必要的,但却破坏了面向对象编程的好处。要改变这一点,请考虑创建一个对象来处理它。使 "logic variables" 像这样:
int i = firstclick - position;
并使用此示例,将 "firstclick" 和 "position" 设为私有对象属性并创建 "getters" 和 "setters"。然后根据get/set执行逻辑。这将使您能够专注于“对象”是如何根据对它的更改而受到影响的。然后,如果您执行了第 1 步,则可以将这些方法合并到您的新对象中。
此外,您可以尝试采用最深的嵌套逻辑,将其变成 "object",然后尝试对下一个最深的嵌套逻辑执行相同的操作,依此类推。这可以揭示不明显的逻辑模式,同时还有助于使您的代码更易于阅读和维护。
检查您的 "flag" 变量。也许应该将它们归为一个或多个对象。您甚至可以将对象用作 "flag" - 但即使是标志也可以成为代码中的两个或多个变量,而不是正确地成为单个对象。
注意:不要"afraid"只有一种或两种方法的小或简单的对象。另外,不要犹豫使用单行方法。重要的是将动作(方法)和属性(变量)放在对象中,因为它们 相关。