一年炉石传说的游戏体验

炉石传说这款游戏,最先是从玩星际争霸2的朋友那里知道的,那时候刚发布,大家都去申请了公测账号,当时也跟着去试了一把。当时的兴趣都在星际2上,所以玩了几把就忘掉了。直到去年去苏州玩,旅馆里无聊,又开始玩了这个游戏,重新发现了这个游戏的乐趣,就整整玩了一个暑假。到现在,玩了大约有十个月吧,昨天终于把这个账号卖掉了,算是给这段游戏经历画上了句号。

Hearthstone_Logo_CN

这是非常值得回忆的一段游戏时光。有段时间,每天起床都特别开心,因为能开新的游戏卡包了(这个游戏的日常任务能得40或60金币,100金币买一包卡)!一个卡包里面有5张卡至少有一张稀有,有几率开出史诗,传说(非常珍贵)。我现在几乎能记起来每一张传说卡的瞬间!一张传说能带来几天的好心情。正因为这个游戏的这种集卡机制,使得我对账号的感情比较深,毕竟都是自己一张一张开出来的。

Card Box_Cinematic

这应该算是一款相当成功的卡牌游戏了。游戏界面制作精美:UI全部设计在一个盒子里,这种风格贯穿始终;游戏采用“酒馆”的世界背景,每次官方消息,游戏指引等都已酒店老板自称,非常有意思。比如说,玩家数超过三千万,官方新闻说“我们需要更多的椅子了!”;对战界面也安排的极为精致,代入感很强。卡牌的获得方式算是一大创新吧,除了副本奖励的卡牌能够稳定获得,其余的卡牌都需要开扩展包来得到。而通过扩展包开到的卡牌,是完全随机的。

hotelboss

炉石传说最大的特点,就是卡牌的平衡性了。成也是它,败也是它。可以说,这是所有暴雪游戏的特点了。单说这款游戏中,平衡性就体现在,每一张卡牌都有独到的用途,虽然有些逗比卡,但是每一张都是不能被完全替代的。Amaz就说过,每一张都是好卡。我相信像米尔豪斯这种卡,在将来都会有不可替代的用途。在天梯就体现在,没有一套卡是百分之百无敌的,一套卡的兴起,必然会引起另一套克制的卡组流行。肯定会有人用T7猎,机械法,动物园,这种横行天梯的卡组来反驳我。只能说,概率而已。这种卡组对起手要求低,“天糊”几率大,就像在星际2里面,低分段神族4bg胜率高,一样的。并不影响游戏的平衡性。

Every Card is good card.

——Amaz

其中说的败,就是这个游戏太平衡了。如果你的卡比对手多很多,那么你的组合肯定就多得多,胜率一定高一些。加上游戏只有1v1的对战模式,就决定了它注定是一个孤独的游戏。和好友对战的模式单一,趣味性比较低。而且好友对战不是天梯,你的朋友卡组质量如果不是和你一个等级的,那么好友对战基本没法打。在对战中遇到的网友,顶多以后有观战任务能去看一下别人打,基本上也很少有别的交流,因为好友对战没有奖励,认识之后交流也不多。别的游戏例如星际2,魔兽世界中,认识朋友之后交流比较多。

Screenshot_8_full

另外提一点,关于交流。游戏关闭与对手对话功能,只有添加好友之后才能对话。我想,禁止骂人所带来的游戏体验肯定远大于弱化社交。但是游戏依然提供了内置的“你好”,“抱歉”等语音,依然可以用这些嘲讽。我在美服也打过,自己的感觉就是:美服称赞,问好用的比较多,国服基本都是“抱歉”,或者在失误的时候“打得不错”,来嘲讽。总体的玩家素质,大陆就是比较低,这是事实。

说了这么多,我AFK的主要原因是缺钱。次要原因是玩腻了,开卡包带来的惊喜少了,一局一局的对战也渐渐没有了感觉,已经厌倦了这种游戏模式。不过,这是一个超级棒的游戏。

 

