在tic-tac-toe实现中减少代码重复

问题描述 投票:0回答:2

我在C中制作一个井字游戏,我的函数checkwinner()以if语句的形式有很多代码重复。

void checkwinner(void){
     if(square[1] == square[2] && square[2] == square[3]){
         printresult(square[2]);
     }
     else if(square[4] == square[5] && square[5] == square[6]){
         printresult(square[5]);
     }
     else if(square[7] == square[8] && square[8] == square[9]){
         printresult(square[8]);
     }
     else if(square[1] == square[4] && square[4] == square[7]){
         printresult(square[4]);
     }
     else if(square[2] == square[5] && square[5] == square[8]){
         printresult(square[5]);
     }
     else if(square[3] == square[6] && square[6] == square[9]){
         printresult(square[6]);
     }
     else if(square[1] == square[5] && square[5] == square[9]){
         printresult(square[5]);
     }
     else if(square[3] == square[5] && square[5] == square[7]){
         printresult(square[5]);
     }
}

名为square []的数组包含字符“X”或“O”。因此该函数比较行,列和对角线,并检查字符是否匹配。

有没有办法减少代码重复,使代码更紧凑?

c
2个回答
1
投票

就像Angen说的那样,匹配功能很好:

bool match(int x, int y, int z){
    return square[x] == square[y] && square[y] == square[z];
}

但是,我也会考虑像这样重写这个。我假设你的square是一个char阵列,但它也适用于int。另请注意,您需要检查空单元格。

/* Returns the winner on match, and otherwise 0 */
char match(int x, int y, int z){
    if(square[x] != 'X' && square[x] != 'O')
        return 0;
    if (square[x] == square[y] && square[y] == square[z])
        return square[x];
    returns 0;
}

之后,您可以分别检查三个案例。也许这对于一个小小的tic tac toe来说太过分了,但无论如何我都会表现出来。这个想法很好地转化为更大的应用程序。

char matchRows() {
    int row=1;
    for(int i=0; i<3; i++) {
         char c=match(row+i, row+3+i, row+6+i);
         if(c)
             return c;
    }
    return 0;
}

char matchColumns() {
    int column=1;
    for(int i=0; i<3; i++) {
         char c=match(column+i, column+1+i, column+2+i);
         if(c)
             return c;
    }
    return 0;
}

char matchDiagonals() {
    char c;
    if(c=match(1,5,9))
        return c;
    if(c=match(3,5,7))
        return c;
    return 0;
}

然后你可以像这样写checkwinner

char checkWinner() {
    char c;
    if(c=matchRows()) 
        return c;
    if(c=matchColumns()) 
        return c;
    if(c=matchDiagonals())
        return c;
    return c;            
}

然后我会添加一个新函数来接管以前的checkWinner的职责:

void printWinner() {
    char c=checkWinner();
    if(c)
        printResult(c);
}

也许这在计算总线数时不会使代码更紧凑,但它绝对是更好的设计,每个单独的功能都更紧凑。此外,您可能会注意到,我将功能分开,以便功能不会打印和处理有关如何计算获胜者的逻辑。

我在你的功能中添加了camelCase。这使代码更容易阅读。


0
投票

你可以写这样的功能

bool match(int x, int y, int z){
    return square[x] == square[y] && square[y] == square[z];
}

然后

void checkwinner(void){
         if(match(1,2,3)){
         printresult(square[2]);
         }
         else if(match(4,5,6)){
         printresult(square[5]);
         } ... 

你可以将printresult移动到匹配功能

bool match(int x, int y, int z){
        if(square[x] == square[y] && square[y] == square[z]){
             printresult(square[y]);
              return true;
        }
    return false;
    }

如果你的功能没有别的办法,那就有了类似的东西

  void checkwinner(void){
             if(match(1,2,3)){
                 return;
             }
             if(match(4,5,6)){
                   return;
             } ... 
© www.soinside.com 2019 - 2024. All rights reserved.