一直很喜欢玩这个小游戏,简单的游戏中包含运气与思考与策略,喜欢这种简约又不失内涵的游戏风格。于是萌生了用C语言实现一下的想法。

具体代码是模仿这个:https://www.cnblogs.com/judgeyoung/p/3760515.html

博主分析的都很到位,很多算法技巧都值得借鉴,C语言实现2048的主要思想已经在那个博客中详细的分析了,但是我觉得在博主的代码中还是有很多很好的思想是值得我借鉴学习的。

比如这个生成随机数,顺便规定随机数的概率:

/* 生成随机数 函数定义 */
void add_rand_num()
{
srand(time());
int n = rand() % get_null_count();/* 确定在何处空位置生成随机数 */
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (board[i][j] == && n-- == ) /* 定位待生成的位置 */
{
board[i][j] = (rand() % ? : );/* 确定生成何值,设定生成2的概率是4的概率的两倍 */
return;
}
}
}
}

首先是 srand() 函数,他是一个随机数发生器的初始化函数。

原型为:void srand(unsigned seed)

用法是:程序员需要为这个函数提供一个随机数的种子:srand(随机数),如果使用相同的种子,那么后面的rand()函数就会每次运行都是生成一样的随机数,即伪随机数。

如:srand(1),直接用1来初始化种子,后面都是一样的随机数 。

为了生成真正的随机数,我们一般采用系统时间来作为随机数初始化函数的种子。使用time()函数来获取系统时间:

它的返回值为从 00:00:00 GMT, January 1, 1970 到现在所持续的秒数,然后将time_t型数据转化为(unsigned)型再传给srand函数,即: srand((unsigned) time(&t));

还有一个经常用法,不需要定义 time_t 型 t 变量,即: srand((unsigned) time(NULL)); 直接传入一个空指针,因为你的程序中往往并不需要经过参数获得的 t 数据。

第二句是:

int n = rand() % get_null_count();//在空余格中生成一个随机位置

利用随机数对剩余空格数目进行取余运算,得到小于剩余格数的随机数。

最后一句是:

if (board[i][j] ==  && n-- == )//随机位置处为0时填入一个随机数,但是如果随机位置处不为0呢?
{
board[i][j] = (rand() % ? : );//在随机生成的空白格处填上一个2或者4,利用三项表达式对3取余,得到1/3,2/3的概率。
return;//结束函数
}

就是在格子中没有数字时并且在刚刚生成的随机数的位置处,填入一个数字2或者4,并且为了降低难度,固定生成2是生成4的概率的2倍。

利用三目运算符和对3取余的特点,产生概率分布。

rand()随机数对3取余只有可能是0/1/2,而在三目运算符中,当第一个数不为0时,运算符的值就取中间那个数的值,否则取最后一个数。所以取2的可能性为2/3,取4的可能性为1/3,这样就产生了不同的概率。但是这种方法只能产生  n:1 的概率分布,如果要产生      4:5,    8:17  的概率时,这种方法就不在适用了。

上面这些代码还是有一些漏洞的,因为游戏刚开始是需要有两个数的,一个数必为2,另一个数就是上面生成的那个数,但是如果第二个数恰好生成的随机位置处是第一个数,那么根据这儿代码,就什么也没有执行,最终导致出现刚开始界面就一个数字的情况。

解决办法就是在刚开始生成的两个数的程序中不使用  get_null_count(),而是获取第一个数字2的准确位置,然后生成第二个数字时,在排除第一个数字的地方生成数字即可。

程序的主体就是数字的上下左右移动,go_left()和其他三个函数,他们的思想都是相似的,就拿go_left()函数来分析一下:

按照原作者的思想,移动的时候一共有三种情况。

如果相邻的两个数一样,就合并,数字相加。

如果相邻的数字不一样,简单的说,又分两种情况:数字需要移动和不需要移动。

具体代码为:

/*左移函数*/
void go_left(void)
{
/*i遍历行下标*/
for (int i = ; i < ; i++)
{
/*j为列下标,k为待比较项列下标,循环进入时k < j*/
for (int j = ,k = ; j < ; j++)
{
/*找出k后面第一个不为0的项*/
if (board[i][j] > )
{
/*情况1*/
if (board[i][j] == board[i][k]) //两个数相同就合并
{
scoer += board[i][k++] <<= ;
board[i][j] = ;
if_need_add_num = ; //合并之后需要生成随机数和刷新界面
}
/*情况2*/
else if (board[i][k] == ) //k项为空,则把j格移到k格
{
board[i][k] = board[i][j];
board[i][j] = ;
if_need_add_num = ;
}
/*情况3*/
else //k项不为空,也不等于j项,此时两个都不需要动,只是下标需要变换
board[i][++k] = board[i][j]; //把j项移到k项的紧挨着的右边 if (j != k) //移动过之后不相等说明之前他们不是紧挨着的
{
board[i][j] = ;
if_need_add_num = ; //此时移动虽然没有消去一个数,但是也要添加一个随机数出来
}
}
}
}
}