《以撒的结合:重生》网页版图鉴

这个月以撒登陆 PSN 啦!最近又拾起了这个游戏,却发现好多道具都忘记了。《以撒的结合:重生》这款游戏中,有四百多种道具,而且游戏里面,道具没有说明,只有图片。所以在拾起来道具之前,很难知道道具的作用。

b6159350522b811dc19cef604e4d8b1c

于是,图鉴就成为这个游戏重要的辅助工具。以前我们用的图鉴,都是从一个以撒的 wiki 上面截图下来的,要找一个道具的话,需要翻多页。我想,如果做成一个网页版的话,就方便多了,点击一个道具,直接出来信息。所有的道具呈现在一页里面,查找方便。网上没有这样的图鉴,我就想自己做一个。

我的想法是:

  1. 写个程序将道具的信息格式化成 xml 格式;
  2. 前端主要将所有的道具图片呈现出来;
  3. 用 jquery 设置监听,点击图片之后,显示出道具信息。

在实际写的时候,才遇到了各种各样的麻烦,这篇文章中,将这些问题简单总结一下,大家如果有兴趣,可以自己深入了解一下。

C++操作中文

整合道具信息这块,我是用 C++写的。处理 string 很需要经验,我花了一个好长时间学习对中文的操作。中文是用两个字节表示一个字符的,单独获取一个字节没有任何意义。或许,可以针对中文字符写一个库?

监听 jquery 添加的元素

使用 jquery 添加的元素,是无法使用$()来选择,进行监听函数绑定的。这个项目中,我用了   .delegate( selector, eventType, handler(eventObject) )  这个函数来代替。这个函数可以匹配的元素包括那些目前已经匹配到的元素,也包括那些今后可能匹配到的元素。但是,它已经被 .on() 代替了。(on函数字太多了,我没看= =)

背景图片的适应

css 中可以对背景图片的大小适用只有以下这种:

  • auto:背景图像的真实大小。
  • cover:将背景图像等比缩放到完全覆盖容器,背景图像有可能超出容器。
  • contain:将背景图像等比缩放到宽度或高度与容器的宽度或高度相等,背景图像始终被包含在容器内。

看起来,好像 css 中只适合对那种合适平铺的图片作为背景啊。我的处理方式是:直接加一个图片的 div,这个图片的 z-index 设置为-1,即在所有的元素的下面,然后这个图片的宽和高都可以拉伸了!(但是joyme说我这样做 background,显得一点都不专业 = =,但也想不出别的办法呀)

现在想起来的问题,就这么多。吐个槽吧,想想这么简单的东西,真正做的时候,却遇到了这么多麻烦!尤其是图片拉伸,来来回回尝试各种方法,花了四个多小时!前端也真是不简单啊。更糟糕的是,自己花了那么长时间,给室友看,用的360浏览器,一打开布局全完蛋。前端工程师都是勇士!

最近熬了两天夜了,今天一定好好睡一下。第一天,主要实现了基本功能,可以查询了。

psb

 

昨天花了一天时间————加!特!技!duang!变成了这样子:

psb-2

 

今天又补齐了道具,把 Demo 挂在 Github 上了。大家有好的建议或者报错可以给我留言~或者在 Github 上提交 issue 或者 pr。

Demo

以撒的结合:重生 中文 在线图鉴:http://laixintao.github.io/isaac/

项目地址:https://github.com/laixintao/ISAAC-Atlas-online

 

 

分清 C++的指针、引用和数组

C++ 里面的指针常常使初学者感到困惑,尤其是和引用,常量,数组等组合起来的时候,一个变量是数组,还是指针,指针是常量,还是所指对象是常量就显得更模棱两可了,例如下面这些代码:

如果你也有类似的困惑的话,希望在读完本文之后,会有一个清晰的概念。

热身

