吴昊品游戏核心算法 Round 17(补遗篇) —— 单词游戏(前篇)
ToWords
不 过,说归说吧!这一年话的时间确实也不多,但是,也积累了一些常见的关于单词处理的方法。在单词出现的算法上,原本考虑利用数据挖掘的相关方法对单词进行 处理的,但是,吸取到拓词的启发,我得到了如下的结论:如果单单考虑一个记单词游戏所带给玩家的智能程度的话,其实,利用拓词那种简易的方式就足够了。在 算法中过分地追求人的记忆的科学性,只会导致游戏运行起来速度变得缓慢,而这种科学性会随着速度而大打折扣。所以说,与其过分地强调科学性,速度乃是第一 重要之因素。
那么,市面上的单词游戏怎么样呢?其实,也是很多的,有些并不是本来就在生活中存在这样的游戏,而是和一些传统的经典游戏相互结合,而产生了一种比较有趣的游戏,比如如下两款,比较经典:
Letrix US English
这是一款叫Letrix US English的游戏,很明显地,它由经典游戏俄罗斯方块改编过来的。这款游戏很好地运用了触屏的功能,用游戏者自己的手点击自己选定的单词(根据时间的 顺序对单词的字母进行前后排序)。如图所示,当选定了NAVY的时候,系统的后台会判断这几个字母按照点击顺序是否可以组合成一个单词。如果可以的话,就 将其消去,同时,剩下的单词会逐渐下落,但是如果不是的话,就会取消消去行为。
这款游戏我将结合后面的“吴昊教你玩俄罗斯方块”进行详细阐述,目前这里只是简单介绍一下。
另一款也颇为经典,它是结合了一款经典的叫做“连连看”的游戏而组合成为了“单词连连看”(另外,有一个和我一届的申报了大学生创新基金的团队在做另外一个与单词有关的项目,叫做——单词连连看,颇为经典)
Word up
如图所示,这是这款游戏的主界面和游戏界面,右图中,我们可以用自己的手指以横,竖和斜三种方式来操纵字母的移动顺序。不过,这里和“单词俄罗斯方块”相 比,单词连连看中,比较局限的一点是,你的手指只能在没有抬起来之前将所有的字母按照一定顺序选中。因为,只要你的手指头一抬起来,就要算你这一回合结束 了(注意,在你每次用手指划分的时候,方向是可以在中途变换的,无论是横,竖还是斜)。
该游戏的数学模型可以考虑如下:
我们考虑BEG和GEE这两个单词,有如下一些方法可以进行搜寻。
我们这里可以简单地写一个方法来实现如下一个AI:将方格上所有需要消去的单词消去之后,我们可以找到剩下来的单词(我们这里按照字母表的顺序排列),也就是我们这里得到的“神秘单词”。
我们假设输入和输出如下:
Input:整个游戏界面以及玩家希望划出的单词(这些单词不一定可以在游戏界面中找到,具体的方法在标称中会以自然语言说出)
Output:输出剩余的单词组成的“神秘单词”
2
3 int main()
4 {
5 int characters[26];
6 int n,m,p;
7 int i,j;
8 for(i=0;i<26;i++)
9 characters[i]=0;
10 scanf("%d%d%d",&n,&m,&p);
11 //读入一个游戏界面
12 for(i=0;i<n;i++)
13 {
14 char str[11];
15 scanf("%s",str);
16 for(j=0;str[j]!='\0';i++)
17 characters[str[j]-'A']++;
18 }
19 //这里略去一个实现,作为check()
20 int check(char *a)
21 {
22 /*
23 假如输入的单词在这一个数组中,我们则对数组中的第一个字母寻找在游戏界面中与之相似的字母
24 之后,利用方向数组对这个字母周边的八个字母进行展开(这里要考虑到越界的条件),逐一匹配
25 并最终找到第二个字母,之后,在找到的第二个字母中,将其对它的余下的七个方向进行搜索,就
26 是这样的一个过程,直到找到最后一个单词位置,并将它们全部挖空。这里,考虑到问题的复杂性
27 只给出方法,我们假设我们读者写出的p个单词都是可以找到的,基于这一点上进行分析
28 */
29 }
30 //上一段中累积字母,这一段则是除去的功能
31 for(i=0;i<p;i++)
32 {
33 char str[200];
34 scanf("%s",str);
35 for(j=0;str[j]!='\0';j++)
36 characters[str[j]-'A']--;
37 }
38 //这里按照字典序输出"神秘单词"
39 for(i=0;i<26;i++)
40 {
41 //这里巧妙地将字母换成了数字
42 if(characters[i]!=0)
43 {
44 for(j=0;j<characters[i];j++)
45 {
46 printf("%c",i+'A');
47 }
48 }
49 printf("\n");
50 }
51 return 0;
52 }
53