news 2026/9/23 20:00:02

Basic Computer Games 项目解析:用 MiniScript 与 Mini Micro 运行经典独立钻石棋 High IQ

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Basic Computer Games 项目解析:用 MiniScript 与 Mini Micro 运行经典独立钻石棋 High IQ
  • 示例工程

【免费下载链接】basic-computer-games

An updated version of the classic "Basic Computer Games" book, with well-written examples in a variety of common MEMORY SAFE, SCRIPTING programming languages. See https://coding-horror.github.io/basic-computer-games/

项目地址:https://gitcode.com/gh_mirrors/ba/basic-computer-games
点击查看免费下载

High IQ(独立钻石棋)是 1978 年经典《Basic Computer Games》合集中的一局逻辑游戏,本仓库在00_Alternate_Languages/48_High_IQ/MiniScript/目录下提供了完整的 MiniScript 移植版。本文将围绕 MiniScript 运行说明 展开,完整讲解两种官方推荐的运行方式(命令行 MiniScript 与 Mini Micro 图形环境),并深入到 highiq.ms 的源码,剖析棋盘建模、走子合法性判定、终局判定等核心实现,最后对照原始 BASIC 版本 说明移植思路。读完本文,你既能立刻跑起这局游戏,也能理解其数据结构与算法设计,可据此复刻到任意语言。

游戏背景:High IQ 是什么

根据 48_High_IQ/README.md 的项目说明,High IQ 是一款经典欧洲单人跳棋(European solitaire)的计算机化版本:游戏使用一个十字形(cross-shaped)棋盘,除中心孔外每个孔都插有钉子(peg),共 32 枚。玩家通过"跳子"将钉子跳入空孔,被跳过的钉子被移除,目标是移除全部 32 枚钉子——若无法全部移除,则尽可能多移。游戏存在多种可获胜的策略,且每种策略在棋盘上可沿八个方向施展。

该游戏由 Charles Lund 在荷兰海牙的美国学校(The American School in The Hague)期间编写,最初收录于 1978 年版《Basic Computer Games》。其 BASIC 源码由 Vintage Basic 归档收录,本仓库在 48_High_IQ/highiq.bas 保留了原始实现。

在仓库结构上,00_Alternate_Languages/目录(见 00_Alternate_Languages/README.md)存放的是不属于约定 10 种主语言、但被社区欢迎的"备选语言"移植版,MiniScript 移植即归此类,主要供教育学习用途。该目录下每个游戏子目录都遵循"游戏名/MiniScript/README.md + *.ms"的组织方式,High IQ 对应 MiniScript 目录,其中包含两个文件:

  • README.md:移植说明与运行指南(即本文主体文档);
  • highiq.ms:完整可运行的 MiniScript 源码(约 160 行)。

运行方式一:命令行 MiniScript

关联文档给出的第一种运行方式是使用 MiniScript 的命令行解释器(Command-Line MiniScript)。完整步骤如下:

  1. 前往 MiniScript 官方命令行版本下载页,获取适配你操作系统的安装包;
  2. 按官方说明完成安装,确保miniscript命令可用;
  3. 在终端中进入本仓库的00_Alternate_Languages/48_High_IQ/MiniScript/目录(或用绝对路径指定文件),执行:
miniscript highiq.ms

程序随即启动:先打印标题与带钉子编号的初始棋盘图,提示玩家记下编号后按回车开始,之后进入"输入走子编号 → 显示更新棋盘 → 判定终局"的循环。

运行方式二:Mini Micro 图形环境

第二种方式是在 Mini Micro(MiniScript 官方内置的虚拟计算机/图形环境)中运行,适合希望在图形化文件系统与终端中操作的用户:

  1. 下载并启动 Mini Micro;
  2. 点击顶部磁盘槽位(top disk slot),选择"Mount Folder..."(挂载文件夹);
  3. 在弹出的对话框中选择包含highiq.msREADME.md的 MiniScript 文件夹(即本仓库的00_Alternate_Languages/48_High_IQ/MiniScript/),完成挂载;
  4. 在 Mini Micro 的命令行提示符下依次输入:
load "highiq" run

load会从挂载的文件夹载入highiq.ms程序,run则启动它。Mini Micro 方式的好处是不需要单独安装命令行解释器,并且加载后可以方便地查看、编辑脚本源码。

源码剖析一:十字棋盘的建模

理解了两种运行方式后,再深入 highiq.ms 看棋盘是如何在内存中表达的。

setupBoard函数(highiq.ms)构建了一个 9×9 的二维数组t作为棋盘,使用三种数值标记格子状态:

  • 5:该格有钉子(pin);
  • 0:该格是空孔(hole);
  • -5:该格无效(棋盘外的区域,不参与游戏)。
