【C语言探索之旅】 第一部分第八课:第一个C语言小游戏
内容简介
1、课程大纲
2、第一部分第八课:第一个C语言小游戏
3、第一部分第九课预告: 函数
课程大纲
我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案。还会带大家用C语言编写三个游戏。
C语言编程基础知识
什么是编程?
工欲善其事,必先利其器
你的第一个程序
变量的世界
运算那点事
条件表达式
循环语句
实战:第一个C语言小游戏
函数
练习题
习作:完善第一个C语言小游戏
C语言高级技术
模块化编程
进击的指针,C语言王牌
数组
字符串
预处理
创建你自己的变量类型
文件读写
动态分配
实战:“悬挂小人”游戏
安全的文本输入
练习题
习作:用自己的语言解释指针
用基于C语言的SDL库开发2D游戏
安装SDL
创建窗口和画布
显示图像
事件处理
实战:“超级玛丽推箱子”游戏
掌握时间的使用
用SDL_ttf编辑文字
用FMOD控制声音
实战:可视化的声音谱线
练习题
数据结构
链表
堆,栈和队列
哈希表
练习题
第一部分第八课:第一个C语言小游戏
经过前七课的努力,我们终于来到了第一个比较正式的程序:一个C语言小游戏。虽然暂时还不介绍C语言的图形编程,这个游戏还是命令行的形式,但是不论怎样,这都是一个小小的里程碑。我们的目的是让大家看到经过之前几课的学习,你已经可以完成一些有意思的事了。虽然我们知道理论是很好的,但是如果我们不能把所学的理论付诸实践,那也很没有意思,我们不就白学了那么多理论。
信不信由你,你其实已经有水平实现自己的第一个有意思的程序了。
准备工作和建议
程序的原理
在动手编程之前,得先跟大家说一下这个程序是干什么的。
我们可以称呼这个游戏为《或多或少》。
游戏的原理是这样:
每一轮电脑从1到100中随机抽一个整数
电脑请求你猜这个数字,因此你要输入一个1到100之间的整数
电脑将你输入的数和它抽取的数进行比较,并告知你的数比它的数大了还是小了
然后它会再次让你输入数字,并告诉你比较的结果
一直到你猜到这个数为止,一轮结束
游戏的目的,当然就是用最少的次数猜到这个“神秘”数字。虽然没有绚丽的图形界面,但是或多或少,这都是你的第一个游戏了,应该值得骄傲。
下面演示了一轮的样式,你要编程来实现它:
这个数字是什么?50
猜小了!
这个数字是什么?75
猜小了!
这个数字是什么?85
猜大了!
这个数字是什么?80
猜大了!
这个数字是什么?78
猜小了!
这个数字是什么?79
太棒了,你猜到了这个神秘数字!!
随机抽取一个数
但大家要问了:怎么来随机地抽取一个数呢?不知道怎么办啊,臣妾做不到啊。
诚然,我们还没学习如何来产生一个随机数。让亲爱的电脑兄来做这个是不简单的:它很会做运算,但是要它随机选择一个数,它还不知道怎么做呢。
事实上,为了“尝试”得到一个随机数,我们不得不让电脑来做一些复杂的运算,好吧,归根结底还是做运算。
我们有两个解决方案:
请用户通过scanf函数输入这个神秘数字,那么就需要两个玩家咯。一个选数字,一个猜数字。
孤注一掷地让电脑来为我们自动产生一个随机数。好处是:只需要一个玩家,可以自娱自乐。缺点是:需要学习该怎么做...
我们来学习用第二种方案编写这个游戏,当然你也可以之后自己编写第一种方案的代码。
为了生成一个随机数,我们要用到rand()函数(rand是英语“random:随机” 的缩写)。顾名思义,这个函数能为我们生成随机数。但是我们还要这个随机数是在1到100的整数范围内(如果没有限定范围,那会很复杂)。
我们会用到以下的形式:
srand(time(NULL));
mysteryNumber = (rand() % (MAX - MIN + 1)) + MIN;
第一行(srand函数)用于初始化随机数的生成器。srand其实是seed random的缩写,seed在英语中是“种子”的意思。
给出 百度百科 的简单解释:
【srand和rand配合使用产生伪随机数序列。rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列】
【所谓的“伪随机数”指的并不是假的随机数,这里的“伪”是有规律的意思。其实绝对的随机数只是一种理想状态的随机数,计算机只能生成相对的随机数即伪随机数。计算机生成的伪随机数既是随机的又是有规律的 —— 一部份遵守一定的规律,一部份则不遵守任何规律。比如“世上没有两片形状完全相同的树叶”,这正点到了事物的特性 —— 规律性;但是每种树的叶子都有近似的形状,这正是事物的共性 —— 规律性。从这个角度讲,我们就可以接受这样的事实了:计算机只能产生伪随机数而不是绝对的随机数。】
【通过time()函数来获得计算机系统当前的日历时间(Calendar Time),处理日期时间的函数都是以本函数的返回值为基础进行运算。其原型为:time_t time(time_t * t); 如果你已经声明了参数t,你可以从参数t返回现在的日历时间,同时也可以通过返回值返回现在的日历时间,即从一个时间点(例如:1970年1月1日0时0分0秒)到现在此时的秒数。如果参数为空(NULL),函数将只通过返回值返回现在的日历时间。】
如果我们在使用rand函数前没有用srand函数制定seed的值,或者虽然用了srand函数,但是给它的参数是一个常量,比如srand(1),那么每次程序运行rand产生的数字都是一样的。只有用例如time()函数来给一个每次都不一样的seed值,才能使得rand的返回值不一样,才能做到“随机”。
srand函数只需要在rand函数前面调用一次就够了,也只能调用一次,之后你想要调用rand函数几次都无所谓,但是每个程序中不能用两次srand函数,切记。
上面代码格式中的MAX和MIN是常量,MAX是英语的“最大”Maximum的缩写,MIN是“最小”Minimum的缩写。顾名思义,MAX和MIN分别是你规定的范围的最大值和最小值。
建议在程序的一开始定义这两个常量:
const int MAX = 100, MIN = 1;
引入的库
为了程序能够顺利运行,我们需要引入三个库:
stdio.h
stdlib.h
time.h
我们以前的课说过库的作用,库里面提供一些定义好的函数,比如time.h里面就有我们的time()函数,stdlib中有rand和srand函数。
好啦,我不继续透露了。我们已经说明了游戏的原理,也给出了一轮游戏的运行例子,也给出了主要的随机数生成代码,该轮到你来完成游戏的代码了。加油。
我的代码
希望大家自己先写代码,查阅一些资料,或复习前面几课的内容。运行成功了或实在写不出来才来看答案。
以下给出我的版本,当然了,这个游戏的代码可以有不同的版本。你完全可以自己发挥。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (int argc, char** argv)
{
int mysteryNumber = 0, guessNumber = 0;
const int MAX = 100, MIN = 1;
// 生成随机数
srand(time(NULL));
mysteryNumber = (rand() % (MAX - MIN + 1)) + MIN;
/* 程序的循环部分, 如果用户没猜中数字,就一直进行循环 */
do
{
// 请求用户输入所猜数字
printf("这个数字是什么 ? ");
scanf("%d", &guessNumber);
// 比较用户输入的数字和神秘数字
if (mysteryNumber > guessNumber)
printf("猜小了 !\n\n");
else if (mysteryNumber < guessNumber)
printf("猜大了 !\n\n");
else
printf ("太棒了,你猜到了这个神秘数字 !!\n\n");
} while (guessNumber != mysteryNumber);
return 0;
}
程序的解释(从上到下的顺序):
预处理指令:就是开头的那三行,以#开始,include是英语“包含,引入”的意思。所以表示引入什么库。之前我已经给大家这部分的代码了,所以如果你的程序运行起来出错是在这部分的话,那你也是够够的了 :P
变量:这个游戏中,不需要太多变量,只有一个用于记录用户输入的数字的变量guessNumber,和一个电脑随机抽取的数字mysteryNumber。同时也定义了两个常量(const变量,其实叫只读变量比较准确)MAX和MIN,值分别是100和1。这样定义的好处是,如果你后面要改这两个数值,会很方便,直接改这一行的两个值就好了。如果没有用MAX和MIN而是在程序里每一个地方写100和1的话,那如果以后要改数值,工作量就大了。
随机数:srand和rand那两行,产生在1和100之间的一个随机数,值赋给mysteryNumber。
循环:我选择了用do...while循环。理论上一个while循环也可以做到,但我觉得这里用do...while可能更合逻辑。为什么呢?还记得do...while循环的特点吗?就是循环体里的指令至少会执行一次,不像while循环可能一次也不执行。这里我们至少要让用户输入一次数字,不可能用户一次也不输入就猜到了数字。
在每一次进入循环体里运行时,我们都请求用户输入一个数字,并且把这个数字的值赋给guessNumber变量,接下来就比较guessNumber和mysteryNumber(需要猜的数字)的大小:
mysteryNumber大于guessNumber,那么输出“猜小了”,继续循环
mysteryNumber小于guessNumber,那么输出“猜大了”,继续循环
mysteryNumber等于guessNumber,也就是else语句的情况,即是说我们猜对了,输出“太棒了,你猜到了这个神秘数字!”,结束循环
循环也需要一个条件,我们给出的条件是:只要猜的数字和神秘数字不一样,循环就继续。
现在这个游戏还是很基础很简单的,但是可以有以下的改进方案:
增加一个记录步数的计数器,在你猜对的时候输出:“太棒了,你用**步猜到了这个神秘数字!”
目前的程序只进行一轮就结束了,如果玩家不过瘾,还想继续下一轮怎么办呢?可以加入一个问题:“你还想继续玩吗?”,等待用户输入数字来回答。定义一个布尔值continue来存储用户输入的回答,比如continue的默认值是1,就是用户默认是继续玩下一轮的,但如果用户输入0,那么程序停止,游戏结束
增加一个模式:两人模式。可以你出题我来猜。但是我希望你能够在程序一开始就让用户选择是玩哪一种模式,是经典的人机对战,还是人人对战。如果是两人模式的人人对战,那么就不是用srand和rand来产生神秘数字了,而是让玩家一通过scanf来输入这个数字
设置几个难度级别,让玩家选择:初级(1-100中的一个数),中级(1-1000中的一个数),高级(1-10000中的一个数)。如果你这样设计,就需要改写MAX值了,而此时MAX就不能再是一个const变量了,必须要把MAX前面的const去掉,MIN的还能保留。
你也可以自己增设难度,想出更多好玩的点子来丰富这个游戏。通过完善和改进这个小游戏,你会学到更多。
第一部分第九课预告:函数
今天的课就到这里,一起加油咯。
下一次我们学习第九课,来认识函数这个极为重要和有用的内容吧!
程序员联盟
微信公众号*您若觉得本文不错,请点击画面右上角《···》按钮“分享到朋友圈”或“发送给朋友”
*新朋友请关注「程序员联盟」微信搜公众号
ProgrammerLeague
小编的微信号:
frogoscar
小编的QQ号: 379641629
小编的邮箱: enmingx@gmail.com
(微信和邮箱最常用)
PS: 有朋友反映看手机端的文章太累,其实是可以用浏览器网页来看的
方法1. 点击画面右上角的《···》按钮,然后选择“复制链接”,再把链接黏贴到你的浏览器里面或用邮件发送给自己,就可以在电脑的浏览器里打开了
方法2. 头条网www.toutiao.com,搜索我的自媒体“程序员联盟”,里面有所有文章,也可以直接进这个链接:http://www.toutiao.com/m3750422747/
新朋友如何查看所有文章:
点击“查看公众号”,再点击“查看历史消息”
“程序员联盟”公众号专为程序员,App设计师,各位喜爱编程和热爱分享的小伙伴们推送各样编程相关知识,优秀软件推荐,业界动态等。搜索
ProgrammerLeague 加关注~
持续关注 程序员联盟 微信公众号,更多有趣,有料,有亮点的内容等着你哦!
【C语言探索之旅】 第一部分第八课:第一个C语言小游戏的更多相关文章
- 【C语言探索之旅】 第二部分第二课:进击的指针,C语言的王牌!
内容简介 1.课程大纲 2.第二部分第二课: 进击的指针,C语言的王牌 3.第二部分第三课预告: 数组 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言 ...
- 【C语言探索之旅】 第二部分第九课: 实战"悬挂小人"游戏 答案
内容简介 1.课程大纲 2.第二部分第九课: 实战"悬挂小人"游戏 答案 3.第二部分第十课预告: 安全的文本输入 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题, ...
- 【C语言探索之旅】 第一部分第九课:函数
内容简介 1.课程大纲 2.第一部分第九课:函数 3.第一部分第十课预告: 练习题+习作 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. ...
- 【C语言探索之旅】 第一部分第七课:循环语句
内容简介 1.课程大纲 2.第一部分第七课: 循环语句 3.第一部分第八课预告: 第一个C语言小游戏 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编 ...
- 【C语言探索之旅】 第三部分第二课:SDL开发游戏之创建窗口和画布
内容简介 1.第三部分第二课: SDL开发游戏之创建窗口和画布 2.第三部分第三课预告: SDL开发游戏之显示图像 第三部分第二课:SDL开发游戏之创建窗口和画布 在上一课中,我们对SDL这个开源库做 ...
- 【C语言探索之旅】 第二部分第一课:模块化编程
内容简介 1.课程大纲 2.第二部分第一课: 模块化编程 3.第二部分第二课预告: 进击的指针,C语言王牌 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C ...
- 【C语言探索之旅】 第一部分第十课:练习题+习作
内容简介 1.课程大纲 2.第一部分第十课: 练习题+习作 3.第二部分第一课预告: 模块化编程 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三 ...
- 【C语言探索之旅】 开宗明义及第一课:什么是编程?
内容简介 1.课程大纲 2.第一部分第一课:什么是编程? 3.第一部分第二课预告:工欲善其事,必先利其器 课程大纲 不知道为什么,一直对C语言有一种很深厚的“情怀”(类似老罗对锤子手机的那种),说 ...
- 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL
内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...
随机推荐
- 【CSS3】transform-origin原点旋转
忙乱, 点 -moz-transform-origin: 0 0; -webkit-transform-origin:0 0; -o-transform-origin:0 0; 以右上角给原点 -mo ...
- springMVC中一个class中的多个方法
在前面.已经可以利用SpringMVC进行简单的例子了,但是,在controller中我们实现了Controller接口.这样就必须实现handleRequest(HttpServletRequest ...
- xcode Workspaces
A workspace is an Xcode document that groups projects and other documents so you can work on them to ...
- jQuery中的getJSON()
json文件是一种轻量级的数据交互格式.一般在jQuery中使用getJSON()方法读取. $.getJSON(url,[data],[callback]) url:json文件地址 data:可选 ...
- Linux 单用户模式的使用
在进入系统启动菜单时,选择kernel,输入"e"后进入,在kernel开头的启动项后输入(空格) /single或者 / 1,然后输入"b"重新启动机器,此时 ...
- bloom filter与dawgdic(一种trie树)
我有一个做了一款移动浏览器的朋友. 他有这样一个需求:当用户输入一个站点的url时候.移动浏览器须要识别这个网址是否是一个恶意网址.另外.他有一个恶意网址库. 或许这种解决方法有多种. 当中一种就是把 ...
- cocos2d-x快乐的做让人快乐的游戏3:cocos-2d 3.x中的物理世界
Cocos2d-x 3.0+ 中全新的封装的物理引擎给了开发人员最大的便捷,你不用再繁琐与各种物理引擎的细节,全然的封装让开发人员能够更快更好的将物理引擎的机制加入�到自己的游戏中,简化的设计是从2. ...
- Windows phone 8 学习笔记(2) 数据文件操作
原文:Windows phone 8 学习笔记(2) 数据文件操作 Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方 ...
- oracle之spool详细使用总结(转)
今天实际项目中用到了spool,发现网上好多内容不是很全,自己摸索了好半天,现在总结一下. 一.通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得 ...
- PHP socket类
没事的时候自己封装了一个socket类 功能非常easy和curl功能是一样的 class socketClass{ private $host; private $url; private $err ...