今天把以前的扫雷代码重构了一遍,有点收获
1.分清代码中结构相同的部分和不同的部分,将结构相同的部分提取出来
之前的代码:
if (bomb == nearBombNum[x][y]) // 如果周围雷数和判断一样 { if (x - 1 >= 0 && y + 1 >= 0 && x - 1 <= 19 && y + 1 <= 19 && !isBomb[x][y])// 边界判断,如果点击处不是地雷 { changeBombImage(button[x - 1][y + 1]); // 点击处左上角判断 if (nearBombNum[x - 1][y + 1] == 0 && !isBomb[x - 1][y + 1]) showBomb(button[x - 1][y + 1]); } if (x >= 0 && y + 1 >= 0 && x <= 19 && y + 1 <= 19 && !isBomb[x][y]) { changeBombImage(button[x][y + 1]); // 点击处正上方判断 if (nearBombNum[x][y + 1] == 0) showBomb(button[x][y + 1]); } if (x + 1 >= 0 && y + 1 >= 0 && x + 1 <= 19 && y + 1 <= 19 && !isBomb[x][y]) { changeBombImage(button[x + 1][y + 1]); // 点击处右上角判断 if (nearBombNum[x + 1][y + 1] == 0) showBomb(button[x + 1][y + 1]); } if (x - 1 >= 0 && y >= 0 && x - 1 <= 19 && y <= 19 && !isBomb[x][y]) { changeBombImage(button[x - 1][y]); // 点击处左边判断 if (nearBombNum[x - 1][y] == 0) showBomb(button[x - 1][y]); } if (x + 1 >= 0 && y >= 0 && x + 1 <= 19 && y <= 19 && !isBomb[x][y]) { changeBombImage(button[x + 1][y]);// 点击处右边判断 if (nearBombNum[x + 1][y] == 0) showBomb(button[x + 1][y]); } if (x - 1 >= 0 && y - 1 >= 0 && x - 1 <= 19 && y - 1 <= 19 && !isBomb[x][y]) { changeBombImage(button[x - 1][y - 1]); // 点击处左下角判断 if (nearBombNum[x - 1][y - 1] == 0) showBomb(button[x - 1][y - 1]); } if (x >= 0 && y - 1 >= 0 && x <= 19 && y - 1 <= 19 && !isBomb[x][y]) { changeBombImage(button[x][y - 1]); // 点击处正下方判断 if (nearBombNum[x][y - 1] == 0) showBomb(button[x][y - 1]); } if (x + 1 >= 0 && y - 1 >= 0 && x + 1 <= 19 && y - 1 <= 19 && !isBomb[x][y]) { changeBombImage(button[x + 1][y - 1]); // 点击处右下角判断 if (nearBombNum[x + 1][y - 1] == 0) showBomb(button[x + 1][y - 1]); }
每一个格子,都要对周围的8个格子进行处理,包括边界判断,旗子数目计算,地雷数目计算,都有相同的结构,只是不同的格子,各自的坐标不同 ,通过2个数组xLocation 和yLocation组合起来,循环8次,就能执行同样的操作了。
重构之后的代码:
int xLocation[] = { x - 1, x, x + 1, x - 1, x + 1, x - 1, x,x + 1, }; int yLocation[] = { y + 1, y + 1, y + 1, y, y, y - 1, y - 1,y - 1 }; if (bomb == nearBombNum[x][y]) // 如果周围雷数和判断一样 { for (int i = 0; i < 8; i++) // 周围8个格子,每个格子判断一次 { if (new Mybutton(xLocation[i], yLocation[i]) .locationLegalJudge() && !isBomb[x][y]) // 边界判断,而且不是地雷 { int xL = xLocation[i]; int yL = yLocation[i]; changeBombImage(button[xL][yL]); if (nearBombNum[xL][yL] == 0 && !isBomb[xL][yL]) showBomb(button[xL][yL]); } } }
2.边界判断
刚开始一直在边界判断上出问题,总是写一堆复杂的判断条件
开始是这样的:
if (x - 1 >= 0 && y + 1 >= 0 && x - 1 <= 19 && y + 1 <= 19&& !isBomb[x][y]) if (x >= 0 && y + 1 >= 0 && x <= 19 && y + 1 <= 19&& !isBomb[x][y]) if (x +1 >= 0 && y + 1 >= 0 && x + 1 <= 19 && y + 1 <= 19&& !isBomb[x][y]) …… ……
上面这种方式,参数坐标一直在不断改变,很混乱
后来想了想,用构造方法的方式来解决这个问题就比较简单了
Mybutton类
Mybutton(int x, int y) { //构造方法 this(); // 调用无参构造方法 this.x = x; this.y = y; } public boolean locationLegalJudge() { //边界判断方法 return this.x >= 0 && this.x < 19 && this.y >= 0 && this.y < 19; }
然后对一个格子周围8个格子做边界判断
for(int i=0;i<8;i++) { if(new Mybutton(xLocation[i],yLocation[i]).locationLegalJudge()) //边界判断 { …… } }
解决这个问题的主要思想就是,将变化的坐标,变成构造方法的参数,归一为同样的形式,用同样的方法判断就好了。