这儿为了提前适应集成开发,我把全部代码按功能分为了三大块,主函数、头文件、函数定义。
目录
一、源代码
test.c主函数
game.h头文件
game.c函数定义
二、解析
1、引用自定义函数
2.打印菜单
3.游戏基本逻辑的实现
(1)棋盘逻辑
(2)棋盘的定义与初始化
(3) 下棋的逻辑
(4)输赢判断的逻辑
(5)输赢判断的具体实现
(6) 棋子的判断
(7)主函数中的集成
(8)函数的声明
结束语
#include "game.h"
void meun()
{
printf("**********************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("**********************\n");
}
void game() {
char ret = 0;
char board[ROW][COL] = {0};
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DispalyBoard(board, ROW, COL);
//下棋
while (1)
{
//玩家下棋
PalyerMove(board, ROW, COL);
DispalyBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board,ROW,COL);
if (ret != 'C')
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
DispalyBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢!\n\n");
}
if (ret == '#')
{
printf("电脑赢\n\n");
}
if (ret == 'Q')
{
printf("平局\n\n");
}
DispalyBoard(board, ROW, COL);
}
int main() {
srand( (unsigned int )time(NULL) ); //设置随机数的生成起点
int input = 0;
do
{
meun(); //打印菜单
printf("请选择:>");
scanf("%d",&input);
switch (input)
{
case 1:
game(); //printf("三子棋");
break;
case 0:
printf("退出游戏");
break;
default:
printf("选择错误,请重新选择:>\n");
break;
}
} while (input);
return 0;
}
#include
#include
#include
#define ROW 3
#define COL 3
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DispalyBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PalyerMove(char board[ROW][COL], int row, int col);
//电脑下棋 随机
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL],int row, int col);
#include "game.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 DispalyBoard(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\n");
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");
}
}
}
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col){
printf("电脑下棋:>\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row; //规定范围为0~2
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判断棋盘是否满了
//满了返回1
//否则返回0
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;
}
//判断输赢
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];
}
}
//列的判断
int j = 0;
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
{
return board[1][j];
}
}
//对角线的判断
if (board[0][0] == board[1][1] && board[1][1] == board[2][1] &&board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][2] &&board[1][1] != ' ')
{
return board[1][1];
}
//平局的判断
if ( IsFull(board , row , col) )
{
return 'Q';
}
//游戏继续
return 'C';
}
在我们编程代码的时候一定不能忘记的就是引入头文件,我们常常在使用库函数的时候就需要这一步,比如我们在使用 printf() 的时候就需要引入
stdio 就是指 “standard input & output"(标准输入输出)
而在我们实际的大型工程下面我们常常需要自己自定义一个函数来实现某个功能,这时我们就需要自己模拟一个函数的定义、声明与调用哦 (⊙o⊙) !
例如我们在 game.h头文件 中声明一些我们需要的函数,在 game.c函数定义 中定义它们,最后在 test.c主函数 中集中实现它们,这就是一个工程项目的基本步骤。
但是我们在引用自己定义的函数的时候就与引用库函数有点区别了。
引用库函数
#include
#include
#include
引用自定义函数
#include "game.h"
我们需要注意的是,当我们在一个自定义函数中声明,或者引用某一些库函数的时候只需要引用一次就够了。
例如我们在 game.h 中引入了,在另一个函数中是不需要重复声明。只需要引入 game.h 就行了
#include
#include
#include
void meun()
{
printf("**********************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("**********************\n");
}
void game() {
char ret = 0;
char board[ROW][COL] = {0};
//初始化棋盘
InitBoard(board, ROW, COL); //在下棋的时候我们需要一张干净的棋盘,因此我们需要初始化一
//个棋盘
//打印棋盘 //初始化之后,我们就将其打印出来方便观看
DispalyBoard(board, ROW, COL);
}
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 DispalyBoard(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
//下棋
while (1) //这是一个死循环,我们让它一直工作直到得到我们想要的
{
//玩家下棋
PalyerMove(board, ROW, COL); //函数的调用,下棋时我们需要把棋盘、行与列传过去
DispalyBoard(board, ROW, COL); //下完之后我们再打印出来
//判断输赢 //当我们下完一次后需要判断一次是否出现了赢的局面
ret = IsWin(board,ROW,COL);
if (ret != 'C') //当函数的返回值不为 C 的时候就说明出现了游戏结束的居面
{ //这时我们就跳出整个循环 然后判断是谁输赢
break;
}
//电脑下棋 //同上
ComputerMove(board, ROW, COL);
DispalyBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*') //输赢判断
{
printf("玩家赢!\n\n"); //这里我们是根据返回值来判断输赢的
}
if (ret == '#') //玩家赢 - '*'
{ //电脑赢 - '#'
printf("电脑赢\n\n"); //平局 - 'Q'
} //继续 - 'C'
if (ret == 'Q')
{ //需要注意的是这是我们自己定义的返回值,
printf("平局\n\n"); //当然我们可以定义其它的值,我们需要什么就让它返回什么
}
DispalyBoard(board, ROW, COL);
//判断输赢
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]; //我们只需要返回一个值就行了
} //这里就是我们定义的谁下什么棋就让它返回什么值
}
//列的判断
int j = 0;
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
{
return board[1][j];
}
}
//对角线的判断
if (board[0][0] == board[1][1] && board[1][1] == board[2][1] &&board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][2] &&board[1][1] != ' ')
{
return board[1][1];
}
//平局的判断
if ( IsFull(board , row , col) ) //平局的判断,我们同样也写成一个函数
{
return 'Q';
}
//游戏继续
return 'C';
}
平局
//判断棋盘是否满了
//满了返回1
//否则返回0
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;
}
玩家的判断
//玩家下棋
void PalyerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("请下棋:>\n");
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");
}
}
}
电脑的判断
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col){
printf("电脑下棋:>\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row; //规定范围为0~2
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int main() {
srand( (unsigned int )time(NULL) ); //设置随机数的生成起点
int input = 0;
do //do…while循环,来实现
{
meun(); //打印菜单
printf("请选择:>");
scanf("%d",&input); //玩家输入选择
switch (input)
{
case 1:
game(); //进入游戏
break;
case 0:
printf("退出游戏");
break;
default:
printf("选择错误,请重新选择:>\n");
break;
}
} while (input); //当输入 0 时退出游戏
return 0;
}
关于这随机数的产生可以参考 https://blog.csdn.net/weixin_67595436/article/details/124357160
srand( (unsigned int )time(NULL) ); //设置随机数的生成起点
#include
#include
#include
#define ROW 3 行
#define COL 3 列
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DispalyBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PalyerMove(char board[ROW][COL], int row, int col);
//电脑下棋 随机
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢 //这是我们自己定义的
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL],int row, int col);
梦还是得做的,因为梦是自己内心渴望的表现,希望当学成归来之时,你还是一个有梦之人……
未完持续……