2048这个游戏从刚出开始就风靡整个世界。本技术博客的目的是想对2048涉及到相关的所有问题进行细致的分析与讨论,得到一些大家能够接受并且理解的结果。在这基础上,扩展2048的游戏性,使其变得更好玩,更有意思,更有耐玩性。本技术博客涵盖了有关2048的策略,理论分析与讨论,代码简单剖析,以及代码扩展的思路。个人认为应该是至今为止最全的2048游戏相关分析博客了。如有任何问题,有意思的讨论,以及想要交流的内容,欢迎大家留言~ 本篇为Part I,针对2048中各个问题进行分析与讨论。

题注

2048这款游戏刚开始出的时候没有提起我的一点兴趣…我的一个高中同学曾经在微信上求助(当然了,因为隐私问题我把姓名和头像都抹掉了):

自此以后,我踏上了人生,哦不,玩2048的不归路啊… 刚开始的时候我也是一点都不会玩,每次最多只能玩到256。然后呢,和大多数的朋友们一样呀,也是在网上各种查攻略,查技巧。查来查去,想想自己这一大段时间没干别的,就学算法来着。于是干脆,也别查了,自己分析分析想想最适合自己的策略吧!这一想不要紧,还真想出一些门道和一些可用的扩展来。本人呢,又是个编程的渣渣,但是又不甘于真的成为一个编程的渣渣,于是干脆,自己改!最后呢,就有了这样一篇博客,还有一个半成不成的Android版Extend 2048游戏。

本文,我尽量写的比较蛋疼,哦不,比较随性一些,不涉及非常恶心的数学分析呀什么的,只是概述性质的描述。对于代码来说呢,我也会写的非常粗浅,只是把核心的问题和解决方法分享给大家。确实有兴趣的朋友们可以看我修改的源代码,来进一步分析改动的地方以及一些细节问题。我会将源代码以文本的形式更新到本篇博客中。

本文的第一部分是学酥篇,是我这个学酥已经想明白的,有结论的思考和回答。对游戏本身有兴趣的,希望对游戏进行进一步了解与理解的,可以看这一部分的内容。看完以后,我想对于2048这个游戏本身,朋友们也就找到最适合自己的几乎能够确保打过的方法了。

本文的第二部分是学神篇,是我这个学酥想到了,但是似乎不能够解答的问题。对游戏有更进一步思考的,想挑战极限完全研究透彻这个游戏的朋友们,可以看这一部分的内容。这一部分我会列举我想到的有关2048很有意思,甚至有启发意义的问题。在此,欢迎大家补充问题,也欢迎大家在博客下面进行细致的讨论,我们争取能把这些问题全都解决掉,彻底把2048玩吐了,嗯!

本文的第三部分为菜鸟程序员篇,以一个2048源代码为例,分析其组成框架,为进一步改造2048这个游戏做好铺垫,并在PC平台完成了扩展。PC端不适合玩,只适合对2048的一些有趣的性质进行测试。我自认为在Java和Android方向,自己可能还能进阶到初级程序员,因此这章就叫菜鸟程序员篇啦。

本文的第四部分为初级程序员篇,根据第一、第二部分讨论的内容,对2048这个游戏在Android下进行进一步的扩展,使其变得更好玩,更耐玩,还更有挑战性。不过,因为第二部分中一些比较关键的问题没有解决,所以这个扩展版实际上还没有完成,在此呼吁CSDN上面有兴趣的朋友们,一起来进行更新,看看能不能把它变得更棒!

由于文章太长,本文分成两篇博客分别撰写。本篇为Part I,主要是游戏分析与讨论,涵盖了第一部分和第二部分的内容。后面准备撰写和发布的Part II,主要是游戏的实现和扩展,涵盖了第三部分和第四部分的内容。

啰啰嗦嗦的说了一大堆,最后提几个声明:

  • 本文的所有理论分析中的图像,使用MathType构造,截图后上传;
  • 本文的所有图片为本人原创;
  • 2048程序的例子原始链接为:https://github.com/PeterCxy/2048。其遵守开源协议。大家可以以非商业为目的对代码进行修改和调试。
  • 感谢我们实验室跟我一起为2048 High起来的开发大牛FBA(拼音缩写)同学,为修改Android版Extend 2048的界面做出了巨大的贡献。FBA同学在网上的昵称为firefix。他的CSDN博客地址我得给大家问问,他也是刚开的技术博客,相信以后他的博客中会有很多好玩的东西;感谢另外一个实验室,跟我一样蛋疼的好玩的老师在这篇博客中跟我进行的讨论,让我对于学神问题进行了进一步的推广,并且能够找到一种可行的解决学神问题的方法。他的网上昵称为king,可是个在学院颇受欢迎的萌老师哦!

