如何将我的`winnerCheck`函数转换为递归工作? - C

时间:2018-11-21 17:22:36

标签: c recursion iteration global-variables

问题:我在建立对递归的理解方面很艰难(学习缓慢的人),每当我要创建.name { margin-bottom: 5em; margin-left: 5%; margin-top: 5%; } 函数时,我总是通过首先recursive

然后,我会尽力达到一些基本的递归规则,但通常最终会感到有些筋疲力尽。

我要做的就是将iteration函数转换为工作winnerCheck

此外,我听说使用recursively时会皱眉。这是真的?我应该将数组global variables移到本地工作吗?

感谢您提供的任何指导和意见。

代码:

square

1 个答案:

答案 0 :(得分:1)

winnerCheck函数测试是否满足任何可能的获胜条件。并且这包括检查某些三元组是否都由同一个球员提交。

您可以对具有所有三元组的数组进行硬编码,以确保获胜。然后检查胜利是否意味着遍历该数组,并且可以轻松地递归完成。

编辑

因此,有8个可能的“获胜位置”三元组,您可以将其声明为

const int numwinpos = 8;

const int winpos[8][3] = {{1,2,3},
                          {4,5,6},
                          {7,8,9},
                          {1,4,7},
                          {2,5,8},
                          {3,6,9},
                          {1,5,9},
                          {3,5,7}};

关于递归检查过程,这里是一个示例,说明如何检查大小为v的向量n的任何元素是否满足属性p

// returns -1 if no v[i] satisfies p
// returns  i if v[i] satisfies p (picks largest i)
// (i>=0) and (i<n)

int recTest(const int v[], const int n){

  if( (n>0) && (!p(v[n-1])) )
    return recTest(v,n-1);
  else
    return n-1;
}

EDIT2:

因此winnersCheck的格式可以是

int winnerCheck(char square[], int winseq[][3], int n){
  // there's n winning sequences to test, 0 .. n-1
  // let's check sequence n-1
  int pos0 = winseq[n-1][0];
  int pos1 = winseq[n-1][1];
  int pos2 = winseq[n-1][2];
  if( (n>0) && !(squares in positions pos1, pos2 and pos2 marked by same player) )

    // game does not contain winning sequence n-1
    // so test the other n-1 positions, i.e. 0 .. n-2 
    return winnerCheck(square,winseq,n-1);  
  else
    // either n = 0 and there's no more positions to test 
    // or game contains winning sequence n-1 
    return n-1;
}

当然,如果要插入的条件可能会有点大。您可能想要以不同的方式组织或定义辅助功能来完成这项工作。

这也是对您的主代码的一些修改,这些修改显示了您所做的某些事情如何变得更加清晰。

int main() {

  // Game Board: there's 9 squares in the game
  // 0 1 2
  // 3 4 5
  // 6 7 8

  // ' ' represents "nothing" in a square
  char square[9]={' ',' ',' ',' ',' ',' ',' ',' ',' '}; 

  // There are 8 possible ways of winning the game
  int nwinseq = 8;
  int winseq[8][3] = {{0,1,2},
                      {3,4,5},
                      {6,7,8},
                      {0,3,6},
                      {1,4,7},
                      {2,5,8},
                      {0,4,8},
                      {2,4,6}};

   // there's player 1 and player 2
   // player 1 goes first  
   int player = 1;   

   // current play
   // at most 9 plays in a game
   int i = 1;

   // winning sequence
   // 8 possibilities (0 to 7)
   // no winning sequence found when game starts
   int w = -1;

   // execute game until it's over
   bool gameOver = false;

   while(!gameOver){    
    // print board  
    board(square);

    // ask player for his move of choice
    int choice; 
    printf("Player %d, enter a number: ", player);
    scanf("%d", &choice);

    // change the square according to player's move
    move(player, square, choice);

    // check for win
    w = winnerCheck(square, winseq, nwinseq);

    gameOver = (w >= 0) // found winning sequence i
            || (i == 9); // or made 9 plays already

    // update play number and player
    // obs: maybe update it only if game is not over
    // matter of taste
    i++;

    if (player == 1)
      player = 2;
    else // player == 2 
      player = 1;
  }

  // Game is over 
  // Print the end result 
  // ...
}

void move(int player, char square[], int choice){
   if (player == 1)
    square[choice] = 'X';
  else
    square[choice] = 'O';
}