系列文章目录
三子棋需要运用到函数,循环,分支语句。考察这些所学知识的运用。在此写三子棋代码可以进行分文件编写。这样可以使得代码更加清晰,分工明确,易于编写。
前言
要想使用C语言写出三子棋游戏就得了解三子棋的的游戏规则。
三子棋的棋盘是3X3的棋盘,获胜规则是在横线,竖线,斜线上有三个一样符号就算获胜,平局是整个棋盘都下满之后还没有出现三个连在一起的一样的符号则算平局。当然你中间还得考虑相同的位置不能重复落子。
提示:以下是本篇文章正文内容,下面案例可供参考
一、分文件编写是什么?
C语言分文件编写是将C程序按照功能模块划分,分别编写在不同的文件中,然后通过头文件和函数声明来实现文件的相互调用和协作。这种方式可以提高程序的可读性和维护性,同时也方便代码的复用。一般情况下,一个C程序可以被分为多个源文件(.c文件)和头文件(.h文件),每个源文件都包含一个或多个函数的定义,而头文件则包含这些函数的声明和相关的宏定义和数据结构的定义。在编译时,将所有的源文件和头文件一起编译链接,生成最终的可执行文件。
二、分文件编写代码
1.代码编写
1、创建test.c文件作为主业,用来进行主函数编写和调用函数。
2、编写基础主函数
#include "game.h"
void menu()
{
printf("***************************************\n");
printf("********* 1. play *************\n");
printf("********* 0. exit *************\n");
printf("***************************************\n");
}
int main()
{
menu();//打印菜单
printf("请选择:>");
scanf("%d", &input);
}
3、使用switch实现menu()函数里的选项功能
void menu()
{
printf("***************************************\n");
printf("********* 1. play *************\n");
printf("********* 0. exit *************\n");
printf("***************************************\n");
}
int main()
{
menu();//打印菜单
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出\n");
break;
default:
printf("抱歉没有这个选项\n");
break;
}
}
4、创建game()函数用来实现游戏功能
void game()
{
char ret = 0;
//使用全局变量创建二维数组,方便后期修改
char board[ROW][COL] = { 0 };
//初始化数组
InitBoard(board, ROW, COL);
}
5、创建头文件game.h,创建文件game.c文件,用来实现三子棋游戏的具体功能.
在头文件game.h头文件中添加全局变量ROW和COL并赋值为3。这里的全局变量为整个程序里的二维数组board提供依赖。
将函数InitBoard写入头文件game.h,方便后面调用。这样写的话在test.c和game.c文件中就只需要引进game.h这一个头文件就行了。
(当然也可以不添加编写整个game.h这个头文件,不过那就是要在各自文件中都要添加一边代码中所需要到的头文件)
#include <stdio.h>
#include <time.h>
#include <math.h>
#define ROW 3
#define COL 3
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
6、在game.c文件中实现InitBoard函数具体功能
#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] = ' ';
}
}
}
7、回到主页test.c编写三子棋棋盘
void game()
{
char ret = 0;
//使用全局变量创建二维数组,方便后期修改
char board[ROW][COL] = { 0 };
//初始化数组
InitBoard(board, ROW, COL);
//打印数组
DisplayBoard(board, ROW, COL);
}
然后到在game.h和game.c进行引用和具体功能实现
geme.h
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
game.c
#include "game.h"
//棋盘打印
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");
}
}
8、棋盘实现完毕,就该玩家和电脑下棋了
在主页进行调用,在头文件进行声明,在game.c进行具体功能实现
test.c
//玩家
PlayerMove(board, ROW, COL);
//电脑
ComputerMove(board, ROW, COL);
int main()
{
srand((unsigned)time(NULL));//设置随机数的生成起点
int input = 0;
do
{
menu();//打印菜单
printf("请选择:>");
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出\n");
break;
default:
printf("抱歉没有这个选项\n");
break;
}
} while (input);
return 0;
}
game.h
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
game.c
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
while (1)
{
printf("玩家下棋:>\n");
printf("请输入坐标:> ");
scanf_s("%d %d", &i, &j);
if ((i >= 1) && (i <= row) && (j >= 1) && (j <= col))
{
//判断当前数组的下标位置是否是空格
if (board[i - 1][j - 1] == ' ')
{
//如果是空格则将星号填入当前位置
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("坐标被占用,请重新输入\n");
}
}
else
{
printf("所给坐标不在范围之内,请重新输入\n");
}
}
}
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("电脑下棋:>\n");
while (1)
{
//rand产生随机值,%row是让数值控制在3以内
i = rand() % row; //0~2
j = rand() % col; //0~2
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
9、以上玩家和电脑下棋的功能就只是执行一边,所以要在主函数调用中添加循环,并添加判断输赢条件,用以中止循环和结束游戏。
//规定:如果玩家赢则返回 * 号,电脑赢则返回 # 号。如果都不是则是平局。
while (1)
{
PlayerMove(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
//打印棋盘
DisplayBoard(board, ROW, COL);
ComputerMove(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if(ret == '#')
{
printf("电脑赢");
}
else
{
printf("平局\n");
}
DisplayBoard(board, ROW, COL);
在头文件和game.h中声明和实现具体功能
game.h
//玩家赢 - ‘*
//电脑赢- ’#‘
//平局-’Q‘
//继续- ’C’
char IsWin(char board[ROW][COL], int row, int col);
game.c
//用以判断棋盘上是否还有空格,以此判断是否是平局 int Is_full(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; for (x = 0; x < row; x++) { for (y = 0; y < col; y++) { if (board[x][y] == ' ') { 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[1][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] != ' ') { //返回棋盘上当前位置的符号,对应主页test.c文件判断输赢 return board[1][1]; } } //对角 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] != ' ') { //返回棋盘上当前位置的符号,对应主页test.c文件判断输赢 return board[1][1]; } //平局 if (Is_full(board, row, col)) { return 'Q'; } //游戏继续 return 'C'; }
2.完整代码显示
(1) test.c
#include "game.h"
void menu()
{
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);
//打印数组
DisplayBoard(board, ROW, COL);
//下棋
while (1)
{
PlayerMove(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
ComputerMove(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if(ret == '#')
{
printf("电脑赢");
}
else
{
printf("平局\n");
}
DisplayBoard(board, ROW, COL);
}
int main()
{
srand((unsigned)time(NULL));//设置随机数的生成起点
int input = 0;
do
{
menu();//打印菜单
printf("请选择:>");
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出\n");
break;
default:
printf("抱歉没有这个选项\n");
break;
}
} while (input);
return 0;
}
(2) game.c
#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 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");
}
}
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
while (1)
{
printf("玩家下棋:>\n");
printf("请输入坐标:> ");
scanf_s("%d %d", &i, &j);
if ((i >= 1) && (i <= row) && (j >= 1) && (j <= col))
{
//判断当前数组的下标位置是否是空格
if (board[i - 1][j - 1] == ' ')
{
//如果是空格则将星号填入当前位置
board[i - 1][j - 1] = '*';
break;
}
else
{
printf("坐标被占用,请重新输入\n");
}
}
else
{
printf("所给坐标不在范围之内,请重新输入\n");
}
}
}
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("电脑下棋:>\n");
while (1)
{
i = rand() % row; //0~2
j = rand() % col; //0~2
if (board[i][j] == ' ')
{
board[i][j] = '#';
break;
}
}
}
int Is_full(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
for (x = 0; x < row; x++)
{
for (y = 0; y < col; y++)
{
if (board[x][y] == ' ')
{
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[1][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][1];
}
}
//对角
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 (Is_full(board, row, col))
{
return 'Q';
}
//游戏继续
return 'C';
}
(3) game.h
#pragma once
#include <stdio.h>
#include <time.h>
#include <math.h>
#define ROW 3
#define COL 3
//初始化棋盘
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 ComputerMove(char board[ROW][COL], int row, int col);
//玩家赢 - ‘*
//电脑赢- ’#‘
//平局-’Q‘
//继续- ’C’
char IsWin(char board[ROW][COL], int row, int col);
总结
如有不足之处还请指出,我会回复的,非常感谢大家的查看,非常感谢,非常感谢。重要的事说三遍。另外希望大家看完以后也能有所收获。