我们将五子棋的棋盘用二维字符数组来进行表示,如何在其中一方下完棋之后判断场上的胜负呢?
五子棋盘用空格表示空位置,用字符*和#表示玩家,判断模块使用函数:
char if_win(char board[ROW][COL], int row, int col, int WIN);
这里提供了一种简单的遍历算法:
这是一个棋盘
判断胜负的方式有两种情况:
1,判断方式
这个棋盘是一个14*14的正方形,将棋盘数据用宏定义常量来存储,同时存下胜利需要的连珠个数
#define ROW 14
#define COL 14
#define WIN 5
以从左向右判断为例:定义一个变量flag=1
如果这个位置和右侧的子相同且不为空,就把flag的值加1。如果不符合上面的条件,就将flag设为1;flag值到了胜利条件:检测到连珠成立,则返回这个位置的字符,表明胜方,结束判断过程。不符合,一行检测完之后,换到下一行,继续检测,遍历所有的行。
flag1 = 1;
for (int b = 0; b < row-1; b++)
{
if ((board[b][a] == board[b + 1][a]) && (board[b][a] != ' '))
{
flag1++;
}
else
{
flag1 = 1;
}
if (flag1 == win)
{
return board[b][a];
}
}
使用这种标记判断的方式,我们可以写出所有的判断方式:
//行
for (int b = 0; b < row; b++)
{
flag2 = 1;
for (int a = 0; a < col - 1; a++)
{
if ((board[b][a] == board[b][a+1]) && (board[b][a] != ' '))
{
flag2++;
}
else
{
flag2 = 1;
}
if (flag2 == win)
{
return board[b][a];
}
}
}
//斜
for (int b = 0; b < row-1; b++)
{
flag3 = 1;
for (int a = 0; a < row - 1; a++)
{
for (; (a < col - 1) && (b < row - 1); a++, b++)
{
if ((board[b][a] == board[b + 1][a + 1]) && (board[b][a] != ' '))
{
flag3++;
}
else
{
flag3 = 1;
}
if (flag3 == win)
{
return board[b][a];
}
}
}
}
for (int b = 0; b < row- 1; b++)
{
flag4 = 1;
for (int a = col - 1; a > 0; a--)
{
for (; (a > 0) && (b < row - 1); a--, b++)
{
if ((board[b][a] == board[b + 1][a - 1]) && (board[b][a] != ' '))
{
flag4++;
}
else
{
flag4 = 1;
}
if (flag4 == win)
{
return board[b][a];
}
}
}
}
还有如果未检测出胜负,也可能有平局的情况。
所以要检测棋盘是否铺满:
if (is_full(board, row, col) == 1)
{
return 'Q';
}
int is_full(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
上述判断结束后,如果游戏未结束,则返回其他字符。根据返回的字符来决定游戏是否进行,或者进行胜者的判断。
2.优化代码的一种思路
以从左向右判断行为举例:
如果红线和红线右方的位置判断到空白 或者在红线右方检测到相邻棋子不相同。
比如上面这种情况,红线上的棋子和右边的棋子不同,那么后面就算是棋子全都一样,也不能达到胜利条件,这种情况下可以直接跳过判断。
斜向也可以这么做:
但是在棋盘大的情况下,这么做优化作用其实并不大,可以做一个参考方法。