TDD实战(五)“井字游戏” 需求三
虫师 创建于 almost 7 years 之前
最后更新: less than a minute 之前
阅读数: 177
需求3
继续实现需求3,检查所可能获胜的情况,只要满足其中一个,就宣布相应玩家获胜。
最先在水平、锤直或对角线上将自己的3个标记连起来的玩家获胜。
测试用例1
现在我们检查是否有垂直线完全被某个玩家占据。
@Test
public void whenPlayAndWholeVerticalLineThenWinner(){
ticTacToe.play(2,1); //X
ticTacToe.play(1,1); //O
ticTacToe.play(3,1); //X
ticTacToe.play(1,2); //O
ticTacToe.play(2,2); //O
String actual = ticTacToe.play(1,3); //O
assertEquals("O is the winner", actual);
}
一个玩家的棋子占据整条垂直线就赢了。
实现代码1
这个实现和前面一个类似,前面在水平方向上做检查,现在需要在垂直方向上做同样的检查。
private boolean isWin(){
int playerTotal = lastPlayer * 3;
for(int i = 0; i < SIZE; i++){
if(board[0][i] + board[1][i] + board[2][i] == playerTotal){
return true;
}else if(board[i][0] + board[i][1] + board[i][2] == playerTotal){
return true;
}
}
return false;
}
** 执行 测试用例1 检查它是否运行通过。
测试用例2
水平线和垂直线都搞定后,最后来实现对角线。
@Test
public void whenPlayAndTopBottomDiagonalLineThenWinner(){
ticTacToe.play(1,1); //X
ticTacToe.play(1,2); //O
ticTacToe.play(2,2); //X
ticTacToe.play(1,3); //O
String actual = ticTacToe.play(3,3); //X
assertEquals("X is the winner", actual);
}
实现代码2
对于测试用例2,只涉及一条线,因此可以直接检查。
private boolean isWin(){
int playerTotal = lastPlayer * 3;
for(int i = 0; i < SIZE; i++){
if(board[0][i] + board[1][i] + board[2][i] == playerTotal){
return true;
}else if(board[i][0] + board[i][1] + board[i][2] == playerTotal){
return true;
}
}
if((board[0][0] + board[1][1] + board[2][2]) == playerTotal){
return true;
}
return false;
}
测试用例3
如果你足够细心,会发现上面处理斜线不完整,井子棋的斜线是有两条的,上面只处理了“\” ,还有一条反向的 “/”。
编写测试用例测试这条反斜线。
@Test
public void whenPlayAndBottomTopDiagonalLineThenWinner(){
ticTacToe.play(1,3); //X
ticTacToe.play(1,1); //O
ticTacToe.play(2,2); //X
ticTacToe.play(1,2); //O
String actual = ticTacToe.play(3,1); //X
assertEquals("X is the winner", actual);
}
实现代码3
这个实现和前一个基本一样,唯一需要修改的是坐标。
private boolean isWin(){
int playerTotal = lastPlayer * 3;
for(int i = 0; i < SIZE; i++){
if(board[0][i] + board[1][i] + board[2][i] == playerTotal){
return true;
}else if(board[i][0] + board[i][1] + board[i][2] == playerTotal){
return true;
}
}
if((board[0][0] + board[1][1] + board[2][2]) == playerTotal){
return true;
}else if((board[0][2] + board[1][1] + board[2][0]) == playerTotal){
return true;
}
return false;
}
重构
处理对角线时,所做的计算看起来不太好,也许重用既有的循环更合适。
private boolean isWin(){
int playerTotal = lastPlayer * 3;
char diagonal1 = '\0';
char diagonal2 = '\0';
for(int i = 0; i < SIZE; i++){
diagonal1 += board[i][i];
diagonal2 += board[i][SIZE -i -1];
if(board[0][i] + board[1][i] + board[2][i] == playerTotal){
return true;
}else if(board[i][0] + board[i][1] + board[i][2] == playerTotal){
return true;
}
}
if(diagonal1 == playerTotal || diagonal2 == playerTotal ){
return true;
}
return false;
}
这里的重构增加了代码的难度,分别定义了两个字符变量diagonal1
和 diagonal2
来记录两个斜线的坐标,如果两个下线满足条件,则用户获胜。
到此,需求3 完成。