第一部分-学酥篇-2048游戏分析

1. 分数计算和分数分析

分析

首先,我们来关注一下2048中大家都不怎么关注,但是游戏里面又不可缺少的细节:2048的计分。2048是如何记分的?为什么达到2048的目标时分数总在一个范围内变化呢?

大家运行自己的2048,简单的做几个位置的移动,就能够看出2048的一些记分的特点了。2048的计分规则非常简单:将能合并的两个数合并后,合并的结果为这一次合并玩家所得到的分数。如果同时合并了两个方格,那么得分分别计算后再相加。举几个简单的例子(2015.07.27更新,此处非常感谢一位面试官指出了这里的一个错误,下面第2种情况应该得到20分,而不是40分。明年或者后年入职后需要当面致谢~):

  • 如果把一个2和一个2合并,那么玩家得4分;如果把1个4和1个4合并,那么玩家得8分,以此类推;
  • 如果同时合并了两个2和2,那么玩家得(2+2) + (2+2) = 8分。如果同时合并了1个2和2,以及1个8和8,那么玩家得(2+2) + (8+8) = 20分,以此类推;

那么,如果合并到2048,玩家得到的分数应该是多少呢?我们有:

2048 = 1024 + 1024

1024 = 512 + 512

512 = 256 + 256

256 = 128 + 128

128 = 64 + 64

64 = 32 + 32

32 = 16 + 16

16 = 8 + 8

8 = 4 + 4

所以,玩家至少得到的分数为:2*1024 + 4 * 512 + 8 * 256 + 16 * 128 + 32 * 64 + 64 * 32 + 128 * 16 + 256 * 8 + 512 * 4 = 2048 * 9 = 18432

然而,我们玩的过程中会发现,新增加的方格有时候会直接产生4,而非2。这种产生会影响到玩家得得分。因为如果产生了一个4,而非一个2,那么玩家合并的时候,4 = 2 + 2的这个分数就没有了,玩家会因此损失4分。这种损失是不可避免的,而且确实实实在在地影响了玩家得最终得分。所以,对于只合并到单一的2048这个数,玩家最多得到的分数为:18432 + 1024 * 2 = 20480。这也就是为什么大家在玩的过程中,达到2048时自己游戏的分数一般都大概为20000分的原因了。

但是呢,有的玩家确实在合并到2048时拿到了更高的分数。这是因为在获得2048的时候,面板上面还有很多合并2048没有使用的数,而且合并到2048留下的数越多越大,得到的分数越高。具体分数列表如下:

多增加的数 多增加的分数
1024 1024*8~1024*9
  512 512*7~512*8
  256 256*6~256*7
  128 128*5~128*6
    64 64*4~64*5
    32 32*3~32*4
    16 16*2~16*3
      8 8*1~8*2
      4 4*0~4*1

每个1024,分数会增加2048 * 8 到 2048 * 9之间;而且,由于出4的概率比较小(从后面的源代码分析中也可以看出,游戏每次有10%的概率出现4,90%的概率出现2),因此分数会比较接近于预估最高分。举个例子,如果玩家合并到2048时面板上的情况如图:


那么,其大致分数应该可以估计为:
最高分 = 2048*10 + 1024*9 + 8*2 + 4*1 = 29716
最低分 = 2048*9 + 1024*8 + 8*1 + 4*0 = 26632

为了进一步验证正确性,我来举几个我玩完版本的例子。

Example 1

预计最高分:2048*10 + 16*3 + 2 * (8*2) + 3 * (4*1) = 20572

预计最低分:2048*9 + 16*2 + 2 * (8*1) = 18480

Example 2

预计最高分 = 2048*10 + 64*5 + 16*3 + 8*2 + 3 * (4*1) = 20881

预计最低分 = 2048*9 + 64*4 + 16*2 + 8*1 + 3 * (4*0) = 18728

2. 最大解分析

结论