项目完整代码在原博客中已经给出。

运行效果:

C语言实现简易2048小游戏的更多相关文章

  1. C语言写的2048小游戏

    基于"基于C_语言的2048算法设计_颜冠鹏.pdf" 这一篇文献提供的思路 在中国知网上能找到 就不贴具体内容了 [摘 要] 针对2048的游戏规则,分析了该游戏的算法特点,对其 ...

  2. 2048小游戏代码解析 C语言版

    2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图:  游 ...

  3. 2048小游戏4X4C语言

    */ #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> v ...

  4. Swift实战之2048小游戏

    上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完 ...

  5. 如何在CentOS上安装一个2048小游戏

    如何在centos上安装一个2048小游戏 最近在学习CentOS系统,就琢磨着玩点什么,然后我看到有人在玩2048小游戏,所有我就在想,为啥不装一个2048小游戏搞一下嘞,于是乎,我就开始工作啦 由 ...

  6. jQuery实践-网页版2048小游戏

    ▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...

  7. C# 开发2048小游戏

    这应该是几个月前,闲的手痒,敲了一上午代码搞出来的,随之就把它丢弃了,当时让别人玩过,提过几条更改建议,但是时至今日,我也没有进行过优化和更改(本人只会作案,不会收场,嘎嘎),下面的建议要给代码爱好的 ...

  8. js、jQuery实现2048小游戏

    2048小游戏 一.游戏简介:  2048是一款休闲益智类的数字叠加小游戏 二. 游戏玩法: 在4*4的16宫格中,您可以选择上.下.左.右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合 ...

  9. 用js实现2048小游戏

    用js实现2048小游戏 笔记仓库:https://github.com/nnngu/LearningNotes 1.游戏简介 2048是一款休闲益智类的数字叠加小游戏.(文末给出源代码和演示地址) ...

随机推荐

  1. JEECG 3.7.2版本发布,企业级JAVA快速开发平台

    JEECG 3.7.2版本发布 -  微云快速开发平台 JEECG是一款基于代码生成器的J2EE快速开发平台,开源界"小普元"超越传统商业企业级开发平台.引领新的开发模式(Onli ...

  2. 人生苦短,我用Python 第一篇

    一.变量名 自定义变量名只能用 数字.字母.下划线组成. 使用变量前,需对其先赋值 注意:1.变量名不能以数字开头:      2.不能是关键字:例如:'and', 'as', 'assert', ' ...

  3. HTML meta refresh 刷新与跳转(重定向)页面

    下面为各位整理了一些HTML meta refresh 刷新与跳转(重定向)页面的例子吧,后面本站长自己也补充了一些js页面刷新与跳转例子吧. refresh 属性值  --  刷新与跳转(重定向)页 ...

  4. dedesms中的导致生成静态页面多出空白行解决办法

    前几天给朋友用织梦仿一个手机网站,保存处理好的代码,页面头部在浏览里莫名其妙多了一段空白区域,用调试工具查看,发现是代码里多了一行&#65279.后来发现很多网友在生成织梦页面的时候,头部 ...

  5. Python3 的列表

    1:列表: Python的列表比C语言的数组强大的多,数组只能存放相同类型的数据,而列表则像一个大集装箱可以存放整形.浮点型.字符串.对象等 2:创建列表的方法 #创建一个普通列表 list1=[1, ...

  6. Spring整合Struts的两种方式介绍

    1 使用Spring托管Struts Action 该种方式就是将Struts Action也视为一种Bean交给Spring来进行托管,使用时Struts的配置文件中配置的Action的classs ...

  7. eclipse导入项目之后报错

    一.项目本身就有错 二.jdk版本的问题 参考网址:http://jingyan.baidu.com/article/95c9d20da3ec5fec4e756186.html 从别的地方导入一个项目 ...

  8. python与MySQL

    一.python与mysql交互 因版本不同python操作mysql有两个模块,python3不再支持MySQL-python,模块使用都一样: python2.7:MySQL-python pyt ...

  9. JavaScript对象的valueOf()方法

    js对象中的valueOf()方法和toString()方法非常类似,但是,当需要返回对象的原始值而非字符串的时候才调用它,尤其是转换为数字的时候.如果在需要使用原始值的上下文中使用了对象,JavaS ...

  10. scrapy_Response and Request

    scrapy中重要的两个类是什么? Requests.Response 什么是Requests? 网页下载 有哪些参数? url callback headers     # 头部信息 cookie ...