一个内存位置,保存一个值,内存位置也可以作为值,这就叫做指针。在事情变得复杂之前,我们可以确定两件事:一个变量保存的要么是地址,要么是值。现在,我们从最简单的概念开始:

  1. 指针保存的是地址,解引用得到对象的值;
  2. 引用类型是真实对象的“绑定”,可以当做这个对象的另一个名字来使用,对引用类型的操作,就是对真实对象的操作(引用必须初始化!)。取地址得到的是对象的地址;
  3. 解引用 * ,取地址 & 具有双重含义:在表达式中作用如1 2 粗体所示;在声明中,它们用来组成复合类型。注意:int *p = i;

举个栗子:

那么问题来了:改变的是指针指向的对象呢?还是对象的值呢?

法则一:改变的永远是等号左侧的对象。

比如,第2行,等号的左侧是定义,r 是 int 类型的引用,引用“绑定”了 i;第4行,等号左侧是指针,那么改变的就是 指针的值,也就是所指的对象;第7行,等号左边是指针解引用,那么修改的就是指针指向的对象,即 i;最后一行,等号左侧是引用类型取地址,是一个地址,额,对一个地址赋值,很显然这一行是错误的……

注意:虽然上文说了某些符号在定义式中有另一种含义,但这还是常常使人混淆——*p不应该是变量的值吗? 我有个小技巧,将在定义式中的*理解成为类型的一部分,将它看成和 int 的组合就好了,像这样:int * p = i;

复合类型

上面的概念是不是很简单?接下来要将指针和引用相互组合,产生更复杂的类型了。

指向指针的指针

首先,指针先指向了一个对象。这个对象保存的是个地址,对这个地址解引用,可以得到令一个对象的值。

在内存中,是这个样子的:

pointer

指向指针的引用

由于引用不是真实的对象,所以不存在“指向引用的指针”,但却可以有“指向指针的引用。”这时,上文的规则同样适用,即作为指针的别名使用。

现在就有点复杂了,r 到底是指针还是引用呢?法则二:从右向左读。例如第三行的 r ,左边是 &,所以它是个引用类型,再向右,* 表示引用的这个类型是一个指针,再向右 int 表示,这个指针的类型是int,综合,r就表示“一个指向 int 型的指针的引用。

const限定符和constexpr

当 const 涉及指针的时候,可以分为两种情况:

  1. 顶层const:指针本身是个常量,不能改变所指的对象。
  2. 底层const:指针指向的对象是一个常量,不能改变或者通过指针改变这个对象的值。

不要慌,这里法则二依然适用:从右向左。对于 p1,右侧是 const ,表示 p1 是一个常量,向右,p1 是常量指针,再右,常量指针 p1 指向了 int 型。

小试牛刀:解释一下p2和p3吧!

constexpr

这是 C++11 的新规定,允许将变量声明为 constexpr 类型以便由编译器来验证变量的值是否是一个常量表达式。

“变量的值”,就是左值,说白了就是基本类型是不是一个常量。比如 a 基本类型是 int ,constexpr 就指定 int 型为常量。 p 是一个指针,constexpr 指定指针 p 是一个常量。由此,我们可以得到法则三:constexpr 声明中如果有指针,那么constexpr 只对指针有效,而与对象无关。

类型别名

类型别名顾名思义,就是将复杂的变量名起一个好听好记的名字。可以参考1-3行,这是类型别名的常用的例子(其实最常用的时候,是给长长的结构体取“外号”)。

看完了前3行之后,你可能觉得“就是个别名,那我理解的时候,替换成原来的名字就好了!”所以你就会像 p_c_str 那样,去解释 c_p_str :按照我们的从“右向左法则”,它首先是一个指针,然后指向 char 型,这个 char 型是 const 的,所以这是一个“指向char 型常量的指针”。