在网上的很多朋友实际上已经分析了最大解的问题。这里面比较知名的,总结的也比较全的文章是《知乎》上面的一篇,链接为:http://m.zhihu.com/question/23492860。本篇文章也就不把这篇文章再粘贴过来占用篇幅啦。我们在这里只是把它从单纯的4*4,扩展到n*n的情况:

1*1的情况下,最大解为4,如图。

2*2的情况下,最大解为32 = 2^5 = 2^(2*2 + 1),如图。

3*3的情况下,最大解为1024 = 2^10 = 2^(3*3 + 1),如图。

4*4的情况下,最大解为2^17 = 2^(4*4 + 1),如图。其中,我们知道最小的格必须是4,所以有n - 14 = 2,因此n = 16。在这种情况下是能够全合并的,因此最高分可以得到2^17。

以此类推,n*n的情况下,最大解也就显然为2^(n*n + 1)。具体为什么这样最优,以及为何不可能再高了,请大家参看《知乎》上面的帖子。

策略

这个问题的研究实际上也给出了2048这个游戏的通用直观解法:尽可能让方格里面的数从大到小以回行排列,整个排列就像一个贪吃蛇一样,并且让最大的数卡在角落中。在网上的很多文章和帖子往往都只强调了“最大数在角落”这一点,而没有强调按照“贪吃蛇”方式安排其余数这一点。这也是很多朋友玩得到1024,就是到不了2048的原因。

按照上面的分析,排成“贪吃蛇”方式的理由就很直观了:合并的时候为了合并方便。至于为什么要把最大数放在角落里面呢?这是游戏性质决定的,固定一个角落,方格会都向固定的角落上面靠。如果不固定角落的话,最大数周围产生的小数很难合并到较大数中。我相信大家在玩游戏的过程中也有所体会吧~ 如果不小心把最大数移出角落,结果在最大数旁边生成一个2,那么把它合并起来几乎就是不可能的事情了。绝大多数已经知道诀窍的人,仍然输的原因基本都是如此:万不得已让最大数离开了一下角落,结果在最大数旁边产生了一个小数…

3. 达到目标解的移动步数分析

Analysis

那么,2048游戏如果推广到n*n的情况下,是否可以一直玩下去,而电脑(手机)屏幕可以显示的下呢?这个问题就涉及到“达到目标解的移动步数”这个问题了。简单些,就是说:最后玩到2048的时候,我们到底进行了多少次移动,或者说滑动了多少次屏幕呢?这个问题也会让大家了解到,玩成功一次2048大约需要多长的时间。

实际上,最后得到的2048是靠一个个生成的2和4加起来的。在这里为了简化讨论,我们假设每一次移动产生的方格都是2。这样的话,我们有如下的递推关系:

产生2048需要移动1次(2个1024相加)

产生2个1024需要移动2次(4个512分别相加)

产生4个512需要移动4次(8个256分别相加)

产生8个256需要移动8次(16个128分别相加)

产生16个128需要移动16次(32个64分别相加)

产生32个64需要移动32次(64个32分别相加)

产生64个32需要移动64次(128个16分别相加)

产生128个16需要移动128次(256个8分别相加)

产生256个8需要移动256次(512个4分别相加)

产生512个4需要移动512次(1024个2分别相加)

因此,总移动次数为:512+256+128+64+32+16+8+4+2+1 = 1024 - 1 = 1023次。大家玩2048的时候,算上游戏移动的动画的话,假定0.5s移动一次,那么一次2048的时间大致为:0.5s/次 * 1023次 = 511.5s,约为8.5分钟。这也就是为什么2048特别适合消磨时光的原因了… 时间长度恰到好处,正好是人体工作中间需要休息的大概时间。

这里实际上还有一个问题,在大家玩的时候,很可能出现同时合并好几个解的情况。举个例子,在下图中,我们向上(或者向下)移动就能够同时合并4个数:

这样的合并显然会减少总的合并和移动次数。但是我们说,这种情况并不是每次都发生,同时,我们还会经常发生移动但不合并任何数的情况。因此,这种并行合并的情况以及移动不合并的情况,我们不进行讨论(或者说根本没有办法讨论…)。

但是,我们要发现一个问题,对于2048来说,移动次数为2048 / 2 - 1次。那么如果到了4096呢?移动次数就变为了4096 / 2 - 1 = 2047次。换算成时间就为17分钟,这还可以接受。那么到8192呢?移动次数就变为了8192 / 2 - 1 = 4095次。换算成时间就为34分钟。也就是说,随着目标值的增长,游戏时间会成2次方指数长度增长。

