基于模块化的设计思想,想要设计一个三子棋游戏,可以用不同的文件存放不同的代码,通过函数的调用,以体现C语言的面向过程特点。
将程序的源码用于三个文件存放,分别为game.h
、game.c
和test.c
game.h
:用于存放函数的声明,根据头文件的格式采取以下方式书写,保证其只调用一次。
而其中的声明部分用于对实现相应功能函数的声明,当然也可以用define
定义一些标识符常量,在三子棋的游戏中我们可以把行号和列号进行定义,如果相对三子棋进行拓展,只需更改此处,其他地方无需改动,便能很好达到目的。
想要在其他源文件中使用所声明的函数只需通过#include "game.h"
引用该函数即可。
game.c
:对于实现相应功能函数的定义,由于只是一个测试框架,更多的功能会在后续补充,现在只给出些许函数说明。
这里对三子棋的实现功能作简要分析:可以定义一个二维的字符串数组,将其初始化为空字符,然后分别定义玩家和电脑所用到的字符来表示其棋子,通过更新赋值,和实时打印棋盘来模拟下棋的过程,最后判断输赢。
棋盘的初始化即为循环赋值。
void InitBoard(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i=0; i<row; i++)
{
for (j=0; j<col; j++)
{
arr[i][j] = ' ';
}
}
}
而棋盘的打印根据棋盘的特点也可模拟初始化采用两层for循环输出
每一行都可分为输入行和边界
注意!无论是输入行还是边界行,没行的末尾均无界
最后一行输入行结束后无边界行
所以有如下代码:
void PrintBoard(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i=0; i<row; i++)
{
for (j=0; j<col; j++)
{
printf(" %c ",arr[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");
}
}
}
这样便可以通过改变标识符常量的大小来改变棋盘的大小
注意! Ⅰ 函数声明与定义不同的是在代码结束后必须加上分号 Ⅱ 二维数组在传参时,如果给的形参是数组名,它传的是第一行的地址,所以后面的括号不能省略,还必须给出固定的列数
主要的游戏功能将会在下次博客中体现
test.c
:这个源文件用于体现整个游戏的逻辑框架。
整个玩游戏过程是一个循环,但无论如何都需要打印一次菜单所以选择do-while
语句,switch
语句可以根据输入进行分支,而且通过default
语句实现错误输入的处理。
#include <stdio.h>
#include "game.h"
void menu()
{
printf("****************************************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("****************************************\n");
}
int main()
{
char arr[ROW][COL];
int input = 0;
do
{
menu();
scanf("%d",&input);
switch(input)
{
case 1:
// game(此处可以添加更完整的游戏功能实现);
InitBoard(arr,ROW,COL);
PrintBoard(arr,ROW,COL);
break;
case 0:
printf("游戏结束\n");
return 0;
default :
printf("输入错误!请重新输入\n");
break;
}
}while (input);
return 0;
}