问题:我在建立对递归的理解(学习速度慢(方面遇到了困难,每当我被要求创建recursive
函数时,我总是先通过iteration
创建它。
然后,我会尽我所能达到递归的一些基本规则,但最终通常会感到有点精疲力竭。
我所要做的就是将winnerCheck
函数转换为工作recursively
。
此外,我听说使用global variables
是不受欢迎的。这是真的吗?我应该将阵列square
移动到本地工作吗?
感谢您提供的任何指导和意见。
代码:
#include<stdio.h>
#include<conio.h>
char square[10] = {'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
int winnerCheck();
void board();
int main() {
/*
char board[3][3] = {
};
printf("t|t|tn");
printf("t|t|tn");
printf("________|_______|________n");
printf("t|t|tn");
printf("t|t|tn");
printf("________|_______|________n");
printf("t|t|tn");
printf("t|t|tn");
printf("t|t|tn");
*/
int player = 1, i, choice;
char mark;
do {
board();
player = player % 2 ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
//mark = (player == 1) ? 'X' : 'O';
if (player == 1) {
mark = 'X';
} else {
mark = '0';
}
if (choice == 1)
square[1] = mark;
else if (choice == 2)
square[2] = mark;
else if (choice == 3)
square[3] = mark;
else if (choice == 4)
square[4] = mark;
else if (choice == 5)
square[5] = mark;
else if (choice == 6)
square[6] = mark;
else if (choice == 7)
square[7] = mark;
else if (choice == 8)
square[8] = mark;
else if (choice == 9)
square[9] = mark;
i = winnerCheck();
player++;
} while (i == -1);
board();
if (i == 1)
printf("==>aPlayer %d win ", --player);
else
printf("==>aGame draw");
getch();
return 0;
}
int winnerCheck() {
if (square[1] == square[2] && square[2] == square[3])
return 1;
else if (square[4] == square[5] && square[5] == square[6])
return 1;
else if (square[7] == square[8] && square[8] == square[9])
return 1;
else if (square[1] == square[4] && square[4] == square[7])
return 1;
else if (square[2] == square[5] && square[5] == square[8])
return 1;
else if (square[3] == square[6] && square[6] == square[9])
return 1;
else if (square[1] == square[5] && square[5] == square[9])
return 1;
else if (square[3] == square[5] && square[5] == square[7])
return 1;
else if (square[1] != '1' && square[2] != '2' && square[3] != '3' && square[4]
!= '4' && square[5] != '5' &&
square[6] != '6' && square[7] != '7' && square[8]
!= '8' && square[9] != '9')
return 0;
else
return -1;
}
void board() {
printf("nntTic Tac Toenn");
printf("Player 1 (X) - Player 2 (O)nnn");
//prints the board after every input
printf(" | | n");
printf(" %c | %c | %c n", square[1], square[2],square[3]);
printf("____|_____|____n");
printf(" | | n");
printf(" %c | %c | %c n", square[4], square[5],square[6]);
printf("____|_____|____n");
printf(" | | n");
printf(" %c | %c | %c n", square[7], square[8],square[9]);
printf(" | | n");
}
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}};
关于递归检查过程,这里是关于如何检查大小为n
的向量v
的任何元素是否满足属性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;
}
第2版:
所以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;
}
当然,你需要填写的条件可能有点太大,无法在if中内联。你可能想以不同的方式组织它,或者定义这样的辅助函数来完成这项工作。
这里还有一些对主代码的修改,显示了您所做的一些事情是如何变得更清晰的。
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';
}