追求神乎其技的程序设计之道(一)

作者: Vgod    原文链接: 见这里

(作者简介:Vgod目前是MIT在读博士,他刚刚发布了自己的图形化编程研究项目Sikuli,引起了业界广泛的关注,更多详情,请移步Sikuli的项目主页 ,那里有精彩的演示视频。Vgod正在与博文视点合作,准备出版他的第一本书。)

最近有读者问到我学写程序的方法和经验,让我一下掉入时光隧道回想起当初用VB写出自己第一个游戏时的成就感,但当初没料到的是我真的就此迷上了电脑和写 程序的快感,不知不觉也过了10年的光阴…。在这篇文章中,我想写出我对程序设计的看法和我一路学习上来的历程和经验。写程序是一条无止境的道路,不只是 科学和工程,更是一种艺术。而我还在追求“神乎其技”的半路上,虽然还有很多要学的,但我也希望能让初学者更容易看清楚这条路是什么样子,避免陷入盲目追 求新技术的死巷中。

一切的开始

如果是从DOS时代开始玩电脑的玩家,应该都知道当初DOS有两个内建的QBASIC小游戏:贪食蛇和猩猩丢香蕉。这两个小游戏是许多人儿时共同的回忆, 我还记得我小学时曾有几堂电脑课,当时老师在台上叽哩瓜啦的不知道在教什么,而台下每台电脑都是贪食蛇或丢香蕉的画面(老师对不起,其实我就是带头做乱的 罪魁祸首…)。

微软把这两个QBASIC游戏附在DOS内对我产生了莫大的影响,那是我第一次发现到原来QBASIC和不只是像PE2能打打字而已,QBASIC竟然能 把一堆看起来像咒语的文字变成游戏!幸运的是我家刚好有本第三波的QBASIC入门书,没事我就自己拿起来翻着看,虽然当时太小,即使把整本都看完了还是 搞不懂贪食蛇是怎么写出来的,但也误打误撞知道了原来这就是程序设计,原来我能直接把贪食蛇文件内的一个数字改掉就能有几百条命可以用,原来学写程序就能 做出电脑游戏…。对小孩子而言,知道这些事就像告诉他魔术师袖子里的秘密一样,我一天到晚兴奋地要老爸带我去书店看电脑书,彷彿真的可以搞懂电脑萤幕背后 的一切魔法一样,我也梦想着有一天能写出自己的游戏。但当时我没想到的是,我还真的花了十几年的时间在探索电脑的魔法…。

MUD与黑白棋

升上初中后,家里装了一台28.8kbps的modem,当时的internet还没完全成形,在没有Google的时代internet是没什么价值 的。当时的modem最常被我拿来上一些的BBS,那时候BBS站还不少,最棒的是还能从站上抓到很多软件和各式各样的教学文章,像是如何用汇编语言写电 脑病毒,如何破解大富翁2之类的文章。这些文章对当时的我就像武林秘籍一样,虽然没办法完全看懂,但我也是从中得到很多零碎的概念,像是16进位的换算、 汇编语言、中断向量、常驻内存程序….。

在初二时,我还不小心迷上当时一个超热门的MUD——万王之王(KK),每天放学回家都急着连上线,让家里电话整晚都占线,玩到每个月电话费都是上千元,搞得我妈数次警告要把modem收起来再也不让我上网了。(还好她没真的这么做,不然我现在就没办法写这篇文章了。)

MUD是现在MMORPG的纯文字版,整个虚拟世界都用文字描述,并且只要用telnet就可以连上去玩了。但内行的玩家都知道,玩MUD应该要用 zMud或是UNIX下的tintin++,因为这两个软件可以设定所谓的trigger,侦测到某些事件的发生,就能自动采取事先指定好的动作。因为一 切的信息都是由文字呈现,所以侦测事件非常简单,只要看看有没有特定字符串出现就可以了;而要做特定的动作也很简单,就是送出文字指令而已。(眼尖的人一 定会发现,这其实就是现在MMORPG外挂的最原始形式。)严格说起来,zMud是我首次写“应用程序”的平台,我学会通过trigger在MUD的世界 中写自动化的机器人,自动在迷宫中游走,自动换装备打怪练功..。这时的我突然体会到,会写程序真是太棒了,我在MUD中简直跟神一样。其实当时我也不过 只会用最基本的变量、if、循环而已,但通过在虚拟世界中写机器人的练习,让我的逻辑思考概念有飞快的进步,也给我了非常强烈的动力想好好学一个正统的程 序语言。

