三子棋游戏[game.h] //放函数声明
#define ROW 3 //可以在这里更改行数
#define COL 3 //更改列数
#include<stdio.h>
#include<stdlib.h> //srand生成随机数的头文件
#include<time.h> // time生成时间戳的头文件
void InitBoard(char board[ROW][COL],int row,int col);
void DisplayBoard(char board[ROW][COL],int row,int col);
void PlayerMove(char board[ROW][COL],int row,int col);
void ComputerMore(char board[ROW][COL],int row,int col);
char IsWin(char board[ROW][COL],int row,int col);
[game.c] //放函数定义
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h" //引用.h里的文件
void InitBoard(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++)
{
board[i][j]=’ ’; //将棋盘初始化
}
}
}
void DisplayBoard(char board[ROW][COL],int row,int col) //实现棋盘的外观
{
int i=0;
for(i=0;i<row;i++) //定位所有行
{
int j=0;
for(j=0;j<col;j++) //定位循环里的第一列
{
printf(" %c ",board[i][j]); //创建一个 | | ......的棋盘第一行样子
if(j<col-1) //记得去掉最后一列|保证棋盘美观性
printf("|");
}
printf("\n"); //承接上面的行转入下一行
if(i<row-1) //同样去掉最下面的一行---
{
for (j=0;j<col;j++) //定位棋盘的第二行---|---|---......
{
printf("---");
if(j<col-1) //定位循环里的第二列
printf("|");
}
printf("\n"); //换行,此时已经将重复的两行模板建好,进入之后的循环就
可以一直循环显示出上面第一行与第二行的内容
}
}
}
void PlayerMove(char board[ROW][COL],int row,int col)
{
int x=0;
int y=0;
printf("玩家操作:\n");
while(1)
{
printf("请输入要下的坐标:");
scanf("%d%d",&x,&y);
//下面判断x,y坐标合法性
if(x>=1&&x<=row&&y>=1&&y<=col) //考虑到玩家一般使用从1开始的坐标
,所以将程序里的0对应玩家输入的
1(用户友好)
{
if(board[x-1][y-1]==’ ’) //检查该位置是否被下过子了
{
board[x-1[]y-1]=’*’;
break; //落子成功,跳出while
}
else
{
printf("该坐标被占用");
}
}
else
{
printf("坐标非法,请重新输入!\n");
}
}
}
void ComputerMove(char board[ROW][COL],int row,int col)
{
int x=0;
int y=0;
printf("电脑走:\n");
while(1)
{
x=rand()%row; // 将随机数变化为在row的范围内
y=rand()%col; //同理
if(board[x][y]==’ ’) //此处是判断电脑选出的坐标是否没有被落过子
;这里的x,y是系统生成的具有0的坐标,所
以不用和上面玩家一样减一
{
board[x][y]=’#’; //电脑落子
break;
}
}
}
int IsFull(char board[ROW][COL],int row,int col) //返回1表示满了0是没有
{
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; //满了
}
char IsWin(char board[ROW][COL],int row,int col) //判断是否有三子相连
{
int i=0;
//判断平行相邻的三个框内是否图案一致
for(i=0;i<row;i++)
{
if(board[i][0]==board[i][1]&&board[i][1]==board[i][2]&&board[i][1]!=’ ')
{
return board[i][1];
}
}
//判断水平相邻的三个框内是否图案一致
for(i=0;i<col;i++)
{
if(board[0][i]==board[1][i]&&voard[1][i]==board[2][i]&&board[0][i]!=’ ’)
{
return board[0][i];
}
}
//判断右斜或左斜相邻的三个框内是否图案一致
if(board[0][0]==board[1][1]&&board[1][1]==board[2][2]&&board[1][1]!=’ ')
return board[1][1];
if(board[2][0]==board[1][1]&&board[1][1]==board[0][2]&&board[1][1]!=’ ')
return board[1][1];
//判断是否平局
if(1==IsFull(board,ROW,COL))
{
return 'O’;
}
return 'X’;
}
[test.c] //测试
#define _CRT_SECURE_NO_WARNINGS 1 //解除不安全警告,也可全文件都定
义,方法之前有
#include<stdio.h>
#include"game.h" //引用自定义的头文件里的ROW与COL
void menu()
{
printf("****************************\n");
printf("****1.play*******2.exit*******\n");
printf("****************************\n");
}
void game()
{
char ret=0; //用来接收IsWin的返回值
char board[ROW][COL]={0}; //创建数组,存放棋盘信息
InitBoard(board,ROW,COL); //初始化棋盘(进入空白棋盘的创建函数)
DisplayBoard(board,ROW,COL); //打印棋盘(将空白棋盘改变为初始的棋盘)
while (1)
{
PlayerMove(board,ROW,COL); //玩家下棋
DisplayBoard(board,ROW,COL); //打印棋盘
ret=IsWin(board,ROW,COL); //判断玩家是否赢
if(ret!=’X’) //判断是否应该继续下棋
{
break;
}
ComputerMove(board,ROW,COL); //电脑下棋
DisplayBoard(board,ROW,COL); //再次打印棋盘
ret=IsWin(board,ROW,COL); //判断电脑是否赢
//所以此处的IsWin要可以判断四种结果:玩家胜利(*)
,电脑胜利(#),平局(O),继续(X)
if(ret!=’X’)
{
break;
}
}
if(ret==’*’)
{
printf("玩家胜利\n");
}
else if(ret==’#’)
{
printf("电脑胜利\n");
}
else
{
printf("平局\n");
}
}
void test()
{
int input=0;
srand((unsigned int)time(NULL)); // time返回时间戳作为随机数;int作用为
强制转化为整型
do
{
menu();
printf("请输入选择:");
scanf("%d",&input);
switch(input)
{
case 1:
game();
printf("三子棋\n");
break;
case 2:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}while (input); //如果input为真(除0外的数字)则循环继续,反之
,结束循环
}
int main()
{
test();
return 0;
}
|