吴昊品游戏核心算法 Round 17(补遗篇) —— 单词游戏(前篇)

最近,我的大学生创新基金快结题了,在忙碌之中,我在思考着这一年的积累。这 是一段比较长的时间吧,本来想的是做成一个单词游戏软件的(基于android系统),但是在导师的意思下,她认为她儿子在华师一附中嘛,本来天性就非常 好玩,而且,她怀疑这种模式记单词是否有效果。最后,我改进了自己的思路,准备做出一款类似于目前市面上的ToWords的游戏。但是,进展的难度大大高 于我的预期,首先,是人员的选择,很多人都是中途凑热闹,而并没有持之以恒。所以,最后基本上是我和一个女生一起完成的,还部分借鉴了Github和部分 开源社区的源码,自己对android的UI也没有真正掌握,导致一触及到底层的东西,自己就一点办法都没有了。

  ToWords

 

  不 过,说归说吧!这一年话的时间确实也不多,但是,也积累了一些常见的关于单词处理的方法。在单词出现的算法上,原本考虑利用数据挖掘的相关方法对单词进行 处理的,但是,吸取到拓词的启发,我得到了如下的结论:如果单单考虑一个记单词游戏所带给玩家的智能程度的话,其实,利用拓词那种简易的方式就足够了。在 算法中过分地追求人的记忆的科学性,只会导致游戏运行起来速度变得缓慢,而这种科学性会随着速度而大打折扣。所以说,与其过分地强调科学性,速度乃是第一 重要之因素。

  那么,市面上的单词游戏怎么样呢?其实,也是很多的,有些并不是本来就在生活中存在这样的游戏,而是和一些传统的经典游戏相互结合,而产生了一种比较有趣的游戏,比如如下两款,比较经典:

  Letrix US English

 

  这是一款叫Letrix US English的游戏,很明显地,它由经典游戏俄罗斯方块改编过来的。这款游戏很好地运用了触屏的功能,用游戏者自己的手点击自己选定的单词(根据时间的 顺序对单词的字母进行前后排序)。如图所示,当选定了NAVY的时候,系统的后台会判断这几个字母按照点击顺序是否可以组合成一个单词。如果可以的话,就 将其消去,同时,剩下的单词会逐渐下落,但是如果不是的话,就会取消消去行为。

  这款游戏我将结合后面的“吴昊教你玩俄罗斯方块”进行详细阐述,目前这里只是简单介绍一下。

  另一款也颇为经典,它是结合了一款经典的叫做“连连看”的游戏而组合成为了“单词连连看”(另外,有一个和我一届的申报了大学生创新基金的团队在做另外一个与单词有关的项目,叫做——单词连连看,颇为经典)

  Word up

 

  如图所示,这是这款游戏的主界面和游戏界面,右图中,我们可以用自己的手指以横,竖和斜三种方式来操纵字母的移动顺序。不过,这里和“单词俄罗斯方块”相 比,单词连连看中,比较局限的一点是,你的手指只能在没有抬起来之前将所有的字母按照一定顺序选中。因为,只要你的手指头一抬起来,就要算你这一回合结束 了(注意,在你每次用手指划分的时候,方向是可以在中途变换的,无论是横,竖还是斜)。

  该游戏的数学模型可以考虑如下:

 

  我们考虑BEG和GEE这两个单词,有如下一些方法可以进行搜寻。

  我们这里可以简单地写一个方法来实现如下一个AI:将方格上所有需要消去的单词消去之后,我们可以找到剩下来的单词(我们这里按照字母表的顺序排列),也就是我们这里得到的“神秘单词”。

  我们假设输入和输出如下:

  Input:整个游戏界面以及玩家希望划出的单词(这些单词不一定可以在游戏界面中找到,具体的方法在标称中会以自然语言说出)

  Output:输出剩余的单词组成的“神秘单词”

 

 1 #include<stdio.h>
 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 

posted on 2013-04-17 19:56  吴昊系列  阅读(1083)  评论(0编辑  收藏  举报

导航