升上初三后,很幸运的通过推荐甄试提早上了台中一中,升学压力解除后,老师和父母就完全不管我要干麻了。这时我终于有了一段完整的时间可以好好的再把 BASIC重新学过,无奈的是在我初三时QBASIC已经快灭绝了,取而代之的是Windows上的Visual Basic,我只好硬着头皮买本新书来从头学起VB。当时我看的是王国荣的VB 5入门书,整本书有六七百页吧,比我国三所有课本叠起来都还厚,现在想想小时候真的有点不知天高地厚竟然相信自己能看完这么厚的砖头书。那时候我每天上课 就带着这本砖头去学校,这样看了几个礼拜下来,没想到我这时突然都看得懂了,很多原本不知道有什么用途的概念突然都相互连结起来了。(多亏了在MUD里的 训练!)就这样,某天突然有种打通任督二脉的感觉,我发现我全搞懂了,循环、阵列、Windows GUI控件、去背贴图…,我突然想通要怎么用程序语言写出游戏了。

从那之后,每天回家就是打开VB写程序,我想写个黑白棋来检验自己的想法,我把自己知道的所有概念都放进去,有GUI组件、有贴图、有动画、有音效.., 这是我第一个完整的程序,从头到尾每一行都是自己写出来的。(以现在的眼光来说只能说是一个期末project规模的小程序,但对当时的我可是意义非凡)

这个黑白棋让我印象最深的其实是debug的痛苦经验。我花了一个礼拜把程序的核心部分完成,但在吃子的时候却跑出一个不明的bug会打乱整个盘面。为了 找这个bug,我又花了一个礼拜,每天从早到晚都在想哪里写错了,后来慢慢trace了好久,才发现竟然只是一个变量忘了归零!!!

这种bug很常见,不过只是programmer最容易犯的无心之过之一,但这件事对我的影响非常大,它让我花了很长时间在想以后要怎么避免犯同样的错。 我后来才知道一个普通的programmer和厉害的programmer从这里就会分出高下:普通programmer犯了这种错会觉得很平常,并提醒 自己下次别再这么笨了,但实际上不久后一定又会再犯同样的错;厉害的programmer会反省自己写程序的方法,并改变原有的方法或习惯来避免以后再度 产生同样的bug。

古老的程序设计教材(尤其是C语言),都说要把变量声明在函式的一开头,并且因为变量声明完还得经过初始化,所以很多人习惯是在函式开头声明并初始化所有变量。这不是错的,可是,这其实就是会导致bug的元凶。
因为变量在开头就被初始化,这样在真正要用到它的时候就能直接拿来用,但是如果这个变量需要被归零(也就是重新初始化)并在循环中重复利用,就很容易会忘记要再多做这一步。(在多层循环中更容易发生)

我为这个bug苦恼了几天,后来才意识到这是coding style的问题,只要改变声明变量的习惯,就能避免犯这种错误。如果一开始就在循环内声明并给定变量的初始值,而不是在函式开头声明,就不会有这种 bug跑出来了。有了这个经验后,我归纳出一个原则:“永远在变量需要被用到的最内层区块才声明并初始化该变量。”这种原则很重要,我日后一直放在心里, 它也帮助我避免掉未来再犯同样错误的可能。(事实上,我后来再写了十年的程序,再也没有比这更痛苦更长久的debug经验了…)

(待续)

本文遵守Creative Commons 协议,转载请注明原作者,并提供原文链接。
posted @ 2010-01-29 14:23  博文视点  阅读(984)  评论(0编辑  收藏  举报