一、五子棋的基本构成元素
1.棋子
五子棋分黑白两色,形状为扁圆形。双方进行博弈时要将棋子下在棋盘的交叉点处。
棋子符号包括:
黑子:○ 白子:●
棋盘每一个位置分为三种状态,白子、黑子、空白。这里我们用$表示黑子,#表示白子
2、棋盘
棋盘可以抽象为一个二维数组char board[i][j],存储棋子的下标位置
二、五子棋下棋过程
1、绘制棋盘、棋子
2、执黑子的玩家先落子,然后双方轮流落子
3、判断胜负或平局
4、退出游戏
三、五子棋整体框架分析
五子棋的整体框架包括棋盘构建、棋盘显示、下棋落子、判断输赢、主函数五个部分。
1、构建棋盘
棋盘的构建我们选择用 '+' 来表示,这里我们先构建一个 9*9 的棋盘,如图1所示。

代码展示:
/初始化棋盘
void init_board()
{
for(i=0;i<9;i++)
{
for(j=0;j<9;j++)
{
board[i][j]='+';
}
}
}
2、显示棋盘
因为棋盘是一个平面图,有行有列,所以棋盘的显示需要使用 for(;;)的嵌套循环。
代码展示:
//显示器棋盘
void show_board()
{
printf(" 0 1 2 3 4 5 6 7 8 \n");
//显示棋盘
for(i=0;i<9;i++)
{
printf("%d",i);
for(j=0;j<9;j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
}
3、下去落子
下棋落子时,需要判断输入的坐标是否在棋盘上 以及该位置是否已经有棋子两种情况,当下子坐标在棋盘上并且没有棋子是,下子成功,否则下子无效,重新输入坐标。
代码展示:
void input(char A) //下子
{
int x,y; //棋子坐标
int sum; //计数
char buf[20]={0};
while(1)
{
printf("请输入棋子(%c)的坐标:",A);
sum=scanf("%d %d",&x,&y);
if(sum != 2)
{
fgets(buf,sizeof(buf),stdin);
if(strcmp(buf,"surrender\n") == 0)
{//用户输入surrender投降认输
printf("%c投降认输!\n",A);
exit(0);//结束对弈,退出程序
}
else
{
printf("没有该命令!请重新输入棋子坐标%s",buf);
continue;//返回到if中 重新输入棋子坐标
}
}
//吸收残留
fgets(buf,sizeof(buf),stdin);
if(x<0 || x>9 || y<0 || y>9 || board[x][y] != '+')
{
printf("输入的坐标%d %d不在棋盘内或坐标已有棋子\n",x,y);
continue;
}
board[x][y] = A;
sum++;
this_x = x;
this_y = y;
return;
}
}
4、判断输赢
若存在有五颗棋子能连续的连成一条直线,则可判断输赢,对弈结束。当下子次数小于9次时,无论是黑棋还是白棋,两方都不会有输赢,所以判断是否有五子连成一条直线时,可从第9次下棋开始判断。
五子连成一条直线共有8个方向的判定,即竖直向上、竖直向下、横着向左、横着向右、左斜向上、左斜向下、右斜向上、右斜向下。
代码展示:
//判断输赢
int is_win(void)
{
int s=1;
int sum=1;//统计连子的个数
if(sum<=9)//棋子个数少于9个不可能有输赢
return 0;
//竖直方向的直线判定
for(i=1;i<5;i++)
{
if(this_x - i < 0)//判断是否越界
break;
if(board[this_x][this_y] == board[this_x-i][this_y] )
s++;
else //是否连续
break;
}
for(i=0;i<5;i++)
{
if(this_x + i>=9)
break;
if(board[this_x][this_y] == board[this_x + i][this_y])
s++;
else
break;
}
if(s>=5)
return 1;//有一方获胜
// s=0;
//横向直线方向判定
for(i=1;i<5;i++)
{
if(this_y - i < 0)//判断是否越界
break;
if(board[this_x][this_y] == board[this_x][this_y - i] )
s++;
else //是否连续
break;
}
for(i=1;i<5;i++)
{
if(this_x + i >=9)
break;
if(board[this_x][this_y] == board[this_x][this_y + i])
s++;
else
break;
}
if(sum>=5)
return 1;//有一方获胜
// s=0;
//斜线方向(\)上的直线判定
for(i=1;i<5;i++)
{
if(this_x-i < 0 || this_y - i < 0)//判断是否越界
break;
if(board[this_x][this_y] == board[this_x - i][this_y - i] )
s++;
else //是否连续
break;
}
for(i=1;i<5;i++)
{
if(this_x + i >= 9 || this_y + i >=9)//判断是否越界
break;
if(board[this_x][this_y] == board[this_x + i][this_y + i])
s++;
else
break;
}
if(s>=5)
return 1;//有一方获胜
// s=0;
//斜线方向(/)的直线判定
for(i=1;i<5;i++)
{
if(this_x-i < 0 || this_y + i >= 9)//判断是否越界
break;
if(board[this_x][this_y] == board[this_x - i][this_y + i] )
s++;
else //是否连续
break;
}
for(i=1;i<5;i++)
{
if(this_x+i >= 9 || this_y - i < 0)//判断是否越界
break;
if(board[this_x][this_y] == board[this_x + i][this_y - i])
s++;
else
break;
}
if(s>=5)
return 1;//有一方获胜
s=0;
return 0;
}
五、主函数
在主函数中调用构建棋盘函数 (init_board() )、显示棋盘函数 (show_board() )、棋盘落子函数 ( input())、判断输赢函数(is_win() ) 。
代码展示:
int main()
{
init_board(); //初始化棋盘
show_board(); //显示器棋盘
while(1)
{
input('$'); //请 白子 输入
show_board(); //显示器棋盘
if(is_win())
{
printf("白子胜利!");
break; //赢否
}
input('#'); //请 黑子 输入
show_board(); //显示器棋盘
if(is_win())
{
printf("黑子胜利!");
break; //赢否
}
}
}