1.5 第五步:判断玩家所选答案是否正确

为了标识每道题的正确答案,我们可以给正确答案所对应的单选按钮加上一个值为"correct"的class属性,不过这似乎太简单了:从开发者的角度来看,实现起来太过容易,而从玩家的角度来看,又很容易发现正确答案。网页源文件里的全部代码,包括注释在内,都能为访问者所见,因此,即便其不知道正确答案,但只要查看源代码,寻找标注为"correct"的那个单选按钮,也就能发现与之对应的正确答案了。于是,笔者决定实现一个“弱哈希函数”(weak hashing function)  hashing function 亦称hash function,中文也叫“散列函数”、“杂凑函数”。——译者注 ,用它来判断玩家所选答案是否正确,这样的话,那些懂得编程的玩家就不那么容易偷看答案了,而对于那些不会编程的玩家来说,则几乎不可能投机取巧。

所谓哈希函数,就是能根据某个输入值而算出另外一个输出值的函数。其强弱程度取决于能否轻易根据“哈希之后的值”(hashed value)反向推出哈希之前的原始值。如果很容易就能推出来,则是弱哈希函数,否则就是强哈希函数。

在实现此函数之前,先创建一种样式,用以表示玩家答对全部问题时的网页显示风格。将程序清单1.12中的粗体代码加入main.css。

程序清单1.12 向main.css中加入表示“获胜”状态的样式

此样式表明,如果元素的class属性值是correct,那么就将其背景设为蓝色,而将其中的文本设为白色。也许在还未上幼儿园的时候,大家就已经知道“白”这种颜色了,但是你很少会听人提到#24399f这种颜色,即便读研究生课程时,也未必会碰到它。这是RGB颜色(RGB是Red Green Blue的首字母缩写)。前两个数字表示红色值,中间两个表示绿色值,最后两个表示蓝色值。

有个问题要先说一下。颜色值最后一位似乎是“f”。这好像不是个数字吧?在十进制下,这确实不是个有效数位。如果红、绿、蓝三个颜色分量都采用十进制,那么两位数字最多只能表示100种颜色(十位可以取0~9,有10种不同的取值,个位也可以取0~9,也有10种不同的取值,所以一共有10×10种取值)。有人觉得100种太少了,于是决定采用十六进制,这样的话,RGB值的每个分量就有256(16×16)种取值了。有些颜色可以直接用英文词来表示,不过,白色(white)也可以写成#ffffff,而黑色(black)也可以写成#000000。顺便说一下,有人觉得用6位数来表示颜色太麻烦了,于是采用仅含3个数位的十六进制值来表示颜色(每个数位分别代表红、绿、蓝分量),如果写成这种方式,那么黑色就是#000,白色就是#fff。

修改完CSS后,还要在index.html文件里写一点东西。你得用程序清单1.13中的粗体代码,替换掉原来网页里的body起始标签。

程序清单1.13 在index.html中为body元素添加onclick事件处理程序

现在的<body>标签和原来不同了,它还带有名为onclick的属性,而属性值是一个字符串,字符串左右两端有双引号,而引号里边是一行JavaScript代码。如果不明白字符串是什么,请参阅附录A。该字符串描述了一个onclick事件处理程序,也就是说,只要用户在页面中的任何元素上点击鼠标,那么就执行checkAnswer函数。注意,调用函数时要在函数名后面加上一对括号。如果不加括号,那么就表示只引用此函数,而不调用它。

接下来是本章最后一段范例代码了,大家可以想一想:在执行完程序清单1.14中的这个函数后,会发生什么。粗体代码需要添加至game.js文件顶部,可以把它放在用于判断jQuery库是否正确加载的那个if语句之后,并放在显示第一道题所用的那个语句之前。

程序清单1.14 判断玩家所选答案是否正确

这段代码中的粗体部分定义了两个函数。第一个函数是checkAnswer,它先设置好一个空字符串,以便稍后向其中添加内容。接下来,把玩家所选的每个单选按钮所对应的value值依次追加到这个answerString字符串尾部。待循环执行完毕后,调用第二个函数,也就是checkIfCorrect,判断刚才的字符串是否和那一长串数字相等,以此来判定玩家是否已经答对全部问题。那么,为何要与这个数字相比较呢?

刚才在讲CSS颜色的时候说过,十六进制值可以使用0~f这16个字符作为其数位。而每个答案旁边的单选按钮,其value属性值在a~d之间,这4个值也是有效的十六进制数位。(可以把a~d这四个十六进制数位理解成十进制的10~13。)所以,只要把这些值拼成一串,并和表示正确答案的那个十六进制字符串相比较就可以了,而代码中出现的那一串数字,正是这个十六进制字符串的十进制形式。

若两者相符,则向body元素中添加值为“correct”的class属性,这一操作会使网页背景变蓝,并使其中的文字变白。然后,修改h1标签的文本,用“You Win!”替换掉原来的“Quiz”。最后,把原来隐藏的那个canvas元素重新展示出来,以便阻隔鼠标操作。其实还有另外一种做法,比这里所用的办法更为常见,那就是通过jQuery来禁用单选按钮控件,不过笔者认为本例所采用的办法更有意思一些,因为我们巧妙地利用了这个本来与问答游戏毫无关系的canvas元素。有了这个canvas元素之后,可以通过atom.js来构建一款游戏,不过在本章这个问答游戏里,我们只是用它来屏蔽用户的鼠标点击而已。

完成所有步骤之后,保存相关代码文件,并用浏览器打开index.html,如果所有问题都答对了,那么就会出现图1.4这样的画面。

图1.4 答对所有问题后,游戏进入“获胜”状态

[1] hashing function 亦称hash function,中文也叫“散列函数”、“杂凑函数”。——译者注