那么,假设一个人每0.5s移动一次,365*24*3600s不停地进行游戏,假设游戏是可以一直玩下去的话,那么在这段时间内,其总共能够移动365*24*3600 / 0.5 = 62208000次,约为2^26,因此其能达到的最大分数为2^27,这还是在假设游戏过程中一直往高分玩。因此,2048这个游戏在n*n的情况下,理论上是可以一直玩下去的,但是玩下去的时间是一个天文数字。

Example

在此,我们给一个例子。这个例子的运行时靠第三部分的程序而来的。我们让计算机随机进行移动,如果无法再移动,则游戏自动扩大一个维度继续玩。也就是说,如果4*4玩不动了,游戏就扩展成为5*5的继续。我让计算机一共进行31536000次移动,来看看结果计算机扩展到了多大。这个等待是相当漫长的… 几乎用了快10分钟的时间才运行完毕,最后的结果图如下:

也就是说,游戏刚刚扩展到了9*9(我们可以看到面板上还有相当多的空白部分,表示离填满还远得很)。因此,在后续扩展中,最多让方格是10*10的,那么任何正常的人类,在有限的时间内几乎都无法玩到这种情况。

第二部分-学神篇-2048游戏讨论

1. 必然解和通用解讨论

其实呢,2048有一个特别显而易见,但是又特别难以回答的问题:2048为什么把4*4的目标值设置成了2048这么一个奇怪的数呢?我不认识作者,不知道作者当时是如何选择这么一个数作为目标值的。但是我可以确定的是,这个目标是选的确实是恰到好处:既不是很难,又不是很简单。

另一方面,大家也可能看到一个现象:即使一个人刚开始玩,连规则都不懂,它也可能上来就玩到了256甚至512。这实际上牵扯到了2048中一个非常难分析的问题:必然解,通用解,和最大解讨论。

首先给这几个名词下个定义。

  • 必然解:在n*n的情况下,瞎玩也能玩到的解,成为必然解。
  • 通用解:在n*n的情况下,很会玩,用最优的策略,必然能够得到的解。注意,这种情况下是玩家很会玩,知道最佳策略,但是无法控制产生方格的位置以及产生的数。
  • 最大解:在n*n的情况下,很会玩,用最优的策略,并且每次方格产生的位置都是最理想的情况下能拿到的最大分数。

对于最大解的分析,在第一部分已经得到结论了。那么,必然解和通用解呢?这是一个很难分析的问题… 我们从简单的情况依次进行分析。

1*1

这种情况是最简单的。第一个方格出现4,那么达到4;如果出现2,那么达到2;因此,这种情况和玩家会不会玩没有关系,直接得到结论:

  • 必然解 = 2
  • 通用解 = 2
  • 最大解 = 4

2*2

这种情况分析起来就比较复杂了… 大家可以试一试自己玩玩2*2的情况,似乎必然解为8。也就是说,即使随便按,游戏也至少能玩到8。为什么呢?我们可以用枚举的方法来看,具体过程就不细说了,我把非对称的例子排除,只给大家展示有必要展示的情况,如下图:

这是我能想到的最恶劣情况,但是即使这样也是能够合并出8的。同样地,这里也没有什么策略的情况了。

然而,是不是一定能够弄出16呢?答案是否定的。下面的情况就没办法弄出16(方框框住的是新出的数字):

这实际上也和策略没什么关系,因为每一步都是必须要走的(忽略对称情况)。因此我们可以得出结论:

  • 必然解 = 8
  • 通用解 = 8
  • 最大解见第一部分

3*3

这种情况就更复杂了,甚至我们无法枚举出所有情况。实际上,因为大家也没玩过3*3,对这种情况的研究也不深,所以这个地方我们只能暂时放在这里,等看到能人把这个地方填补完整了。

4*4

这种情况是大家经常讨论的情况。这个讨论实际上还有一个等价说法:如果会玩的话,用最佳策略,是否意味着2048是一定能够达到的呢?首先我们知道,2048一定不是必然解,因为不会玩的时候大家都玩不到嘛。现在的问题是,2048是不是通用解?这个就不能让我们一个一个去试了,因为即使最会玩的人,也有可能出现失误。然而出现失误了是说游戏本身玩不到2048,还是说因为失误导致的失败呢?这个问题最好由计算机来回答。