这是完全错误的!是我们的“从右向左”法则出错了吗?不是的,要相信,从右向左在任何时候都是对的,如果它错了,那么一定是你错了——你错就错在,将 typedef 指定的别名拆开理解了。正确的理解很简单,对于 typedef,你要从心底认为这是同一个类型的别名,pstring 是“指向 char 型的指针”,永远都是。对于 c_p_str,从右向左的时候,第一步是“它是一个指向 char 型的指针”,而不是“它是一个指针”。第二步理所应当的是“这个指针的类型是 const 的”,综合,c_p_str 就是“指向 char 类型的常量指针”。

法则四:typedef 定义的类型别名不要替换成原来的名字去理解!

小试牛刀,解释一下 ps 吧!答案是:“ps 是一个指针,它指向了一个对象,这个对象是一个指向 char 的常量指针。”

decltype 类型指示符

这也是 C++11 的新标准,编译器分析表达式并返回其类型,要注意的是,不会计算表达式的值。这点非常重要,因为上文说过,引用从来都是作为所指对象的同义词出现,但只有在deltype 的时候是个例外。原因如下:

第三行因为编译器阶段并不会对 *p 求值,所以直接返回一个引用类型。这个地方,引用就和所绑定的对象有区别了。(事实上,第三行是错误的,因为定义引用的时候没有初始化。)

法则五:在(且仅在)deltype 处,引用不是对象的同义词!

数组

引用可以绑定数组,指针可以指向一个数组,数组可以存放指针,但是唯独不存在引用的数组!参考下面的例子:

很显然,这里不能再用从右向左了,不然的话,”[ ]”永远也读不到了。对于负责的数组声明,要由(内)向外阅读——法则六。

例如 p_array ,首先,它是一个指针(内指的是括号内),然后类型修饰符从右向左再依次绑定:指向的是一个数组,这个数组是int型。 再复杂的数组,也可以以此类推。

Summary

  1. 改变的永远是等号左侧的对象。
  2. 从右向左读(类型修饰符依次绑定)。
  3. constexpr 声明中如果有指针,那么constexpr 只对指针有效,而与对象无关。
  4. typedef 定义的类型别名不要替换成原来的名字去理解!
  5. 在(且仅在)deltype 处,引用不是对象的同义词!
  6. 对于复杂的数组声明,要先从内向外读,再按照从右向左。

是不是 So easy 呢?你会读了吗?

 

笑话三则

昨天在隔壁宿舍讨论算法的时候,一个室友大喊了一声:“卧槽,老子就是更新了个 QQ 而已,这 QQ 浏览器和 QQ 音乐是哪里来的!”

说起来,我昨天从一个网站上下载了一些扑克牌的素材图片,过了一会儿……打字的时候,输入法已经默默地变成了百度输入法……

不过还是另一位朋友更惨,他说:“有次回宿舍,手机顺手插在电脑的 USB 上就上厕所去了,回来的时候,手机已经装好了360……。”

形成鲜明对比的是,最近收到一封广告邮件,于是发回去问他们是怎么知道我地址的。竟然真的收到了礼貌的回复:

emailreplay

 

自由比皇帝更伟大——《悲惨世界》笔记

在第三部《马吕斯》第四卷 ABC 朋友会中的第五章 “开阔视野”中,马吕斯和他在 ABC 的朋友们有一段精彩的辩论。ABC 的青年象征了年青一代,思想进步,热爱自由,热血,激进。读这段的时候,我和他们产生了强烈共鸣。

即使没读过《悲惨世界》,也能从中感受到这些青年人思想碰撞的火花,这段对话发生的时候,马吕斯刚加入 ABC 朋友会。在此之前,追随拿破仑的生父去世,马吕斯知道了父亲的事迹,由此产生了对拿破仑皇帝狂热的崇拜,和对共和国复辟的坚定信仰。因为这个政治观点和外公不和,大叫着“达到波旁王朝,打倒肥猪路易十八”离家出走,加入了 ABC 朋友会。 这一章,摘抄如下:

五 视野的扩展

