使用FineReport11 实现贪吃蛇功能
微信公众号:次世代数据技术 关注可了解更多的教程。问题或建议,请公众号留言或联系本人; 如果您有报表开发需求或者定制化功能开发,也可以联系本人; 微信号:weibw162
欢迎关注本人B站进行观看:次世代数据技术 同时,您也可以在抖音及微信视频号平台搜索次世代数据技术进行观看。
有关该游戏的功能介绍可以点击👉🏻1、贪吃蛇-功能介绍 进行查看。
创建游戏基础界面
为了更好的展示游戏功能,我们需要实现以下几块内容:
- 数据展示区:用来展示当前游戏的一些系统数据。
- 玩法讲解区:用来说明游戏操作解释。
- 游戏界面展示区:最重要的部分,用来展示游戏动画界面。
- 操作区:用来存放操作按钮。
- 功能实现点:用来辅助说明功能实现的解释。
首先,我们需要新建一个决策报表,并设置其自适应属性为:绝对布局
和横向自适应
。
数据展示区
数据展示区总共需要展示如下四个数据:得分
、果实位置
、蛇头当前位置
、蛇身
。
我们首先在决策报表中拖入一个报表块,并设置其宽高分别为250
、250
,并调整为双向铺满,设置其组件名称为数据展示
。
双击点击进入该报表块的编辑界面,按照如下图所示进行配置。
其展示效果如下:
玩法讲解区
该区域其实就是对游戏的玩法进行简单的介绍。实现起来也是非常简单。
我们拖入一个报表块,放置在数据展示区报表块位置下方,并设置其宽高分别为250
、150
,并调整为双向铺满。
双击进入,并填入如下文本:
蛇身活动区域会随机生成10个红色果实。玩家需要通过点击下方的四个方向键按钮调整蛇头行进方向。通过不断控制蛇的游走吃掉所有果实则胜利,如果蛇头撞到四周墙壁或自身则失败!
蛇身活动区域会随机生成10个红色果实。玩家需要通过点击下方的四个方向键按钮调整蛇头行进方向。通过不断控制蛇的游走吃掉所有果实则胜利,如果蛇头撞到四周墙壁或自身则失败!
其实现内容及效果如下:
游戏界面展示区
此模块主要就是我们游戏的展示界面,也是功能比较集中复杂的模块。
我们拖入一个报表块,放置在屏幕中央位置,并设置其宽高分别为300
、300
,并调整为双向铺满,设置其组件名称为显示器
。
关于此模块内的具体功能我们在后面展开讲。
操作区
操作区顾名思义,就是我们手动操作的区域,此模块主要实现四个按钮,以及游戏结束后的结算效果。
我们拖入一个报表块,放置在游戏界面展示区报表块位置下方,并设置其宽高分别为300
、100
,并调整为双向铺满,设置其组件名称为操作台
。
同时给该报表块增加一个边框。
然后,根据下方左侧图进行配置,得到右侧的效果图。
功能实现点
该区域主要就是介绍此游戏,我们需要实现哪些功能点。功能点清单如下:
- 蛇身活动范围为15*15的方形区域
- 活动区域下方有四个按钮,分别控制蛇头前进方向
- 页面初始化时需要在活动区域左上角生成蛇头,蛇头颜色为深蓝色
- 页面初始化时需要在活动区域随机生成10个果实的位置,果实所在位置为深红色圆形
- 蛇头吃掉果实时蛇身长度加一,蛇身除蛇头外,需显示淡蓝色
- 蛇在吃掉所有果实后获得胜利,撞墙或者撞到自身则失败
- 胜利时,下方操作台需要从四个按钮变成绿色的
WIN!
标志胜利,同时蛇头需变成深绿色,其余蛇身变为浅绿色 - 失败时,下方操作台需要从四个按钮变成红色的
LOSE!
标志失败,同时蛇头需变成深红色,其余蛇身变成浅红色,未吃掉的果实变成灰色
我们拖入一个报表块,放置在屏幕右侧,并设置其宽高分别为300
、400
,并调整为双向铺满。
按照配置,我们需要在合适的位置输入如下公式:
JOINARRAY(ARRAY("1、蛇身活动范围为15*15的方形区域。","2、活动区域下方有四个按钮,分别控制蛇头前进方向。","3、页面初始化时需要在活动区域左上角生成蛇头,蛇头颜色为深蓝色。","4、页面初始化时需要在活动区域随机生成10个果实的位置,果实所在位置为深红色圆形。","5、蛇头吃掉果实时蛇身长度加一,蛇身除蛇头外,需显示淡蓝色。","6、蛇在吃掉所有果实后获得胜利,撞墙或者撞到自身则失败。","7、胜利时,下方操作台需要从四个按钮变成绿色的`WIN!`标志胜利,同时蛇头需变成深绿色,其余蛇身变为浅绿色。","8、失败时,下方操作台需要从四个按钮变成红色的`LOSE!`标志失败,同时蛇头需变成深红色,其余蛇身变成浅红色,未吃掉的果实变成灰色。"),"\n")
JOINARRAY(ARRAY("1、蛇身活动范围为15*15的方形区域。","2、活动区域下方有四个按钮,分别控制蛇头前进方向。","3、页面初始化时需要在活动区域左上角生成蛇头,蛇头颜色为深蓝色。","4、页面初始化时需要在活动区域随机生成10个果实的位置,果实所在位置为深红色圆形。","5、蛇头吃掉果实时蛇身长度加一,蛇身除蛇头外,需显示淡蓝色。","6、蛇在吃掉所有果实后获得胜利,撞墙或者撞到自身则失败。","7、胜利时,下方操作台需要从四个按钮变成绿色的`WIN!`标志胜利,同时蛇头需变成深绿色,其余蛇身变为浅绿色。","8、失败时,下方操作台需要从四个按钮变成红色的`LOSE!`标志失败,同时蛇头需变成深红色,其余蛇身变成浅红色,未吃掉的果实变成灰色。"),"\n")
其实编辑器界面和最终效果如下:
功能实现
接下来,我们开始一步一步实现整个游戏的所有功能点。
蛇身活动区域
首先第一步就是创建蛇身的活动区域。
在游戏介绍里我们已经知道了,我们的蛇在控制之下是需要在一个15*15
的区域活动,超出该区域就会被认定游戏失败。
首先,将报表块中的A-O
列选中,并统一设置其宽度为20像素
。 同样的操作,将1-15
行选中,并统一设置其高度为20像素
。
最后给整个正方形区域增加一个边框。
这样我们就通过从A1
到O15
的225个单元格创建了一个15*15
的区域活动。
创建模板参数存储游戏变量
我们需要创建几个模板参数,用来记录游戏中的关键变量。
蛇头位置
蛇头位置
用来存储蛇头在行进过程中的实时位置。默认值为左上角的第一个单元格,即A1
。
果实位置
果实位置
用来记录随机生成的10个果实所在单元格位置。
其值如下:
SLICEARRAY(UNIQUEARRAY(MAPARRAY(range(0,50),CONCATENATE(char(RAND()*14+65),INT(RAND()*15+1)))),1,10)
SLICEARRAY(UNIQUEARRAY(MAPARRAY(range(0,50),CONCATENATE(char(RAND()*14+65),INT(RAND()*15+1)))),1,10)
SLICEARRAY( // 通过对数组的切片获取到前10个元素
UNIQUEARRAY( // 将随机生成的50个字符串的数组进行去重
MAPARRAY( // 通过使用MAPARRAY()函数与RANGE()函数的配合随机生成包含50个字符串的数组
range(0, 50),
CONCATENATE( // 将随机生成的字母和数字拼接起来,就得到A1-O15的随机字符串
char( // 随机生成65-79的数,并通过char()函数将该数字转换成A-O的字母
RAND() * 14 + 65
),
INT( // 随机生成1-15的数字
RAND() * 15 + 1
)
)
)
),
1, 10)
SLICEARRAY( // 通过对数组的切片获取到前10个元素
UNIQUEARRAY( // 将随机生成的50个字符串的数组进行去重
MAPARRAY( // 通过使用MAPARRAY()函数与RANGE()函数的配合随机生成包含50个字符串的数组
range(0, 50),
CONCATENATE( // 将随机生成的字母和数字拼接起来,就得到A1-O15的随机字符串
char( // 随机生成65-79的数,并通过char()函数将该数字转换成A-O的字母
RAND() * 14 + 65
),
INT( // 随机生成1-15的数字
RAND() * 15 + 1
)
)
)
),
1, 10)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
针对公式做一下解释:
RAND()
函数随机生成0-1之间的小数RAND() * 14
随机生成 0-14之间的数RAND() * 14 + 65
随机生成 65-79之间的数CHAR(RAND() * 14 + 65)
通过对照ASCII码,将数字转换成A-O的字母CONCATENATE()
将多部分拼接成一个字符串CONCATENATE(char(RAND()*14+65),INT(RAND()*15+1))
随机生成A1-O15的字符串RANGE(0,50)
生成0-50的数字数组MAPARRAY()
数组批量处理函数,针对数组中的每一项进行批量处理吗,然后返回一个处理后的数组MAPARRAY(range(0,50),CONCATENATE(char(RAND()*14+65),INT(RAND()*15+1)))
返回一个随机生成的50个字符串的数组UNIQUEARRAY()
对数组内的元素进行去重SLICEARRAY([],0,10)
对数组进行切片,取前10个元素
从上面的代码我们就能看出来其实我们在生成10个果实位置时使用了一个比较取巧的方案,就是随机生成50个字符串,然后去重后取前10个,这种方案虽然大概率是行得通的,但是依然存在缺陷,大家可以在实现时加入自己的想法,实现一个完美的方案。
另外,还有一个漏洞就是,生成的果实可能会存在A1,也就表示和蛇头冲突,希望大家可以自己修复这个漏洞。
蛇身
从游戏演示中我们就能确定蛇身
这个参数应该是一个数组,并且初始条件下,应该包含蛇头的位置,所以其值应该是ARRAY("A1")
。
游戏结果
游戏结果
参数用来标记当前游戏状态,默认状态为0
,1
表示赢得游戏,-1
表示游戏失败。
将参数放置在数据展示区域
在上面一步我们创建了我们必须的几个模板参数,这些参数正好可以放到数据展示区域。
得分
10 - len($果实位置)
10 - len($果实位置)
果实位置
$果实位置
$果实位置
蛇头当前位置
$蛇头位置
$蛇头位置
蛇身
JOINARRAY($蛇身,"-")
JOINARRAY($蛇身,"-")
其中蛇身通过使用-
将每一节拼接成一个字符串。
具体配置及效果如下:
给单元格填充基础符号
因为目前帆软的设计逻辑,如果我们单元格中无任何内容,则无法通过条件属性调整其背景色等属性。
所以,我们需要在225个单元格中全部统一添加一些内容,来占据单元格。
我们在所有单元格中都填入·
点符号,并设置其文字大小为1,这样在前台就可以实现一个大致的空白内容效果。
除此之外,我们还会在后续的步骤中动态的为单元格中添加值,为了方式单元格出现畸形,我们还需要将所有单元格统一设置为不自动调整
。
将蛇头放置在棋盘上
蛇头默认位置是在A1,但是蛇头会随着玩家的控制进行行进,所以在15*15的布局中,所有单元格都有可能出现蛇头。
我们直接选中区域内所有单元格,并统一增加一个条件属性。
通过判断当前单元格位置与蛇头参数是否相同进行条件显示。
其属性配置为背景色,色值为#39a5f6
,条件为公式:
CONCATENATE(CHAR(COL() + 64),ROW()) = $蛇头位置
CONCATENATE(CHAR(COL() + 64),ROW()) = $蛇头位置
COL()
获取当前单元格所在列数,游戏中应该是1-15CHAR(COL() + 64)
和前面效果一样,返回A-O字母ROW()
获取到当前单元格所在行数,游戏中应该是1-15CONCATENATE(CHAR(COL() + 64),ROW())
获取单元格所在位置,即A1-O15
预览效果如下:
将果实放置在棋盘上
和蛇头一样,我们开局生成的10个果实,也需要放置在棋盘上。其判断逻辑与蛇头大致一样。
给所有单元格增加条件属性 通过判断当前单元格是否存在于果实参数数组中,存在则条件显示。
其属性分为两部分,一个是字体样式,我们给一个红色,加粗,14号字体。另一个是新值,我们给一个●
表示果实的样子。条件为公式:
INARRAY(CONCATENATE(CHAR(COL() + 64),ROW()),$果实位置)>0
INARRAY(CONCATENATE(CHAR(COL() + 64),ROW()),$果实位置)>0
INARRAY()
判断字符串中是否存在某个值,如果大于0表示存在
预览效果如下:
将蛇身放置在棋盘上
随着游戏进行,我们吃掉果实后会出现蛇身。其判断逻辑与蛇头大致一样。
给所有单元格增加条件属性
通过判断当前单元格是否存在于蛇身参数数组中,存在则条件显示。
其属性配置为背景色,色值为#90cdf3
,条件为公式:
INARRAY(CONCATENATE(CHAR(COL() + 64),ROW()) ,$蛇身)>0
INARRAY(CONCATENATE(CHAR(COL() + 64),ROW()) ,$蛇身)>0
INARRAY()
判断字符串中是否存在某个值,如果大于0表示存在
预览效果如下:
我们会发现,蛇身会覆盖掉蛇头的效果。这是因为条件属性的优先级是从下向上,越是靠下的,优先级越高
。所以,我们需要将三个条件属性的位置进行调换。
重新预览
控制蛇头向右
操作台点击右
键实现蛇头向右侧行进一步。
逻辑上其实就是蛇头所在位置的字母加1,即从A1变成B1,从D12变E12。
实现此功能,我们需要给操作台的右
按钮所在单元格增加一个超级链接,模拟点击的动作。
超级链接类型为当前决策报表对象
,其中表单对象选择显示器
这个报表块,传递的参数为蛇头位置
,值为公式
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
我们将公式展开:
CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) + 1
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
)
CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) + 1
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
split($蛇头位置, "")
将蛇头所在位置的字符串拆成单字符的数组,比如A1拆成[A,1]
,B14拆成[B,1,4]
regexp()
正则判断GREPARRAY()
过滤数组GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]"))
获取到蛇头位置的字符串的字母字符,即A1中的A,B14中的BJOINARRAY()
将数组按照指定字符串进行拼接,拼接成新的长字符串JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")
将上面提取出的字母字符串,使用空字符串拼接成新的字符串CODE()
将字母转换成ASCII码数字CHAR(CODE()+1)
将字母转换成ASCII码数字后加1,再转换回字符,即从A变成B,B变成CGREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]"))
匹配蛇头位置参数中的数字部分CONCATENATE()
多段内容进行字符串拼接
预览效果如下:
实现以上效果后,我们连续点击右键,发现并不能实现多次移动。第一次点击有效果,第二次以后就没有效果了。这是因为,我们给显示器报表块传递了最新的蛇头位置参数的值,但是并没有对操作台传递最新的值。
所以,我们还需要再新增一个超级链接,将新的蛇头位置传递给操作台。表单对象选择操作台
这个报表块,传递的参数为蛇头位置
,值为公式,与上面完全一致
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
预览效果如下:
最后,我们还需要将此参数传递给数据展示区域,用来实时展示蛇头所在位置。
直接复制一个超级链接,修改表单对象及名称即可。
控制蛇头向左
蛇头向左向右其实就是在公式中加一和减一的区别。
由上个步骤我们可以知道,我们其实是在给三个组件显示器
、控制台
、数据展示
,传递了完全一致的参数蛇头位置
。
蛇头向左行进其实也是同样的逻辑。
我们给左键单元格增加三个超级链接,类型为当前决策报表对象
,传递的参数为蛇头位置
,值为公式:
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
将公式展开如下,可以看出来唯一区别就是字母部分左移是减1,右移是加1。
CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) - 1 // 唯一区别
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
)
CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) - 1 // 唯一区别
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
预览效果如下:
控制蛇头向下
前面的步骤我们实现了蛇头的水平方向左右行进。其原理是通过改变蛇头参数的字符串中的字母字符,左行进则减1,右行进则加1。
其实蛇头向下也是差不多的逻辑,不过我们需要调整的不再是字母字符,而是后面代表垂直位置的数字字符。比如 从A1变成A2则表示向下移动一位。
我们给下键所在单元格添加一个超级链接,类型为当前决策报表对象
,其中表单对象选择显示器
这个报表块,传递的参数为蛇头位置
,值为公式:
CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") + 1)
CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") + 1)
CONCATENATE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
), "") + 1
)
CONCATENATE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
), "") + 1
)
2
3
4
5
6
7
8
9
10
11
12
13
14
此公式与水平行进的公式差不多,这里不针对每个细节重复讲解。
按照之前的惯例,我们除了需要将参数传递给显示器外,还需要传递给操作台和数据展示两个组件。我们可以直接将该超级链接复制两份,然后修改其表单对象即可。
控制蛇头向上
蛇头向上行进其实和向下行进也一样,唯一区别就是向下行进时数字字符串加1,向上行进时数字字符串减1。
我们将下键的超级链接批量复制到上键单元格中,然后修改其公式为:
CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") - 1)
CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") - 1)
上下左右四个按钮的动作功能都配置好后,预览如下:
至此,我们完成了蛇头行进的控制
控制蛇头吃掉果实-果实处理
当玩家控制蛇头行进时,如果路径上出现红色的果实,可通过驱使蛇头行进至与果实同一个单元格,表示蛇吃掉果实。
这里有一个逻辑:
- 如果蛇头下一步的单元格在
果实位置
数组参数中,则需要将该位置从参数中移除掉 - 如果蛇头下一步的单元格不在
果实位置
数组参数中,那果实位置
的值应该不变。
所以,我们使用伪代码实现该公式则可以这样写:
如果 蛇头新的位置 存在于 果实位置数组
则 从 果实位置数组 中 移除该位置所在元素
否则 果实位置不变
如果 蛇头新的位置 存在于 果实位置数组
则 从 果实位置数组 中 移除该位置所在元素
否则 果实位置不变
2
3
我们首先拿右键来实现。
其中伪代码中的果实位置数组
就是我们的模板参数$果实位置
。我们将其带入到伪代码中:
if (
INARRAY(
<蛇头新位置>,
$果实位置
) > 0,
GREPARRAY(
$果实位置,
item != <蛇头新位置>
),
$果实位置
)
if (
INARRAY(
<蛇头新位置>,
$果实位置
) > 0,
GREPARRAY(
$果实位置,
item != <蛇头新位置>
),
$果实位置
)
2
3
4
5
6
7
8
9
10
11
INARRAY()
判断元素在数组中的位置,我们可以用此函数来判断元素是否存在于数组中,大于0表示存在,否则不存在。GREPARRAY()
用来过滤数组,当条件成立时留下该元素,否则移除。这里通过判断每个位置元素与蛇头新位置是否相同来执行是否移除。
IF()
函数最后判断如果蛇头新位置
不存在于$果实位置
中的话,则返回$果实位置
。
伪代码中的蛇头新位置
,其实就是之前步骤里的代码
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
我们将代码替换到伪代码中,如下:
if (
INARRAY(
CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) + 1
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
),
$果实位置
) > 0,
GREPARRAY(
$果实位置,
item != CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) + 1
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
)
),
$果实位置
)
if (
INARRAY(
CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) + 1
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
),
$果实位置
) > 0,
GREPARRAY(
$果实位置,
item != CONCATENATE(
CHAR(
CODE(
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[A-Z]")
),
""
)
) + 1
),
JOINARRAY(
GREPARRAY(
split($蛇头位置, ""),
regexp(item, "[0-9]")
),
""
)
)
),
$果实位置
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
压缩后代码如下:
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置)
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置)
我们对右键的三个超级链接分别添加一个参数果实位置
,并填入上面的公式。
然后,我们预览一下效果:
预览效果中,我们需要注意几点:
- 在蛇头向右侧行进过程中,
蛇头当前位置
始终在变化。 - 蛇头第一次与
J1
单元格位置的果实重合时,数据展示区域的果实位置
由F4,M1,H2,B12,D5,A10,A13,I4,B7,J1
变成F4,M1,H2,B12,D5,A10,A13,I4,B7
,J1
是被吃掉了。同理在后面与第二个果实重合时,M1
所在单元格也被吃掉。 得分
是10减去果实位置
参数的长度,所以当吃掉第一个果实后,果实位置参数变为9个,也就得1分。
同样的逻辑,我们值需要将伪代码中的蛇头新位置
分别替换为各个按钮上的公式即可完成果实位置参数的值。
右键
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置)
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置)
左键
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置)
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置)
下键
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") + 1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") + 1)),$果实位置)
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") + 1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") + 1)),$果实位置)
上键
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") - 1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") - 1)),$果实位置)
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") - 1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"") - 1)),$果实位置)
将上述所有公式添加完毕后就完成了蛇吃果实,果实消失的效果,这里不重复演示了。
相信好多朋友看到这一步,已经对着密密麻麻的公式感到恐惧了。我只能说,别急,后面的会更长。
公式只是看着长而已,如果按照我们的伪代码进行逐步拆解,其实还是挺容易理解的,不是吗?。
控制蛇头吃掉果实-蛇身处理
在前一步,我们处理了蛇吃掉果实的效果。按照我们玩过的贪吃蛇游戏的操作来看,蛇头吃掉果实后,蛇身长度应该变长一节。
首先,我们先来分析一下蛇身的行进逻辑。蛇身其实从编程的角度来看,就是一个队列,其特性就是先进先出
,或者说叫加头去尾
。
举个例子,假设现在蛇身为A1-B1-C1
,其中C1为蛇头,A1为蛇尾。如果蛇头向右行进一步,则蛇身整体向右移动一步,变为B1-C1-D1
,此时蛇头为D1,同时将蛇尾A1
舍弃。但是如果行进路上出现果实,如D1单元格存在一个果实,那么蛇身应该变为A1-B1-C1-D1
,此时则只需要加头,尾部因为增加一节的缘故不需要剔除。
我们分析一下蛇身的公式逻辑:
如果 蛇头新位置 不存在于 果实位置 中
则 将蛇头新位置 加入到 蛇身 中,并将 蛇身 尾部元素删除
否则 将蛇头新位置 加入到 蛇身 中
如果 蛇头新位置 不存在于 果实位置 中
则 将蛇头新位置 加入到 蛇身 中,并将 蛇身 尾部元素删除
否则 将蛇头新位置 加入到 蛇身 中
2
3
我们同样首先拿右键来实现。
伪代码中的果实位置
为模板参数$果实位置
,蛇身为$蛇身
,我们将其带入到伪代码,得到如下:
if (
INARRAY(
<蛇头新位置>,
$果实位置
) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
<蛇头新位置>
),
len(
ADD2ARRAY(
$蛇身,
<蛇头新位置>
)
),
1
),
ADD2ARRAY(
$蛇身,
<蛇头新位置>
)
)
if (
INARRAY(
<蛇头新位置>,
$果实位置
) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
<蛇头新位置>
),
len(
ADD2ARRAY(
$蛇身,
<蛇头新位置>
)
),
1
),
ADD2ARRAY(
$蛇身,
<蛇头新位置>
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
INARRAY()=0
判断蛇头新位置不在果实位置数组中ADD2ARRAY()
将蛇头新位置拼接到蛇身中len()
获取拼接完成后的蛇身的长度REMOVEARRAY(,1)
移除蛇身数组中的最后一个元素,即表示移除蛇尾
伪代码中的蛇头新位置
,其实就是之前步骤里的代码
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))
我们将代码替换到伪代码中,如下:
if (
INARRAY(
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置
) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
len(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
),
1
),
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
)
if (
INARRAY(
CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置
) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
len(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
),
1
),
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
我们对右键的三个超级链接分别添加一个参数果实位置
,并填入上面的公式。
填入后,通过操作点击右键,可以看到左侧的数据展示区域中的蛇身发生变化
需要注意的是,此时显示器中是不会显示蛇身的长度发生变化的,也就是界面中依旧只显示了一个蛇头,后面的步骤我们会增加显示,稍安勿躁。
同样的逻辑,我们只需要将伪代码中的蛇头新位置
分别替换为各个按钮上的公式即可完成果实位置参数的值。
右键
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))
左键
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))
if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))
下键
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)))
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)))
上键
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)))
if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)))
完成以上步骤,我们就实现了整个蛇身的移动,以及吃掉果实后蛇身的变化。
接下来,我们继续实现蛇身在界面的展示功能。
蛇身的展示其实和蛇头的展示大致相同,我们需要在225个单元格上统一增加一个用来显示蛇身的条件属性即可。其属性为背景色
,色值为#90cdf3
。条件为公式:
INARRAY(CONCATENATE(CHAR(COL() + 64),ROW()) ,$蛇身)>0
INARRAY(CONCATENATE(CHAR(COL() + 64),ROW()) ,$蛇身)>0
逻辑很简单,判断当前单元格是否存在于蛇身参数中,存在则条件显示。
预览效果如下:
预览后,就会发现一个问题,虽然整个蛇身都显示出来了,但是蛇身完全都是一个浅蓝色的状态,看不出蛇头的位置了。这是因为条件属性的优先级是由下向上
的,越是靠下的条件属性,优先级越高。所以解决方案很简单,只需要将蛇头的条件属性挪到最下方即可:
调整后,重新预览如下:
至此,我们完成了蛇吃果实的效果。
判断游戏输赢-参数处理
贪吃蛇游戏判断玩家赢得游戏非常简单,只要吃掉所有果实即表示赢得游戏。
但是判断游戏失败有多种情况:
- 蛇头碰到墙壁
- 蛇头碰到蛇身,需要注意的是,蛇头原地反向走也算碰到蛇身
我们按照以上逻辑,整理代码逻辑如下:
如果
新蛇身 去重后 长度 小于 原蛇身 长度 // 蛇咬到自己
且 新蛇身 长度 大于1 // 蛇只有蛇头时无法咬到自己
或
当前蛇头 已经在棋盘最边界 // 下一步就会撞到边界
则 游戏失败
否则
如果 新果实位置 长度 等于0 // 果实吃完
则游戏胜利
否则
游戏继续
如果
新蛇身 去重后 长度 小于 原蛇身 长度 // 蛇咬到自己
且 新蛇身 长度 大于1 // 蛇只有蛇头时无法咬到自己
或
当前蛇头 已经在棋盘最边界 // 下一步就会撞到边界
则 游戏失败
否则
如果 新果实位置 长度 等于0 // 果实吃完
则游戏胜利
否则
游戏继续
2
3
4
5
6
7
8
9
10
11
12
13
我们将原蛇身
参数$蛇身
带入到伪代码中,得到如下:
IF(
OR(
AND(
len(UNIQUEARRAY(<新蛇身>)) <LEN($蛇身),
LEN(<新蛇身>)> 1
),
<蛇头已经在边界>
),
-1,
IF(LEN(<新果实位置>)=0, 1, 0)
)
IF(
OR(
AND(
len(UNIQUEARRAY(<新蛇身>)) <LEN($蛇身),
LEN(<新蛇身>)> 1
),
<蛇头已经在边界>
),
-1,
IF(LEN(<新果实位置>)=0, 1, 0)
)
2
3
4
5
6
7
8
9
10
11
我们同样首先拿右键来实现。
在上述伪代码中,新蛇身
和新果实位置
在前面的步骤中我们已经写过了,拿来直接替换进去即可。
蛇头已经在边界
的公式如下:
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "") = "O"
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "") = "O"
通过判断当前蛇头位置所在单元格的字母是否是O
即第15列来判断蛇头是否在边界。
将以上所有变量替换后,得到如下公式:
IF(
OR(
AND(
len(
UNIQUEARRAY(
if(
INARRAY(
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
len(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
),
1
),
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
)
)
) <LEN($蛇身),
LEN(
if(
INARRAY(
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
len(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
),
1
),
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
)
)> 1
),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "") = "O"
),
-1,
IF(
LEN(
if(
INARRAY(
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置
) > 0,
GREPARRAY(
$果实位置,
item != CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
$果实位置
)
)=0,
1,
0
)
)
IF(
OR(
AND(
len(
UNIQUEARRAY(
if(
INARRAY(
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
len(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
),
1
),
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
)
)
) <LEN($蛇身),
LEN(
if(
INARRAY(
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置) = 0,
REMOVEARRAY(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
len(
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
),
1
),
ADD2ARRAY(
$蛇身,
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
)
)
)> 1
),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "") = "O"
),
-1,
IF(
LEN(
if(
INARRAY(
CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
),
$果实位置
) > 0,
GREPARRAY(
$果实位置,
item != CONCATENATE(
CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[A-Z]")), "")) + 1),
JOINARRAY(GREPARRAY(split($蛇头位置, ""), regexp(item, "[0-9]")), "")
)
),
$果实位置
)
)=0,
1,
0
)
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
压缩后,得到如下代码:
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")="O"),-1,IF(LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置))=0,1,0))
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")="O"),-1,IF(LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置))=0,1,0))
和上面的逻辑一致,我们需要给三个超级链接,分别添加参数游戏结果
,值即为上面的公式。
同样的逻辑,我们需要将伪代码中的参数分别替换为各个按钮上的公式即可完成游戏结果
参数的值。
右键
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")="O"),-1,IF(LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置))=0,1,0))
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")="O"),-1,IF(LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))+1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置))=0,1,0))
左键
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")="A"),-1,IF(LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置))=0,1,0))
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),len(ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))),1),ADD2ARRAY($蛇身,CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),"")="A"),-1,IF(LEN(if(INARRAY(CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(CHAR(CODE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""))-1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),""))),$果实位置))=0,1,0))
下键
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")=15),-1,IF(LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),$果实位置))=0,1,0))
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")=15),-1,IF(LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")+1)),$果实位置))=0,1,0))
上键
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")=1),-1,IF(LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),$果实位置))=0,1,0))
IF(OR(AND(len(UNIQUEARRAY(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)))))<LEN($蛇身),LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)=0,REMOVEARRAY(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),len(ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))),1),ADD2ARRAY($蛇身,CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1))))>1),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")=1),-1,IF(LEN(if(INARRAY(CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1),$果实位置)>0,GREPARRAY($果实位置,item!=CONCATENATE(JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[A-Z]")),""),JOINARRAY(GREPARRAY(split($蛇头位置,""),regexp(item,"[0-9]")),"")-1)),$果实位置))=0,1,0))
到这里,我们已经将游戏的判定做完了,但是还没有地方能展示我们游戏最终的结果。
别急,接下来马上开始…
判断游戏输赢-操作台处理
虽然我们在上面的步骤中实现了游戏的属性判断,但是因为没有做控制,导致即便游戏已经结束了,还可以通过操作台控制蛇头的行进。
很明显,这不符合要求。所以,我们需要控制当游戏结束时四个方向键将不支持继续点击。
但是,在我们的演示中,其实在操作台还有一个演示,就是需要展示游戏的最终结果。
综合考虑,其实我们可以将这两个需求合并起来一起做。
首先,无论游戏输赢,操作台的几个按钮都将消失,换句话说就是都要被隐藏掉。这个过程其实非常简单,我们可以通过条件属性,将操作按钮所在的范围的单元格统一增加一个条件属性。
其中,属性选择行高 0像素
,条件选择公式$游戏结果!=0
。
然后,我们需要在操作按钮区域下放的单元格中再放置高度9个单元格的区域,并合并成一个大单元格。
在单元格中添加文字LOSE!
,并调整样式。同时还需要给该单元格增加一个条件属性,属性选择行高 0像素
,条件选择公式$游戏结果>=0
。
然后,我们需要在LOSE!
区域下放的单元格中再放置高度9个单元格的区域,并合并成一个大单元格。
在单元格中添加文字Win!
,并调整样式。同时还需要给该单元格增加一个条件属性,属性选择行高 0像素
,条件选择公式$游戏结果<=0
。
完成以上步骤,我们重新预览,即可看到游戏结束时的效果了。
由于游戏耗时较久,这里不做演示。
判断游戏输赢-显示器处理
接下来就是整个游戏的最后一步,处理游戏结束时蛇身的效果及剩余果实的效果展示。
首先,我们要梳理清楚我们需要处理的逻辑:
- 果实
- 如果游戏输了,剩余果实颜色变成灰色
- 蛇头
- 如果游戏赢了,呈现深绿色
- 如果游戏输了,呈现深红色
- 蛇身
- 如果游戏赢了,呈现浅绿色
- 如果游戏输了,呈现浅红色
按照以上逻辑,我们需要针对显示器报表块内的所有单元格增加5个统一的条件属性。
果实-输游戏
复制果实的条件属性,并调整属性中的字体
颜色改为灰色。同时增加一个条件公式$游戏结果<0
。
蛇头-赢游戏
复制蛇头的条件属性,并调整属性中的背景
颜色改为深绿色。同时增加一个条件公式$游戏结果>0
。
蛇头-输游戏
复制蛇头的条件属性,并调整属性中的背景
颜色改为深红色。同时增加一个条件公式$游戏结果<0
。
蛇身-赢游戏
复制蛇身的条件属性,并调整属性中的背景
颜色改为浅绿色。同时增加一个条件公式$游戏结果>0
。
蛇身-输游戏
复制蛇身的条件属性,并调整属性中的背景
颜色改为浅红色。同时增加一个条件公式$游戏结果<0
。
至此,我们的整个游戏就算开发完毕。
如果你坚持下来了,牛逼!
拓展
虽然我们已经开发完毕了,但是某个场景还是不够完美,或者不足,或者bug。如果你跟着教程顺利开发出来了,那么有没有信心在此基础上进行一定的拓展呢?
比如下面这些功能:
- 果实初识化时不允许在A1位置,也就是不允许和蛇头初始化在同一个地方?
- 游戏初始化后,蛇头随机出现,长度也随机?
- 在吃完固定的10个果实后,每移动5步,屏幕上自动新增一个果实,但仅允许同时存在一个果实?
- 随机生成的果实按照颜色划分等级,不同颜色的果实吃掉后,增加对应等级的分数?
等……