三子棋是五子棋的简化版,原理和五子棋一样
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
//1.定义棋盘:二维数组
//2.初始化棋盘
//3.先打印一下棋盘
//4.用户下一步棋,顺便检查一下游戏是否结束
//5.电脑下一步棋,顺便检查一下游戏是否结束
//6.回到3
//游戏结束标志:(1)其中一个赢(2)平局,棋盘已满
void InitBoard(char board[ROW][COL])
{
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
board[row][col] = ' ';
}
}
}
void PrintBoard(char board[ROW][COL])
{
for (int row = 0; row < ROW; row++)
{
printf("| %c | %c | %c |\n", board[row][0],board[row][1],board[row][2]);
if (row < 2)
{
printf("|---|---|---|\n");
}
}
}
//x代表用户,o代表电脑
//
void UserMove(char board[ROW][COL])
{
//
//首先提示用户输入坐标,判断输入合法性
//(1)若不合法
//a)数组的坐标越界:提示重新输入
//b)当前位置已经有子:提示当前位置已有子,请重新输入
//(2)若合法,把当前位置字符置为'x'
//
int row = 0;
int col = 0;
printf("请输入坐标:");
while (1)
{
scanf("%d %d", &row, &col);
//输入坐标超出范围
if (!((row >= 0 && row < 3) && (col >= 0 && col<3)))
{
printf("输入坐标已超出范围,请重新输入:");
continue;
}
//输入坐标未超出范围
//1)当前位置已经有子:重新输入坐标
//2)当前位置已经无子:置'x'
else
{
if (board[row][col] != ' ')
{
printf("当前位置已经有子,请重新输入:");
continue;
}
else
{
board[row][col] = 'x';
break;
}
}
}
}
void ComputerMove(char board[ROW][COL])
{
//电脑产生两个随机数,分别代表其下子的横纵坐标
//检测是否合法
//a)若产生的数字不合法:(这里的不合法只有一种情况)当前位置已经有子
//b)若产生的数字合法:置'o'
while (1)
{
int row = rand() % ROW;
int col = rand() % COL;
if (board[row][col] != ' ')
{
continue;
}
else
{
board[row][col] = 'o';
break;
}
}
}
//检查棋盘是否已满,满了返回1,不满返回0
int IsFull(char board[ROW][COL])
{
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (board[row][col] != ' ')
{
continue;
}
else
{
return 0;
}
}
}
return 1;
}
//此函数只检测出有无获胜者(或者说判定游戏有没有结束),不需要具体验证出具体获胜者是谁
char CheckWinner(char board[ROW][COL])
{
//检查所有的行是否连在一起,有两种情况
//a) 都是' ':
//b)是x或o:
//只需要返回位置字符即可,返回的字符可以判断游戏要不要结束
//检查所有的列是否连在一起,有两种情况
//a) 都是' ':
//b)是x或o:
//只需要返回位置字符即可,返回的字符可以判断游戏要不要结束
//检查两条对角线,同理也有上面两种情况
//检查和棋
///
//检查行
for (int row = 0; row < ROW; row++)
{
if (board[row][0] == board[row][1] && board[row][1] == board[row][2])
{
return board[row][0];
}
}
//检查列
for (int col = 0; col < COL; col++)
{
if (board[0][col] == board[1][col] && board[1][col] == board[2][col])
{
return board[0][col];
}
}
//检查两条对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]
|| board[0][2] == board[1][1] && board[1][1] == board[2][0])
{
return board[1][1];
}
//检查和棋:和棋指的是棋盘已满,但是二者谁都未胜
//棋盘已满有两种情况:
//1)谁都未胜,x|x|o
// o|o|x
// x|o|x
//2)刚满,有一方胜 o|x|o
// x|x|x
// o|x|o, 其中[1][1]的x是最后一步下的
//但是由于程序的执行是按步骤从上到下的,所以出现2)情况时,
//首先进入 CheckWinner函数会执行:检查行、列、对角线,然后就返回了,不会再执行到检查和棋
if (IsFull(board))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
char board[ROW][COL];
InitBoard(board);
char winner = ' ';
while (1)
{
PrintBoard(board);
//4.用户下一步棋,顺便检查一下游戏是否结束
UserMove(board);
//PrintBoard(board);
winner = CheckWinner(board);
if (winner != ' '&&winner!=0)//返回结果:x or o or 1 or 0
{
//游戏结束
break;
}
//5.电脑下一步棋,顺便检查一下游戏是否结束
ComputerMove(board);
//PrintBoard(board);
winner = CheckWinner(board);
if (winner != ' '&&winner != 0)
{
//游戏结束
break;
}
}
//出了while循环,说明游戏结束
PrintBoard(board);
if (winner == 'x')
{
printf("用户赢\n");
}
else if (winner == 'o')
{
printf("电脑赢\n");
}
else if (winner == 1)
{
printf("和棋\n");
}
system("pause");
return 0;
}