青年们的相互接触有那么一种可喜的地方,那就是人们在其中无法预见火星,也无法预测闪电。过一会儿将会爆发什么?谁也不知道。温婉的交谈常引起一阵狂笑。人在戏谑时又常突然转入严肃的话题。偶然一个字能使人冲动。每个人都被激情所主宰。一句玩笑话已够打开一个意外的场面。这是一种山回路转、景物瞬息万变的郊游。偶然是这种交谈的幕后操纵者。

那天,格朗泰尔、巴阿雷、勃鲁维尔、博须埃、公白飞和古费拉克一伙谈得起劲,你一言,我一语,混战正酣,不料从唇枪舌剑中突然出现了一种奇怪的严肃思想,穿过喧杂的语声。

一句话怎样会在言谈中忽然出现的?它又怎么会突然吸引住听者的注意力?我们刚才说过,这是谁也不知道的。当时,在喧嚷哄闹声中,博须埃忽然对着公白飞随便说出了这个日期:

“一八一五年六月十八日:滑铁卢。”

马吕斯正对着一杯水,一手托着腮帮,支在一张桌子边上坐着,听到”滑铁卢”这三个字他的手腕便离开了下巴,开始注视在座的人们。

“上帝知道,”古费拉克喊着说(在当时,”天晓得”已经不大有人说了),”十八这个数字是个奇怪的数字,给我的印象非常深。这是决定波拿巴命运的数字。你把路易放在它的前面,雾月放在它的后面,这人的整个命运便全显现在你面前了。这里又还有这么一个耐人寻味的特点,那就是开场是被结局紧跟着的。”

安灼拉一直没有说过一句话,这时他才开口,对着古费拉克说了这么一句:

“你是要说罪行被惩罚紧跟着吧。”

马吕斯在突然听见人家提到”滑铁卢”时,他已很紧张了,现在又听人说出”罪行”这种字眼,那就更超出他所能接受的限度了。

他站起来,从容走向那张挂在墙上的法兰西地图,地图下端,原有一个隔开的方格,方格里有个岛,他把手指按在那方格上,说道:

“科西嘉。一个使法兰西变得相当伟大的小岛。”

这是一股冰冷的风。大家全不说话了。大家都觉得要发生什么事了。

巴阿雷正在摆出他常爱用的那种正襟危坐的姿势来和博须埃对驳,他也为了要听下文而放弃了那种姿态。

安灼拉的蓝眼睛并没有望着谁,仿佛只望着空间,这时他眼睛虽不望马吕斯,嘴里却回答说:

“法兰西并不需要科西嘉来使它自己伟大。法兰西之所以伟大,只因为它是法兰西。’因为我的名字叫狮子。'”

ABC

马吕斯绝没有退却的意思,他转向安灼拉,他那出自肺腑的激越的声音爆发出来了:

“上帝惩罚我要是我有贬低法兰西的意思,但是把它和拿破仑结合在一起,这并不贬低它一丁点。真怪,我们来谈谈吧。我在你们中是个新来的,但是老实说,你们确使我感到奇怪。我们是在什么地方?我们是谁?你们是谁?我是谁?让我们就皇帝这个问题来谈谈各自的见解吧。我常听见你们说布宛纳巴,象那些保王党人一样,强调那个’乌’音。老实告诉你们,我那外祖父念得还更好听些:他说布宛纳巴退。我总以为你们都是青年。你们的热情究竟寄托在什么地方?你们的热情究竟要用来作什么?你们佩服的是谁,如果你们不佩服皇上?你们还要求什么?如果你们不要这么一个伟大的人物,你们要的又是些什么样伟大的人物?他是一个全才。他是一个完人。他的脑子包含着人类种种才智的三乘。他象查士丁尼那样制定法典,象恺撒那样独理万机,他的谈吐兼有帕斯加尔的闪电和塔西佗的雷霆,他创造历史,也写历史,他的战报是诗篇,他把牛顿的数字和穆罕默德的妙喻糅合在一起,他在东方留下了象金字塔那样高大的训谕;他在提尔西特把朝仪教给各国帝王,他在科学院里和拉普拉斯争鸣,他在国务会议上和梅尔兰辩论,他经心整饬纪律,悉力排难解纷,他象检察官一样了解法律,象天文学家一样了解天文;象克伦威尔吹灭两支蜡烛中的一支那样,他也到大庙①去为一粒窗帘珠子讨价还价;他见到一切,他知道一切,这并不妨碍他伏在他小儿子的摇篮上笑得象个天真烂漫的人;突然,惊骇中的欧洲屏息细听,大军源源开拔了,炮队纷纷滚动了,长江大河上建起了浮桥,狂风中驰聘着漫山遍野的骑兵,叫喊声,号角声,所有的宝座全震动了,所有的王国的国境线全在地图上摇晃起来了,人们听到一把超人的宝剑的出鞘声,人们看见他屹立在天边,手里烈焰飞腾,眼里光芒四射,霹雳一声,展开了他的两翼,大军和老羽林军,威猛天神也不过如此!”

