目录
游戏规则
玩家先落子,再是电脑落子,玩家或者电脑在3*3的棋盘上最终落子为行或列或两个对角线三子相连,就认定为哪一方胜出。若棋盘满了,还没有出现三子相连则判为平局。
思路
1. 先打印菜单是否进行游戏
2. 1进行游戏 0退出游戏 其他 再次进行选择
3. 玩家下棋,判断输赢,赢游戏结束,没赢先判断棋盘是否填满,未满电脑下,再次判断输赢,赢游戏结束,没赢先判断棋盘是否填满,再去循环。
创建文件
为了代码简洁明了我们把代码按不同用途分为三个文件,分别是:game.h//头文件(用来包含所需头文件,define定义的常量,函数声明) game.c//游戏文件(要用到的功能函数)test.c//测试文件(代码的整合)
1、game.h//头文件
1.1 头文件
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
1.2用define定义行列
好处:以后需要改棋盘大小可以直接改
#define ROW 3
#define COL 3
1.32函数声明
//初始化棋盘
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);
//判断输赢
char IsWin(char board[ROW][COL], int row, int col);
//电脑下棋
//随机下棋
void ComputerMove(char board[ROW][COL], int row, int col);
2.test.c//游戏测试
2.1主函数
int main()
{
int input = 0;
do
{
menu();//打印菜单
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误!\n");
break;
}
} while (input);
return 0;
}
switch语句:实现了玩家不同选择的实现
do while循环语句:实现先运行主函数,再进行选择进入循环。
2.2对主函数内容的分析
menu()函数(菜单函数)
void menu()
{
printf("*************************\n");
printf("***** 1.play 0. exit****\n");
printf("*************************\n");
}
2.3game()函数
void game()
{
srand((unsigned int)time(NULL));//设置随机数的函数
char ret = 0;
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 != 'C')
{
break;
}
ComputerMove(board, ROW, COL);//电脑下棋
DisplayBoard(board, ROW, COL);//打印棋盘
if (ret != 'C')
{
break;
}
}
if ('*' == ret)
printf("玩家赢\n");
else if ('#' == ret)
printf("电脑赢\n");
else
printf("平局\n");
}
game()函数中包含了初始化棋盘函数、显示棋盘函数、玩家下棋函数、电脑下棋函数、判断输赢函数的调用。
3.game.c//游戏功能实现
3.1 初始化棋盘函数
定义InitBoard()函数,代码:
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] = ' ';
}
}
}
3.2 打印棋盘函数
定义 DisplayBoard()函数,代码:
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)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
} printf("\n");
}
}
3.3玩家下棋
定义Player Move()函数,代码:
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下:>");
while (1)
{
printf("请输入坐标:>");
scanf("%d %d", &x, &y);
//坐标范围合法的判断
if ((x >= 1 && x <= row) &&( y >= 1 && y <= col))
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标被占用,不能下棋,请选择为其他位置\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
注意:我们写代码的时候知道第一个位置的坐标为(0,0),但玩家一般默认第一个位置坐标为(1,1)。所以写程序时要把位置写成(x-1,y-1)。
3.4电脑下棋
定义Computer Move()函数,代码:
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("请电脑下棋:>\n");
while (1)
{
x = rand() % row;//0-2
y = rand() % col;//0-2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
要电脑随机输入一个随机坐标,我用时间戳来实现srand()函数生成随机数字,使用时间戳需要调用time函数,代码:
#include<time.h>
srand()函数的使用:
srand((unsigned int)time[NULL])
对srand()函数生成的随机数进行处理,达到使用范围:
x = rand() % row;//0-2
y = rand() % col;//0-2
3.5 判断输赢
定义IsWin()函数,代码:
//判断输赢
//玩家赢 -- '*'
//电脑赢 -- '#'
//平局 -- 'Q'
//继续 -- 'C'
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][0] != ' ')
return board[i][0];//如果连成,返回哪个符号就是谁赢
}
for (i = 0; i < col; i++)//连成行
{
if (board[0][i] == board[1][i] && board[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[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
if (1 == IsFull(board, row, col))
{
return 'Q';
}
return 'C';
}
三行连成代码:
for (i = 0; i < row; i++)//连成三行
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
return board[i][0];//如果连成,返回哪个符号就是谁赢
}
三列连成:
for (i = 0; i < col; i++)//连成列
{
if (board[0][i] == board[1][i] && board[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[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
平局判断:
如果棋盘填满还没有分出胜负则为平局
遍历棋盘的每一个格子,如果没有一个是空格了,就返回数字 1 ,否则返回数字 0 。
定义IsFull()函数,代码:
int IsFull(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;
}
判断1==IsFull(),返回c 代码继续循环,返回Q平局。
if (1 == IsFull(board, row, col))
{
return 'Q';
}
return 'C';
}
4.game()函数详解
void game()
{
srand((unsigned int)time(NULL));//设置随机数的函数
char ret = 0;
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 != 'C')
{
break;
}
ComputerMove(board, ROW, COL);//电脑下棋
DisplayBoard(board, ROW, COL);//打印棋盘
if (ret != 'C')
{
break;
}
}
if ('*' == ret)
printf("玩家赢\n");
else if ('#' == ret)
printf("电脑赢\n");
else
printf("平局\n");
}
思路逻辑:1.创建一个数组 2.初始化棋盘- 打印棋盘 3. 玩家下棋 -- 打印棋盘 -- 判断输赢(赢/输/平局:本局结束;没结果:继续)4. 电脑下棋 -- 打印棋盘 -- 判断输赢 (赢/输/平局:本局结束;没结果:继续)