桌面山寨版2048—优化篇

     博客近两天略惨淡啊,我会先在博客上不定时的更新,毕竟是想把博客做成自己的主要平台嘛,谢谢支持啦!希望大家能猛戳http://www.richinmemory.com/

三、桌面山寨版2048—优化篇

      当这所有的初步编码都实现之后,我长舒了一口气并且自己玩了1个 小时,虽然整个尤其并没有什么高深的编程技巧,但是真的做到把游戏程序拷贝到任何一个电脑上大家都能玩的地步还是需要花一点精力的。在短暂的享受一下成就 感之后,又回到代码的界面,看到处理按键逻辑的那一部分,总有一种感觉,感觉如果半天没看这段代码,我可能就再也看不懂了。看着这一个个的循环总感觉代码 在张力上缺乏点什么,越看越觉得就像自己脸上糊了一脸的泥,所以,我决定,一定要找点什么来优化优化。

      我的第一反应每次没必要循环那么多,就拿“下”这个方向键来说,没必要从最后一行开始遍历,因为最后一行没有下一行,也就根本不可能发生合并操作。但是一个一共只循环16次的循环变成12次,对于现在动不动就4核的计算机来说,根本就不值一提,这种优化只能是书上的优化。

      回到现实中来,大大优化一个代码无非从规范代 码,数据结构,算法三个方面考虑,不要小看第一点,工作也快一年了,我觉得在实际生产中,绝对第一点占了最大的比例。因为我山寨这个小游戏的行为绝逼只能 算是小作坊行为,所以规范代码我就不想了,剩下的两个,明显考虑使用一个更合适快捷的数据结构比想一个更加牛逼的算法更方便,毕竟人本性都是懒惰的,所以 我尝试能不能找到一个更加合适的数据结构。

      由于这个游戏是一个4×4的 方格,所以我第一个想到是用一个图,也只是想想而已,我只是想挑战一下自己的编程习惯,还没想要挑战自己的智商。剩下来继续搜寻,树,哈希表貌似和这很难 一下子发生联想,于是我就试试能不能套用下堆栈啊,队列啊,这一套,我还真想出了个办法。完整的灵感迸发的过程是这样的:我看着这一个4×4的 大方块,看看自己的循环,“上下”这两个方向都是按照行进行遍历的,“左右”都是按照列进行遍历的,如果我反过来一下,“上下”按照列,“左右”按照行, 因为“上下”合并关系都是在行于行之间发生,一次处理一列貌似是更加贴近人自然思维的方式。比如“下”,从最底部开始,一个数字一个数字进行处理,然后将 合并的结果再一个数字一个数字写回原来的区域,从最后一行往第一行遍历,也从最后一行往第一行处理,写回。这不是活脱脱一个FIFO的过程吗?于是很自然的就想到队列这个犀利的数据结构。而且在实施时,更加发现,只需要一个容量为2的队列就可以完美的实现这个游戏的逻辑。

      有了这个开头,后面的就简单了。还是以“下”这个方向为例,从最后一行最后一列开始,假设是3,3),如果这个数字不是空,那么将这个数字入队,如果是空,则跳过。接着遍历上一行(2,3), 如果是空,则跳过,接着遍历上一行。如果是数字,则入队,然后判断是否和前面的一个数字是否相同,如果相同,则更新队列中前一个数字,并且填入相应的区 域,同时两个相关的数字都出列。这样不仅可以正确的合并操作,并且可以有效的避免一次合并好几个数字的现象。然后以此类推就可以完成全部的操作。这样叙述 有点逻辑混乱,我举两个例子来尝试解释清楚。

      比如一列数字是2空28,首先,8入队,接着2入队,这两个数字不相同,所以将8出队,填入最后一行,下一个是空,不需要处理,下面入队是2,和队中相邻元素是一样的,则更新相邻元素为4,出列,填入相应的格子,循环结束,操作终止。

      再举个例子,比如一列数字是2288,那么8首先入队,接着8入队,发现相邻两个元素相同,所以更新数字同时两个元素出队。接着入队2和2,同样重复上面的操作,循环终止,操作结束。而且这样的处理过程绝对不会发生一下子合并好几块的现象。

      将上面的逻辑实现成代码很简单,特别是我在使用的时候直接使用的STL里面的queue容器,连队列的实现都省了。在循环中,使用一个标识符记录当前未被填入的最后一行的行号,在每次出队的时候就可以将数字正确的更新到正确的位置。

      如果将队列换成堆栈,一样能够实现上面的逻辑。

      这个优化的版本代码真正改动代码部分的技术到没有什么,我觉得重要的是这个逻辑和最后处理的思路。所以,如果你需要完整的代码,请来我的博客http://www.richinmemory.com/ ,我的邮箱就在那儿,给我邮件吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏韩伟的专栏

框架设计原则和规范(一)

此文是《.NET:框架设计原则、规范》的读书笔记,本文内容较多,共分九章,将分4天进行推送,今天推送1-3章。 1. 什么是好的框架 2. 框架设计...

4265
来自专栏java一日一条

程序中减少使用if语句的方法集锦

大约十年前,我听说了反if的活动,觉得这个概念非常荒谬。如果不用if语句,又怎么能写出有用的程序呢?这简直太荒谬了。

1352
来自专栏Java编程

Java回调机制解读

在一个应用系统中,无论使用何种语言开发,必然存在模块之间的调用,调用的方式分为几种:

3006
来自专栏章鱼的慢慢技术路

2015年第六届蓝桥杯C/C++B组省赛题目解析

2282
来自专栏马洪彪

spss C# 二次开发 学习笔记(二)——Spss以及统计术语解释(IT人眼中的统计术语)

针对客户需求,需要对一些数据做统计分析。统计分析的第一步,即为数据查询,查找出要统计分析的数据。 查询得出的是一个行列表格的结果集,行、列、表格等这些IT的数据...

2795
来自专栏Java与Android技术栈

响应式和函数式,两个容易混淆的概念

传统的编程方式,是顺序执行的,上一个任务没有完成的话需要等待直至完成之后才会执行下一个任务。无论是提升机器的性能还是代码的性能,本质上都需要依赖上一个任务的完成...

891
来自专栏PHP在线

PHP 代码规范简洁之道

原文出处: Scholer 1. 统一的编码规范 编码规范往简单说其实就是三个方面: 换行 空格 变量命名 放在 PHP 里面,还有一些附加的地方,比如关键字...

4046
来自专栏Java技术栈

6 道 BATJ 必考的 Java 面试题

请对比 Exception 和 Error,另外,运行时异常与一般异常有什么区别?

1061
来自专栏王亚昌的专栏

让代码更有效率的方法

        老大总结的代码级提高代码执行效率需要注意的点,很值得和大家分享一下,在这儿也由衷地感谢下老大的总结和工作中的指导。大多数的点都在项目中验证过,比...

781
来自专栏转载gongluck的CSDN博客

黑暗的内存管理

黑暗的内存管理 很多人对 C 语言深恶痛绝,仅仅是因为 C 语言迫使他们在编程中必须手动分配与释放内存,然后通过指针去访问,稍有不慎可能就会导...

4086

扫码关注云+社区

领取腾讯云代金券