标签档案:编程

编程++:建立在以前的基础上

在学习编程时,最早的困难往往是生成有效代码的机制。这可能会让新手非常沮丧,因为编程语言翻译人员(编译器)在他们准备接受的东西上是坚定不移的,并将拒绝一切不符合他们要求的东西。但是,一旦掌握了这些语法基础知识,就可以创建以前从未有人编写过的令人兴奋的新程序。

程序员创建新程序的方法之一是注意别人过去写的东西。通过建立在别人已经写好的基础上,他们通常可以节省很多时间,从而将他们的创造性精力集中在他们自己特定程序中新颖的部分。作为一名教师,我很早就鼓励这种方法,例如,当我建议我的学生利用图书馆课程来存储数据集合时。虽然理解这些库类的工作方式当然很重要,但这并不意味着每次需要使用集合时都必须从头编写代码。关键是利用现有的东西,要么围绕它编写代码,要么调整它以适应您的需要。

最近,当我被要求向一个程序添加一些新功能时,我就应用了这个原则。过去20年里,我一直在断断续续地维护这个程序。这是一个用C语言编写的开源项目pgn-extract.它允许国际象棋玩家根据各种不同的标准搜索国际象棋游戏文件,如特定的玩家、开头、结尾等。该程序的一个用户(JS)问我是否有可能让它在游戏中寻找特定的棋盘位置。例如,寻找专家玩家在特定配置下如何玩出棘手的终局游戏的例子可能会很有趣。复杂的部分是JS不希望用户必须指定棋盘上每个棋子的确切位置。相反,他们只会对几件作品感兴趣,而其他的都不重要。

据我所知,还没有这样的东西存在,但这个任务让我想起了熟悉的计算机科学主题模式匹配.在这里,您需要寻找与模糊模式匹配的东西,而不是精确的东西,通常使用正则表达式符号。例如,使用模式"(cC)在*”匹配以“猫”或“猫”开头的单词,如“牛”和“捕手”。这种表示法在Unix命令的计算中很有名grep.虽然这种表示法通常用于匹配普通文本,但我认为它可能适用于匹配国际象棋棋盘——特别是如果棋盘可以用类似文本的形式表示的话。

我的出发点是一个很好的描述由Rob Pike编写的grep的实现(Brian Kernighan记录)。从文本上表示棋盘其实相当简单,国际象棋玩家经常这么做。例如P6r意思是:“白卒,六个空方格,然后一个黑车”。我修改了熟悉的grep符号,以更好地适应国际象棋上下文,以便能够区分黑白棋子,然后将其添加到我的程序中——当然,这承认了对Rob Pike的依赖!

令人高兴的是,最初的请求者JS对结果很满意,但随后他继续演示了我从未想到的新功能的一个很好的偶然使用。他给我发了一张前世界冠军米哈伊尔·塔尔(Mikhail Tal)盯着一个看不见的对手的照片。这张照片大家都知道了,但是Tal凶狠的眼神下的对手是谁呢?JS编码了在图片中可见的板的部分使用新的符号(*/*/*/*/???? b ? ? q / * / ? ? N ? ? P / R ? ?Q1BR1),让程序运行了米哈伊尔·塔尔玩过的所有游戏!结果就是1960年在莱比锡对阵尼古拉·帕德夫斯基的比赛。

编程不仅仅是关于编写正确代码的机制,它是关于采用和适应现有的想法来创建一些新的东西,有时是一些有趣的东西!