globals.t = [[-5]*10] pinNums = [13,14,15,22,23,24,29,30,31,32,33,34,35,38,39,40,41, 42,43,44,47,48,49,50,51,52,53,58,59,60,67,68,69] for row in range(1,9) t.push [-5]*10 for col in range(1,9) if row < 2 or row > 8 or col < 2 or col > 8 or ((row < 4 or row > 6) and (col < 4 or col > 6)) then t[row][col] = -5 else t[row][col] = 5 pinToPos[pinNums.pull] = [row,col] end if end for end for t[5][5] = 0

坐标系中(row < 2 or row > 8 or col < 2 or col > 8)抠出 7×7 的方形区域,而((row < 4 or row > 6) and (col < 4 or col > 6))再抠掉四角,恰好形成十字形状;随后t[5][5] = 0将正中心置为空孔——这正是"32 枚钉子 + 中心空位"的经典开局。

同时,函数用globals.pinToPos字典建立了"钉子编号 → [行, 列]"的映射,33 个有效位置按上、中、下三段的顺序依次分配编号 13~69(编号模式与原始 BASIC 版完全一致,见下节)。这套"二维数组 + 编号映射"的双重结构,是后续所有走子与判定逻辑的基础。

源码剖析二:走子合法性判定

游戏规则要求"跳过相邻钉子跳入空孔",isValidJump(highiq.ms)用非常直观的方式实现了该判定:

isValidJump = function(pinFrom, pinTo) if not pinToPos.hasIndex(pinFrom) then return false posFrom = pinToPos[pinFrom] if not isHole(pinTo) then return false posTo = pinToPos[pinTo] // check that the Manhattan distance is exactly 2 dist = abs(posFrom[0] - posTo[0]) + abs(posFrom[1] - posTo[1]) if dist != 2 then return false // and check that the intervening position contains a pin if t[(posFrom[0]+posTo[0])/2][(posFrom[1]+posTo[1])/2] != 5 then return false return true end function

判定分三步:起点必须是真实存在的钉子(isPin,见 highiq.ms);终点必须是空孔(isHole,见 highiq.ms);起终点的曼哈顿距离必须恰好为 2(即水平或垂直相隔一格),且二者正中间的那格必须包含一枚钉子。三步全过才算合法跳子。

getMove(highiq.ms)把该判定封装进一个while true输入循环:先询问 "Move which piece?",若起点是钉子再询问 "To where?",只有同时通过isHoleisValidJump检查才跳出循环,否则打印Illegal move, try again...并重新输入——这保证了非法输入绝不会污染棋盘状态。

执行走子则落在doOneMove(highiq.ms):将起点格置 0(钉子离开)、终点格置 5(钉子落入)、中间格置 0(被跳过的钉子移除),三次数组写入完成一次完整的跳子。

源码剖析三:终局判定与计分

checkGameOver(highiq.ms)遍历棋盘上每一枚钉子,检查其上下左右两格远处([row-2, row+2][col-2, col+2])是否存在合法跳点;只要找到任意一个合法跳子就立即返回false(游戏未结束),全部遍历完仍无合法跳子才返回true

主循环(highiq.ms)则串联起整局流程:

while true setupBoard printBoard while true doOneMove print printBoard if checkGameOver then break end while print; print "The game is over." pinsLeft = 0 ... print "You had " + pinsLeft + " pieces remaining." if pinsLeft == 1 then print "Bravo! You made a perfect score!" print "Save this paper as a record of your accomplishment!" end if yn = input("Play again (yes or no)? ").lower if yn and yn[0] == "n" then break end while print; print "So long for now."; print

终局后程序统计剩余钉子数(遍历数组计数5),若恰好剩 1 枚则打印满分祝贺语;随后询问 "Play again (yes or no)?",输入以n开头(大小写不敏感,.lower统一转小写)即退出,否则重置棋盘开始新一局。棋盘渲染由printBoard(highiq.ms)完成:无效格输出两个空格、空孔输出o、钉子输出!,与原始 BASIC 版的字符风格保持一致。

与原始 BASIC 版的对应关系

对照 highiq.bas 可以看出 MiniScript 移植保留了原版的数据结构与流程骨架,只是用现代语言特性重写:

职责BASIC 原版(highiq.bas)MiniScript 移植(highiq.ms)
棋盘建模DIM T(9,9)5/-5/0三态标记(L4、L28-L65)9×9 数组t同三态标记,setupBoard
钉子编号DATA语句声明 33 个编号 +B(M)=-7映射(L36-L41)pinNums列表 +pinToPos字典
走子合法性借助B()数组与算术判断(L100-L190)isPin/isHole/isValidJump函数
打印棋盘GOSUB 500(L56-L72),TAB(Y*2)排版printBoard函数
更新棋盘GOSUB 1000(L73-L98)doOneMove函数
终局判定GOSUB 1500(L99-L133)checkGameOver函数

