game.h ##//头文件申明函数
#ifndef _GAME_H_
#define _GAME_H_
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3//棋盘的行数
#define COL 3//棋盘的列数
void InitBoard(char board[ROW][COL], int row, int col);//初始化棋盘
void PutBoard(char board[ROW][COL],int x,int y,char flag);//打印棋盘
int SorkBoard(char board[ROW][COL], int row, int col);//判断输赢
int Win(char board[ROW][COL]);
#endif
#ifndef _头文件名大写_H_
#define _头文件名大写_H_
#endif
//在头文件中,如果你有两个C文件。这两个c文件中都include了同一个头文件,而编译时,这两个c文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。如果用以上三行代码,就可以避免冲突发生。
game.c
#include "game.h";
/*
函数作用:初始化一个棋盘
控制打印出九宫格,来表示棋盘
*/
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
if (i < row - 1)
{
printf("---|---|---\n");
}
}
}
/*
函数作用:打印落子后的棋盘
*玩家落子(输入坐标的方式)为0
*电脑落子(随机坐标)为X
*/
void PutBoard(char board[ROW][COL],int x,int y,char flag)
{
board[x][y] = flag;
InitBoard(board, ROW, COL);
}
/*
函数作用:判断游戏结束
分四种情况:
*相同三个子同一行
*相同三个字同一列
*两个斜边同一个子
*棋盘满
*/
int SorkBoard(char board[ROW][COL], int row, int col)
{
char flag = 0;
//一行三个字符一样
int i = 0;
int k = 0;
int j = 0;
for (i = 0; i < col; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
flag=board[i][0];
return flag;
}
if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
{
flag=board[0][i];
return flag;
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
flag=board[1][1];
return flag;
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
{
flag=board[2][0];
return flag;
}
for (i = 0; i < row;i++)
for (j = 0; j < col; j++)
{
if (board[i][j] == '0' || board[i][j] == 'x')
k++;
}
if (k==ROW*COL)
return k;
}
/*
函数作用:判断输赢
结局分四种情况:
*玩家赢
*电脑赢
*平局
*继续游戏
*/
int Win(char board[ROW][COL])
{
//判断输赢
if (SorkBoard(board, ROW, COL) == '0')
{
printf("玩家赢!\n");
return 0;
}
else if (SorkBoard(board, ROW, COL) == 'x')
{
printf("电脑赢!\n");
return 0;
}
else if (SorkBoard(board, ROW, COL) == ROW*COL)
{
printf("平局!\n");
return 0;
}
else
return 1;
}
游戏.c
#include "game.h";
/*
函数作用:打印菜单
*/
void menu()
{
printf("*****************************************\n");
printf("******* 1.play 0.exit ********\n");
printf("*****************************************\n");
}
void game(char board[ROW][COL])
{
while (1)
{
//玩家下棋
int x = 0;
int y = 0;
char flag = 0;
printf("请玩家下棋(输入坐标):");
scanf("%d%d", &x, &y);
flag = '0';
while (board[x][y] == '0'||board[x][y] == 'x')
{
printf("输入有误,请重新输入:\n");
scanf("%d%d", &x, &y);
}//如果坐标已经被占用,重新生成坐标
PutBoard(board, x, y, flag);
if (Win(board) == 0)//判断输赢
break;
//电脑下棋
x = rand() % ROW;//生成随机0-2的数
y = rand() % COL;//生成随机0-2的数
flag = 'x';
while (board[x][y] == '0'||board[x][y] == 'x')
{
x = rand() % ROW;
y = rand() % COL;
}//如果坐标已经被占用,重新生成坐标
PutBoard(board, x, y, flag);
if (Win(board) == 0)//判断输赢
break;
}
}
int main()
{
char board[ROW][COL] = { 0 };//三子棋的实现其实是基于二维数组的
int n = 0;
srand((unsigned)time(NULL));//生成随机数
do
{
menu();
while (scanf("%d", &n) == 0)
{
printf("输入错误!\n");
getchar();
}//如果输出的是字符,提示输出错误
if (n == 1)
{
memset(board, ' ', ROW*COL);
InitBoard(board, ROW, COL);
game(board);
}
else if (n == 0)
{
printf("退出游戏!\n");
break;
}
else
{
printf("输入错误,请重新输入:\n");
}
} while (1);
system("pause");
return 0;
}