有三种方法可以解决在井字游戏中检测获胜者的问题。有蛮力法、算法法和数据驱动法。
蛮力方法由一系列if 语句组成。由于赢得井字游戏只有 8 种方式,因此只需要 8 个if 语句来确定获胜者。因此,蛮力方法与其他方法相比表现良好,因为它具有相对较少的代码行数、简单易读的代码、相对较小的可执行文件大小和较快的执行速度。蛮力法是最好的方法,因为井字游戏是微不足道的。稍微复杂一点的游戏,比如四连线,可能需要更高级的编码技术,但井字游戏最好用简单的if 语句来解决。
算法方法已在此问题的其他回复中得到证明。 David Syzdek 的算法是迄今为止最好的算法,但在某种程度上是一种混合解决方案,因为它通过使用for 循环将八个if 语句减少到四个if 语句。请注意,他的算法仍然有散布在整个代码中的硬编码索引。
数据驱动的方法使用一个初始化的数据集来抽象问题,这样代码是完全通用的,所有的杂乱无章都被收集到数据集中。以下是使用数据驱动解决方案的代码。
typedef struct
{
int valid;
int rowA, colA;
int rowB, colB;
int rowC, colC;
}
stPath;
static stPath paths[] =
{
{ TRUE, 0, 0, 0, 1, 0, 2 }, // top row
{ TRUE, 1, 0, 1, 1, 1, 2 }, // middle row
{ TRUE, 2, 0, 2, 1, 2, 2 }, // bottom row
{ TRUE, 0, 0, 1, 0, 2, 0 }, // left column
{ TRUE, 0, 1, 1, 1, 2, 1 }, // middle column
{ TRUE, 0, 2, 1, 2, 2, 2 }, // right column
{ TRUE, 0, 0, 1, 1, 2, 2 }, // TL to BR diagonal
{ TRUE, 0, 2, 1, 1, 2, 0 }, // TR to BL diagonal
{ FALSE, 0, 0, 0, 0, 0, 0 } // end of list
};
int checkforwin( char board[3][3] )
{
int a, b, c;
stPath *pptr;
// assumes that board array uses 'X' 'O' and <sp> to mark each position
for ( pptr = paths; pptr->valid; pptr++ )
{
a = board[pptr->rowA][pptr->colA];
b = board[pptr->rowB][pptr->colB];
c = board[pptr->rowC][pptr->colC];
if ( a == b && b == c && a != ' ' )
return( (a == 'X') ? 1 : -1 );
}
return( 0 ); // no winner yet
}
请注意,我并不是在提倡使用数据驱动的解决方案来解决这个特定问题,因为问题本身太琐碎,无法保证数据驱动的解决方案。