值得注意的是,BASIC 版的编号体系(13、14、15 / 22、23、24 / 29~35 / 38~44 / 47~53 / 58、59、60 / 67、68、69)被 MiniScript 版原样继承,这意味着两版的走子输入方式与玩家操作体验完全一致,也便于对照调试。此外,BASIC 版的中心编号为 41(B(41)=-3,即初始空孔),与 MiniScript 版t[5][5]=0语义等价。

运行与验证要点

  • 预期输出:程序启动后依次打印标题 "H-I-Q"、Creative Computing 版权行、带编号的完整棋盘图,以及压缩版棋盘使用提示;游戏过程与结束时的提示语均可在源码print语句中核对(如Illegal move, try again...The game is over.You had N pieces remaining.Bravo! You made a perfect score!)。
  • 两种运行方式的选择:仅需终端执行脚本用命令行 MiniScript;希望在可视化虚拟磁盘中浏览文件、编辑源码则用 Mini Micro 的 "Mount Folder..." 挂载方式。二者加载的都是同一个highiq.ms,行为一致。
  • 适用前提:命令行方式要求系统已安装 MiniScript 命令行解释器;Mini Micro 方式要求已安装 Mini Micro。本仓库只提供.ms脚本与说明文档,不包含解释器本身,首次运行前需先完成对应环境的安装与挂载配置。

通过本文,你既掌握了在两种环境下运行 High IQ MiniScript 移植版的具体操作,也理解了其"9×9 三态棋盘 + 编号映射 + 曼哈顿距离判定"的实现范式——这套模式在00_Alternate_Languages目录下其他 MiniScript 移植(如 Craps、Diamond 等)中同样适用,可作为学习 MiniScript 游戏开发与经典游戏移植的参考起点。

  • 示例工程

【免费下载链接】basic-computer-games

An updated version of the classic "Basic Computer Games" book, with well-written examples in a variety of common MEMORY SAFE, SCRIPTING programming languages. See https://coding-horror.github.io/basic-computer-games/

项目地址:https://gitcode.com/gh_mirrors/ba/basic-computer-games
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 20:00:03

damo图解原理:3个致命坑让你配置环境卡半天,面试必问

damo图解原理:3个致命坑让你配置环境卡半天,面试必问 配置环境就卡半天,是不是你也觉得这行水太深?刚把项目跑起来,面试官却盯着你的 package.json 或 requirements.txt 问底层的依赖解析逻辑,瞬间哑火。这不仅是环境配置的问题,更是 面试必问 的底层原理盲区。…

作者头像 李华
网站建设 2026/9/23 20:00:00

搞懂Incoming手写实现:3个方案对比助你从入门到精通

搞懂Incoming手写实现:3个方案对比助你从入门到精通 复制来的代码跑不通,报错信息像天书,你盯着屏幕抓耳挠腮,这种绝望感我太懂了。很多新手卡在【incoming】这个概念上,以为只是简单的参数传递,结果一动手写实现就露馅。别急,今天咱们不整虚的,直接拆解【incoming】在真实业务里的三种主…

作者头像 李华
网站建设 2026/9/23 19:59:56

岂因祸福避趋之源码解析:3个坑点教你搞定跨域与鉴权

岂因祸福避趋之源码解析:3个坑点教你搞定跨域与鉴权 面试被问“跨域怎么解决”,你只敢答 CORS 和 JSONP?面试官追问“那 JWT 失效了怎么无感刷新?Token 放在 Cookie 还是 Header 里?”你脑子一片空白。别慌,这就是典型的“知其然不知其所以然”。…

作者头像 李华
网站建设 2026/9/23 19:59:24

苹果数据迁移避坑指南:3步搞定iOS换机不丢数据

苹果数据迁移避坑指南:3步搞定iOS换机不丢数据 官方文档翻了三遍还是头大?别慌,我整理了一份实战避坑指南。咱们直接上干货,拒绝废话。 苹果设备换机,数据迁移是最让人头大的一环。照片、微信聊天记录、银行APP登录态、甚至是你精心调校的手表数据,一旦丢失,补回来的成本极高。很多人依赖官方“快速开始”,…

作者头像 李华
网站建设 2026/9/23 19:59:12

红烛教鞭性能优化避坑指南:3步让代码快10倍

红烛教鞭性能优化避坑指南:3步让代码快10倍 复制来的代码跑不通,报错信息像天书一样看不懂,这是很多开发者深夜加班时的真实写照。你盯着屏幕上的 IndexOutOfBoundsException 或 OutOfMemoryError…

作者头像 李华