大家全不言语,安灼拉低着脑袋。寂静总多少有那么点默许或哑口无言的味儿。马吕斯,几乎没有喘气,以更加激动的心情继续说:

“我的朋友们,应该公正些!帝国有这么一个皇帝,这是一个民族多么辉煌的命运啊,而这个民族又正是法兰西,并且能把自己的天才附丽于这个人的天才!到一国便统治一国,打一仗便胜一仗,以别国的首都为兵站,封自己的士卒为国王,连连宣告王朝的灭亡,以冲锋的步伐改变欧洲的面貌,你一发威,人们便感到你的手已握住了上帝的宝剑的柄;追随汉尼拔、恺撒和查理大帝于一人;作一个能使每天的曙光为你带来响亮的前线捷报的人的人民;以残废军人院的炮声为闹钟,把一些彪炳千古的神奇的词抛上光明的天际,马伦哥、阿尔科拉、奥斯特里茨、耶拿、瓦格拉姆!随时把一些胜利的星斗罗列在几个世纪的天顶,使罗马帝国因法兰西帝国而不能专美于前,建大国,孕育大军,象一座高山向四方分遣它的雄鹰那样,使他的百万雄师飞遍整个大地,征服,控制,镇压,在欧洲成为一种因丰功伟绩而金光灿烂的民族,在历史中吹出天人的奏凯乐,两次征服世界,凭武功,又凭耀眼的光芒,这真卓绝,还能有什么比这更伟大的呢?”

“自由。”公白飞说。

这一下,马吕斯也把头低下去了。这个简单冰冷的词儿象把钢刀似的插进他那激昂慷慨的倾诉里,登时使他冷了半截。当他抬起眼睛时,公白飞已不在那里了。他也许因为能对那谀词泼上一瓢冷水而心满意足,便悄悄地走了,大家也全跟着他一道走了,只留下安灼拉一个人。那厅堂变成空的。安灼拉独自待在马吕斯旁边,闷闷地望着他。马吕斯这时已稍稍理了一下自己的思绪,但仍没有认输的意思,他心里还剩下一股未尽的热流在沸腾着,正待慢条斯理地向安灼拉展开争论,忽又听到有人在一面下楼梯一面歌唱,那正是公白飞的声音,他唱的是:

恺撒如给我

光荣与战争,

而我应抛弃

爱情与母亲,

我将对伟大的恺撒说:

收回你那指挥杖和战车,

我更爱我的母亲,咿呀嗨!

我更爱我的母亲!

公白飞的既柔婉又粗放的歌声给了那叠句一种雄伟的气势。马吕斯若有所思,呆望着天花板,几乎是机械地跟着唱:

“我的母亲!”

这时,他觉得安灼拉的手在他的肩头上。

“公民,”安灼拉对他说,”我的母亲是共和国。”