(此图选自口袋妖怪红宝石的某个镇的娱乐场所的赌博机)
这款777赌博机存在于日本的赌场,这里,我不想再像以前一样,通过各种百科COPY一些资料,这样没有意思。我谈谈自己当年玩POKEMON时的感受吧!
赌博机分两种投币模式,一种是一次100个币,一种是一次50个币,我认为任天堂在整个城镇的设计中很独到。比如,有些城镇比较古朴(比如:鬼斯,鬼斯通等出现的城镇,给人一种云雾缭绕的感觉),而有些城镇则比较偏娱乐,比如有娱乐中心的城镇(当然,赌博机乃是必不可少的道具)。我们可以看到,不同的城镇既有共性又有个性。比如,每个城镇都会有道馆和精灵中心(每个道馆也许还会不一样,这反映出了谜题的不一样),但是,每个城镇又确实具有独具特色的标志。
以上,我们来解剖一个口袋妖怪赌博机的构造。如果我们转到三个相同的图标(比如三个皮卡丘),那就中了头彩(777)。我们假设这台机器上有N个数字,并且我们将其引入一些确定性因素(在实际中,是利用srand做种,利用rand生成随机数,这里,考虑到输入输出的确定性,我们这样来设置按钮,假设其每次可以控制各位的增加,那么,最终会变为POJ 2316)
Ozy在短码之美中详尽地阐述了这一问题,并利用各种BT的技法将代码缩短到五行(感觉,这样整真心没有必要啊,短码是很省长度,但是,这样做会严重降低代码的可读性,所以,不提倡,我这里只列出Ozy缩短到最后的代码,具体过程可以参考他的书的P130--P135)
Input:每一行N个数字,表示对777赌博机的一系列操作
Output:输出经过几轮变换后,赌博机上的值
2
3 // 这里因为要开启memset函数
4
5 #include<stdlib.h>
6
7
8
9 // 这是短码的技法,对于某些编辑器是成立的
10
11 main()
12
13 {
14
15 // 每一行N个数字,但是N不超过10,要不然,赌博机会爆掉
16
17 char v[ 10];
18
19 // 输出的答案
20
21 int ans[ 10];
22
23 int i,len;
24
25 // 初始化答案
26
27 memset(ans, 0, sizeof(ans));
28
29 // 每次读入一行,并存储到v中
30
31 for(;gets(v);)
32
33 {
34
35 len=strlen(v);
36
37 for(i= 0;i<len;i++)
38
39 {
40
41 // ASC码和十进制不一样,所以每次需要模48进行转换
42
43 ans[i]+=v[i]% 48;
44
45 // 由于赌博机只有0--9这10个数字(皮卡丘等的符号可以替换为数字)故考虑到循环
46
47 ans[i]%= 10;
48
49 }
50
51 }
52
53 // 最后,输出结果,由于一共只有一行,故不考虑换行的情况
54
55 for(i= 0;i<len;i++)
56
57 printf( " %d ",ans[i]);
58
59 }
Ozy的独到技法,中间的演变过于繁杂,这里一笔带过:
(1)利用getchar()函数将v[]数组的作用抵消
(2)发挥mod计算的技巧,将ans[i]+=n%48写成ans[i]+=(n+2)
(3)利用指针进一步缩短代码
//这种压缩体在某些编译器上面是会报错的
2
3 main(n)
4
5 {
6
7 for(;~n ? n=getchar(p=n> 10 ? *p+=n+ 2,p+ 1:a): *p&&putchar(*p++% 10+ 48););
8
9 }