这里必须要感谢King老师了!在撰写这篇博客的过程中,King老师还跟我进行了一下讨论,如图:

King老师给我提供了一个stackoverflow空间,里面真的有人通过程序实验了一把。图里面的链接不方便大家点击,我在这里重复一下:http://stackoverflow.com/questions/22342854/what-is-the-optimal-algorithm-for-the-game-2048。我把有关的关键论述也放在博客中来:

I developed a 2048 AI using expectimax optimization, instead of the minimax search used by @ovolve's algorithm. The AI simply performs maximization over all possible moves, followed by expectation over all possible tile spawns (weighted by the probability of the tiles, i.e. 10% for a 4 and 90% for a 2). As far as I'm aware, it is not possible to prune expectimax optimization (except to remove branches that are exceedingly unlikely), and so the algorithm used is a carefully optimized brute force search.

Performance

The AI in its default configuration (max search depth of 8) takes anywhere from 10ms to 200ms to execute a move, depending on the complexity of the board position. In testing, the AI achieves an average move rate of 6-10 moves per second over the course of an entire game. If the search depth is limited to 6 moves, the AI can easily execute 20+ moves per second, which makes for someinteresting watching.

To assess the score performance of the AI, I ran the AI 100 times (connected to the browser game via remote control). For each tile, here are the proportions of games in which that tile was achieved at least once:

2048: 100%
4096: 97%
8192: 76%
16384: 13%

The minimum score over all runs was 27536; the maximum score achieved was 377792. The median score is 157652. The AI never failed to obtain the 2048 tile (so it never lost the game even once in 100 games).

也就是说,用最优策略的话,运行了100次,对于2048都成功了,而4096有97%的概率成功了。这样就意味着,4096并不是通用解。那么,这是否意味着2048是通用解呢?也不尽然… 实际上,如果测试了很多很多次,突然又一次没跑出来2048,那么也就意味着2048并不是通用解。但是到现在为止,还是都成功了的… 因此,我们只能断言:

  • 必然解 = 未知
  • 通用解 = 2048
  • 最大解见第一部分

对于n*n,我们确实是无法进行分析了。这里呼唤CSDN上面的牛人们,能够一起来讨论,或者测试这个问题。

2. n*n下目标解的设定问题

那么,接下来又来了一个好玩的问题。在4*4下,游戏作者设定了2048作为目标值。这似乎是通用解的必然结果。那么,在n*n的条件下,目标解应该设定为多少呢?这又是一个到现在为止没有解决的问题。对于一个游戏来说,我们不能将目标解设定为一个靠概率才能够达到的数,要不然即使最会玩的人,也有可能会失败。因此,讲目标解设定为通用解似乎是一个正确的方法。但是,按照前面的讨论,我们确实得不到n*n下的通用解,甚至只能进行猜测。我们只能得到如下的结论(“?”为不确定或者未做测试的结果):

维度 目标解设定值
1*1 2^1
2*2 2^3
3*3 ?
4*4 2^11
5*5 ?

这个问题的解决直接影响Part II中扩展版的完整性。因此,同样地,我们互换CSDN上面的牛人们能够一起讨论或者测试这个问题。

好啦,Part I就到这里。如果有其他好玩的,值得讨论的问题,欢迎大家留言,我也会逐渐继续补充这一篇技术博客,使之成为最全的有关2048游戏的分析与讨论博客。下一部分,我们将切换到代码的实现,分析看看如何实现2048这个游戏,以及能够进行什么样好玩的扩展。

