我知道人们之前会问这个,但我不明白答案。
假设您在函数中有char board[3][3]
作为参数
如果X赢了,你需要返回1,如果O赢了,你需要返回-1;如果没有赢,你需要返回0或者如果它是平局,则需要返回0。
int checkforwin(char board[3][3]);
该功能的声明。
对于其中一个对手获胜的非原始测试有什么想法吗?
答案 0 :(得分:2)
我可能会做类似以下的事情。您可以使用不带for循环的if语句,但这会减小源代码的大小。
// board[3][3]:
// [0][0] | [1][0] | [2][0]
// -------+--------+-------
// [0][1] | [1][1] | [2][1]
// -------+--------+-------
// [0][2] | [1][2] | [2][2]
//
int checkforwin(char board[3][3])
{
int x;
for(x = 0; x < 3; x++)
{
// check vertical lines
if ((board[x][0] != '\0') &&
(board[x][0] == board[x][1]) &&
(board[x][0] == board[x][2]))
return(board[x][0] == 'O' ? -1 : 1);
// check horizontal lines
if ((board[0][x] != '\0') &&
(board[0][x] == board[1][x]) &&
(board[0][x] == board[2][x]))
return(board[0][x] == 'O' ? -1 : 1);
};
// check top left to bottom right diagonal line
if ((board[0][0] != '\0') &&
(board[0][0] == board[1][1]) &&
(board[0][0] == board[2][2]))
return(board[0][0] == 'O' ? -1 : 1);
// check bottom left to top right diagonal line
if ((board[2][0] != '\0') &&
(board[2][0] == board[1][1]) &&
(board[0][0] == board[0][2]))
return(board[2][0] == 'O' ? -1 : 1);
// no winner
return 0;
}
答案 1 :(得分:2)
这个对每行/列/对角线进行计数。
如果计数达到3,则表示一行中有三个X
同样,-3表示一行中有三个O
任何其他值表示没有赢家。
代码中有4个块:
这有很多重复的代码,违反了良好代码的DRY原则 但这很容易理解。
int CheckTicTacToe(char board[3][3])
{
int count = 0;
int row, col;
// Check each of 3 rows:
for(row = 0; row < 3; ++row)
{
count = 0;
for(col=0; col < 3; ++col)
{
count += (board[row][col] == 'X')? 1 :
(board[row][col] == 'O')? -1 : 0;
}
if (count == 3 || count == -3)
{
return count / abs(count); // Return either 1 or -1
}
}
// Check each of 3 columns.
for(col = 0; col < 3; ++col)
{
count = 0;
for(row=0; row < 3; ++row)
{
count += (board[row][col] == 'X')? 1 :
(board[row][col] == 'O')? -1 : 0;
}
if (count == 3 || count == -3)
{
return count / abs(count); // Return either 1 or -1
}
}
// Check Left-to-Right downward Diagonal:
count = 0;
for(col = 0; col < 3; ++col)
{
count += (board[col][col] == 'X')? 1 :
(board[col][col] == 'O')? -1 : 0;
}
if (count == 3 || count == -3)
{
return count / abs(count); // Return either 1 or -1
}
// Check Left-to-Right upward Diagonal
count = 0;
for(col = 0; col < 3; ++col)
{
count += (board[col][2-col] == 'X')? 1 :
(board[col][2-col] == 'O')? -1 : 0;
}
if (count == 3 || count == -3)
{
return count / abs(count); // Return either 1 or -1
}
return 0;
}
答案 2 :(得分:2)
有三种方法可以解决在井字游戏中检测获胜者的问题。有蛮力方法,算法方法和数据驱动方法。
蛮力方法由一系列if
语句组成。由于只有8种方式可以赢得井字游戏,因此只需要8个if
语句来确定获胜者。因此,强力方法与其他方法相比较,因为它具有相对少量的代码行,简单,易于读取的代码,相对小的可执行大小和快速的执行速度。蛮力方法是最好的方法,因为井字游戏是微不足道的。像Connect Four这样稍微复杂的游戏可能需要更高级的编码技术,但是使用简单的if
语句可以最好地解决井字游戏问题。
算法方法已在对此问题的其他回答中得到证明。 David Syzdek的算法是迄今为止最好的算法,但在某种程度上是混合解决方案,因为它通过使用{{1}将八个if
语句减少到四个if
语句循环。请注意,他的算法仍然在整个代码中分散了硬编码索引。
数据驱动方法使用初始化数据集来抽象问题,以便代码完全通用,并且所有混乱都被收集到数据集中。以下是使用数据驱动解决方案的代码。
for
请注意,我并未提倡针对此特定问题的数据驱动解决方案,因为问题本身太过微不足以保证数据驱动的解决方案。
答案 3 :(得分:0)
if语句是采用这种数据结构的方法。您可以使用位掩码,但在给定数据结构的情况下使用字符串元素('X' 'O'
),位掩码将非常难看并且只会使事情变得不必要地复杂。使用If语句进行测试的最短和最清晰的方法。
如果您使用了不同的数据结构,则可能会使事情变得更简单。例如,如果电路板存储为位数组“011011001
”,则位掩码更清晰。