哪个刚接触编程的不想敲出个程序,然后去和朋友炫耀呢?
今天,就让我们用C语言敲个简单的“三子棋”游戏吧。
首先,我们先不要急着把main函数敲出来,先了解一下一个程序是怎么设计的吧,程序实质上是一个一个的子程序,即函数组成的,虽说系统会自带函数(即库函数)但一个程序仅仅用库函数是很难实现的,这时候就需要我们这些程序员来自定义函数了,初学者会习惯性地把自定义函数写在main函数的上面,这确实是个较好的习惯的,但这里会存在一个隐患,就是在程序大起来时,我们要自定义的函数一多起来,这样把自定义函数都堆到main函数前面的写法,就不便于团队之间分享时查找和修改代码了,可能有些人会质问道:“函数多了不也就只要ctrl cv几下就好了吗?”非也!
程序是由一个个的函数组成的,main函数也是其中的一个,如果我们都把自定义函数堆到main函数的前头就显得头重脚轻了,每次我们想打开代码看看main函数的逻辑时就得使劲往下滑,很难定位,对于想观察其他自定义的函数也是一样。
所以,为了方便查找和修改,我们会选择创建多个文件夹来进行函数的分类。
一般是创建三个,一个头文件和两个源文件,头文件用来声明自定义函数,以及函数实现需要用到的头文件(这样在#include “自定义头文件” 时,就不用另外引用库里的头文件了);另外两个源文件,一个是用来写自定义函数的,另一个是拿来写程序逻辑,即main函数的(如果在自定义头文件里已经对要引用的头文件进行了说明,那就只要引自定义头文件就好)
你看,如果我们这样写代码,查找和修改起来是不是有条理多了,分享给团队成员,他们拿到手上后是不是也能很快地理解你写的代码。
基本的整理和分类做好后,就可以开始我们今天的三子棋游戏的实现了:
1.创建三个文件夹(头文件的创建记得加上.h的后缀)小编这里的test.c里写游戏整体逻辑的实现,即main函数,game.c里写游戏逻辑里需要自定义的函数。
2.先从程序逻辑出发,点击test.c文件,引用自定义头文件后,设计main函数,我们进入游戏时总得有个菜单吧,玩家的选择可以通过键入进行,我们这里先创建一个input的变量,当玩家输入1时则进入游戏,输入0则退出游戏,设计到这里其实还不够,万一玩家失误敲错了怎么办?我们是不是得提醒一下,提醒完了就没了吗?是不是还得让玩家重新选择一下,那我们就得把菜单的选择设计成循环结构,这里小编用的是do-while循环,如下图:
#include "game.h"
int main()
{
int input = 0;
do
{
menu();//菜单打印函数,1.play 0.exit
scanf("%d", &input);
//玩家选择后得有对应的反馈,在屏幕上用printf输出文字以提醒
if (input == 1)
{
printf("\n");
printf("^^^^^^三子棋游戏开始^^^^^^\n");
//tick_tack_toe();
}
else if (input == 0)
{
printf("\n程序退出中...");
break;
}
else
{
printf(":) 开玩输入1,退出输入2,请重新选择\n");
}
} while (input);
3.设计菜单(小编这边只是抛砖引玉,大家可以随意发挥)打印菜单的函数不用写在game.c,写在main函数上边就好,能让代码逻辑可视化一点:
//菜单打印
void menu()
{
printf("**************************\n");
printf("***** 1.play *****\n");
printf("***** 0.exit *****\n");
printf("**************************\n");
printf("请根据菜单做出选择:> ");
}
每个函数设计完后都记得调试一下,看看效果,crtl+F5,走~
!怎么报错了?printf和scanf未定义?看看我们的头文件:
哦!是自定义头文件里没有引用对应头文件,在game.h中include一下程序执行所需头文件(后面也是统一在game.h中对所需头文件和函数进行声明, 就不用在多个文件下重复引用了)
5.在我们键入1后,进入tick_tack_toe(),开始设计游戏逻辑:
void tick_tack_toe()
{
//创建一个数组当作棋盘
char chess[3][3] = { 0 };
//确定两方棋子的符号
char player_piece = '$';//玩家棋子 $
char pc_piece = '*';//电脑棋子 *
//清空棋盘
Chessboard_fresher();
//打印初始棋盘
ChessBoard_printer();
//玩家下棋
Player_move();
//打印下棋后的棋盘
ChessBoard_printer();
//判断一下输赢
WinOrNot();
//电脑下棋
PC_move();
//打印下棋后的棋盘
ChessBoard_printer();
//判断输赢
WinOrNot();
}
现在,程序的逻辑已经基本搭建完毕,只剩下这些自定义函数的实现了,文章写到这篇幅已经很长了,为了方便大家消化,本文写到这里就先告一段落了,下篇,咱们接着码:)