2048游戏分析、讨论与扩展 - Part I - 游戏分析与讨论相关推荐

  1. 从空间分布、空间关系、空间演化、属性数据的扩展与再分析、数据分析扩展的角度举例分析GIS空间分析的特点与重要性,并且写出一句宣传GIS空间分析的广告语

    分析GIS空间分析的特点与重要性 空间分布 空间特征是地理现象的最基本特征,根据地理现象的空间分布状况,我们可以用不同的空间维度来表达.GIS中空间分布对于点状地物具有总体分布特征比如(密集型,方向性 ...

  2. 基于魔兽RPG对当前游戏发展趋势的分析,以及尝试一个高游戏性玩法的设计

    游戏发展中有这么一束分支,玩家可以从魔兽争霸3:冰封王座基本游戏模式开始延伸,并通过地图编辑器降低游戏开发门槛,创造开发自己的游戏模式,即魔兽RPG. 如果客观的看,魔兽RPG符合一个优胜劣汰的进化守 ...

  3. 在游戏运营行业,Serverless 如何解决数据采集分析痛点?

    作者 | 计缘 来源|阿里巴巴云原生公众号 众所周知,游戏行业在当今的互联网行业中算是一棵常青树.在疫情之前的 2019 年,中国游戏市场营收规模约 2884.8 亿元,同比增长 17.1%.2020 ...

  4. 以CSGO为例 分析不同网络延时下FPS游戏同步的实现

    FPS游戏中,在玩家的延时都不一样的情况下是如何做到游戏的同步性的? 下面会大量使用CSGO作为例子,这是因为Valve在多人游戏的网络通信方面做得较好,可以当做一个典型来分析. 先讲多人竞技游戏中客 ...

  5. 结构化分析和面向对象分析的区别 例子_管理游戏测评例子

    在测评中心技术中,有一个非常有趣的场景的模拟测评,打造敏捷高绩效团队,提高执行力(包括人才测评),旨在帮助学生培养自主性,了解自己,以独立的意见做出决策,采取果断的行动:培养赋权型领导:树立分享意识, ...

  6. 4、Cocos2dx 3.0游戏开发找小三之Hello World 分析

    尊重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 Hello World 分析 打开新 ...

  7. 游戏运营技术之----运用箱线图分析PCU和DAU(一)

    在我们对PCU和DAU进行分析时,经常采用的方法是做一条曲线比较一下前后两个时期的数据走势,发现问题,进行分析,但是实际过程中,这样的做法远远不能挖掘这两个数据指标更多的内涵和知识.针对本文已经在论坛 ...

  8. 游戏skr而止,漏洞周而复始 —— 游戏合约漏洞全面汇总 | 漏洞分析连载之六

    安全,区块链领域举足轻重的话题,为什么一行代码能瞬间蒸发几十亿市值?合约底层函数的使用不当会引起哪些漏洞?游戏合约中又存在哪些漏洞? 「区块链大本营」携手「成都链安科技」团队重磅推出「合约安全漏洞解析 ...

  9. dnf吸怪源码c语言,[讨论]DNF吸怪/吸物分析(怪物数组)分析

    [讨论]DNF吸怪/吸物分析(怪物数组)分析 2015-11-4 22:30 7662 [讨论]DNF吸怪/吸物分析(怪物数组)分析 2015-11-4 22:30 7662 .版本 2 .子程序 秒 ...

最新文章

  1. CSS实现网页图片预加载
  2. 使用OpenCV自动去除背景色
  3. Java学习-----单例模式
  4. mybatis逆向工程生成的Example类的使用
  5. 1.17 局部内部类
  6. MySQL变量,存储过程,函数,流程控制详解(小白都能懂哦)
  7. leetcode1. 两数之和(两种方法)
  8. mysql 根据时间 获取上个月_MySQL[0]
  9. Python检测U盘插入、自动复制文件并写入新文件
  10. 机器学习第六回-无监督学习—— K-均值算法
  11. CentOS 7 配置yum本地base源和阿里云epel源
  12. ethtool 命令输出的注意点--网卡参数
  13. python定时启动代码_python每天定时运行某程序代码
  14. 【Linux】Windows Ubuntu 双系统开机选择界面设置
  15. 设计模式,六大设计原则,类的特性
  16. 算法竞赛入门经典(第二版)答案——第一部分
  17. FileZilla Server图文安装教程
  18. linux mint借用deepin-wine安装QQ/微信
  19. rundeck 警告邮件QQ邮箱设置
  20. 最高补贴1000元/kW,山东光伏补贴来了

热门文章

  1. NSIS软件打包 脚本代码详解
  2. 软件设计原则:高内聚低耦合
  3. 如何重绘「江南百景图」?近300页 PPT 免费分享!
  4. 网安--第七章 恶意代码分析与防治
  5. php判断搜索引擎是否蜘蛛
  6. 【Verilog - 组合逻辑 - 基础3】4. 与或门-1
  7. 中国信通院:2020年云计算发展白皮书
  8. epub怎么转txt?快来看看这篇文章
  9. 设非零得实系数多项式 $f(x)$ (即系数都是实数得多项式)满足 $f(f(x)) = f^k(x)$,其中 $k$ 是给定得正整数。求多项式 $f(x)$
  10. 谷歌3D人体网站 http://bodybrowser.googlelabs.com/