java 2048思路_浅谈2048

PS:还没有更新完,日后会陆续更新,并配上彩图,方便理解!

关于2048的一些心得

本人比较菜(其实是没有太多时间去玩了),只玩到了4096分,现在把自己的一些技巧分享给大家

(本文需要前置知识:分治,贪心,递归)

整体思路

首先观察这个图,是一个16个格子的矩阵,失败的终点是无法再合并

考虑合并的规则\(2\;to\;4,4\;to\;8,8\;to\;16\),依次类推,可以发现,可以用\(2^{x-1}\)可以得到\(2^x\)其中\((1 \leq x)\)

而游戏所能获得的分值也随着合并之后所得到的数的大小而递增

我们考虑如何最优化合并,以得到2048为例子,想要得到2048(\(2^{11}\)),就要通过两个1024(\(2^{10}\))来合并得到

而每一个1024(\(2^{10}\))需要两个512(\(2^9\))来合并,以此类推,我们发现,必须是\(2^{max-1}\)与\(2^{max-2}\)挨在一起

这样我们只需要得到一个\(2^{max-2}\)就可以合并得到\(2^{max}\)

在此我规定把当前最大值\(2^{max-1}\)堆在矩阵的右下方,把当前次大值\(2^{max-2}\)紧挨着最大值放(也就是矩阵的最后一行从右往左数,第二个位置,因为第一个位置被\(2^{max-1}\)放了)

我们考虑在除了右下方的地方进行乱搞,得到\(2^{max-2}\),然后就可以进行合并\(2^{max-2}\times2\;to\;2^{max-1},2^{max-1}\times2\;to\;2^{max}\)

至此,整体思路分析完毕。

具体细节

首先明白移位的意义是什么

移位并不是瞎动,每一步都有每一步的作用,每一步都要顾全大局,每一步都是为了合并出更大的max而做基础。

考虑具体每一步怎么走

开局随便玩,尽量把最大值往右下方堆积起来,闭着眼睛几乎都可以完成的事情。

我们希望的是当前的最大值永远在最下最右的地方,所以每一步都要保证最大值没有移位

也就是说,慎用或者可以的话,不要用左移和上移,考虑左移的影响,极其有可能是你当前的最大值,到了属于当前次大值的位置,然后在本属于最大值的位置,冒出了一个2;考虑上移的影响,极其有可能是在你最大值的下方新冒出来的2占据了当前最大值的位置,如果出现以上两种情况,基本上是GG了,对于前者有一种补救办法叫做“围魏救赵”,文章末尾会提到

为什么要上移?

假如说你把最下层的8个格子刚好占满,且刚好无法合并,并且没有多余的格子,这时候你无论左移还是右移都是无效的,你只能上移(有一次我最底下依次是\({4096\;2048\;1024\;512\;256\;128\;64\;32}\),但是没有办法,不得不上移,于是我就GG了)

为什么要左移?

1.最后一行没有补齐(也就是有空位),并且当前你再怎么右移也无法进行合并,因此就需要左移(这就是上文提到的风险情况)

2.如果最后一行是补齐的,并且左移之后,你会合并某些项数,意味着你在合并之后,会出现空位,也就有可能成为上文提到的风险情况,有个技巧叫“延迟合并”在大多数情况下会避免这种合并之后出现空位乃至GG的尴尬,文章的末尾会提到这些的

每次移动,尽量下移,这样大多数情况下可以保证你不需要上移,尽量右移,保证你不需要左移

如果在你可以下移可以右移的情况下,大多数选择尽量下移,因为上移可能带来的风险更大,且补救成功的概率为零

相比左移带来的影响,就要小一些,大多数情况可以补救成功(在最大值小于等于1024的时候概率最大).

“围魏救赵”:

设当前的右下方的的数为\(x\)

考虑把当前的\(x\)培养成当前最大值,就可以和\(x\)右边的最大值进行合并

于是我们只能在靠右的一两列作为\(x\)的“移位储备资源库”,每一次都必须使得\(x\)上面的数和当前右下方\(x\)一样,然后可以合并

合并时保持如此原则:能向右合并,尽量不向左;能向下合并,尽量不向上

当能向右和向下的时候,我们选择向右,因为向下有概率和底层\(x\)旁边的数进行合并,而不是\(x\)(注意区分与上文的区别)

“延迟合并”:

在当前这一行可以合并的时候,我们先不去左移或者右移,先尽量下移,使我们有足够多的储备合并块(就是一些零散的2,4,8之类的),然后再左右移合并,可以大大降低自己出锅的概率,具体原理读者自证不难

关于配图,日后会补上的

结语

因为2048每次移位后出现的2与4都是随机化的,因此无法设计出一种完美无缺的算法,达到\(2^{16}\)

只能通过一些技巧来规避,但是无法避免失误,难免会在你成功前的一瞬间,出现一个不速之客“2”,使你顿时GG。

于是你就很抓狂,恼怒,生气!

而游戏所吸引我们的,不正是如此吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Session是Java Web中常用的一种状态管理技术,它可以在不同的HTTP请求之间共享数据,常用于用户登录、购物车等场景。下面我来浅谈一下Session的使用。 Session的创建 在Servlet中,可以通过HttpServletRequest的getSession()方法来获取或创建Session对象。如果请求中已经存在Session,则返回已经存在的对象,否则创建一个新的Session对象并返回。示例代码如下: ```java HttpSession session = request.getSession(); ``` Session的存储 Session中的数据存储在服务器端,可以通过setAttribute()方法向Session中存储数据。示例代码如下: ```java session.setAttribute("username", "张三"); ``` Session的获取 在Session中存储的数据可以通过getAttribute()方法获取。示例代码如下: ```java String username = (String) session.getAttribute("username"); ``` Session的过期 Session有两种过期方式:基于时间的过期和基于使用次数的过期。基于时间的过期是指Session在一定时间内有被使用,则失效;基于使用次数的过期是指Session在一定时间内有被使用,则失效。 在web.xml中可以设置Session的过期时间,示例代码如下: ```xml <session-config> <session-timeout>30</session-timeout> </session-config> ``` 上述代码表示Session的过期时间为30分钟。 Session的销毁 Session可以通过invalidate()方法销毁。示例代码如下: ```java session.invalidate(); ``` 总结 Session是Java Web中常用的一种状态管理技术,可以在不同的HTTP请求之间共享数据。Session的使用需要注意过期时间和销毁方式,以免造成安全隐患和资源浪费。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值