news 2026/9/23 19:05:37

Flip Flop 经典益智游戏备选语言移植解析:从 BASIC 原版到多语言实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flip Flop 经典益智游戏备选语言移植解析:从 BASIC 原版到多语言实现
  • 示例工程

【免费下载链接】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
点击查看免费下载

本指南以《Basic Computer Games》(1978)中的经典益智游戏 Flip Flop 为核心,围绕其在 00_Alternate_Languages/36_Flip_Flop 目录中的备选语言移植展开。你将了解该游戏的完整规则与操作指令、BASIC 原版的伪随机翻转算法,以及 Python、Rust、MiniScript 等移植实现如何忠实还原"同一局内固定随机序列"这一关键机制,并掌握各实现的运行方式与移植要点。

游戏概述:把十个 X 翻成十个 O

Flip Flop 是一个单人益智游戏,目标非常直观:把一行十个X

X X X X X X X X X X

变成一行十个O

O O O O O O O O O O

操作方式是输入一个数字,对应这行中某个位置的下标。每次输入后,该位置的符号会发生翻转(XO,或OX)。游戏的关键设定在于:某些数字输入后只有 1 个位置改变,而另一些数字会连锁改变第 2 个位置——例如输入 3 可能只翻转位置 3,但也可能顺带翻转其他某个位置。官方提示玩家应能在12 步或更少步数内解决,鼓励玩家摸索取胜策略。

游戏还内置了两个特殊指令:

  • 输入0:将整行重置回全部X,用于重新尝试同一局;
  • 输入11:在游戏任意时刻开始一局全新的游戏。

该游戏最初由纽约新海德公园(New Hyde Park, New York)的 Michael Kass 编写,收录于 1978 年出版的《Basic Computer Games》一书,后经 Vintage BASIC 站点以flipflop.bas形式存档,成为本仓库移植工作的原始依据。完整的游戏说明见 36_Flip_Flop/README.md。

备选语言目录的定位:三条标准的例外集合

00_Alternate_Languages/36_Flip_Flop/README.md 这份关联文档本身即是对整个00_Alternate_Languages组织方式的说明:该目录下每个子文件夹代表一个程序向非约定 10 种语言之一的移植版本,而这些"约定语言"需要同时满足三个条件:

  1. 流行度:按 TIOBE 指数衡量足够流行;
  2. 内存安全(Memory safe);
  3. 通常被视为"脚本"语言(Scripting language)。

而备选语言移植不受这三条标准约束——这正是 00_Alternate_Languages/README.md 中明确的定位:例如在这里(仅限本目录)C 或 PASCAL 也是允许的,但仍需保持原始程序的观感与交互风格(控制台应用),并尽量保持代码可移植性;若无法移植,则必须在 README 与目录命名中明确说明限制。

也就是说,主目录 36_Flip_Flop 下收录的是 C#、Java、JavaScript、Python、Ruby、Rust、VB.NET 等"约定语言"移植,而00_Alternate_Languages/36_Flip_Flop专门存放不属于约定 10 种语言的移植——例如当前仓库中该目录仅收录了MiniScript一个移植(00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms)。仓库欢迎任何语言的额外移植,但这些移植仅作教育用途,不计入项目最终的移植数量统计。

BASIC 原版源码解析:伪随机翻转的核心机制

原版逻辑集中在 36_Flip_Flop/flipflop.bas 中,整个程序只有约 80 行,却包含了两个值得注意的算法点。

状态表与输入校验

游戏用A$字符串数组保存 10 个位置的当前符号(第 27-31 行初始化全部为"X"),并维护两个关键变量:

  • M:上一次的输入值;
  • N:本次输入值;
  • C:累计猜测次数(第 220 行置 0,第 630 行每次翻转后C=C+1)。

输入校验(第 340-370 行)保证了:

  • N必须为整数,否则跳到第 310 行输出ILLEGAL ENTRY--TRY AGAIN.
  • N=11表示重新开始(跳回第 180 行重新初始化随机种子与版面);
  • N>11视为非法输入;
  • N=0表示只重置版面为全X(跳回第 230 行,保留计数器与随机数)。

两条不同的伪随机公式

游戏的核心趣味来自"第二次翻转位置"的不可预测性。BASIC 原版根据本次输入是否与上一次相同选择两条公式:

  • NM不同(第 420 行):

    R = TAN(Q+N/Q-N) - SIN(Q/N) + 336*SIN(8*N) N = INT(10 * (R - INT(R)))
  • NM相同(第 530 行,连续输入同一个数字):

    R = .592*(1/TAN(Q/N+Q))/SIN(N*2+Q) - COS(N) N = INT(10 * (R - INT(R)))

其中Q是开局时Q=RND(1)生成的随机种子(第 190 行)。两条公式都用三角函数把输入位置N映射到[0, 10)区间的小数,再取整数部分作为"附带翻转"的第二位置。由于Q在一局内固定,同一局中相同输入会得到相同的附带位置——这是保证谜题可复现、可推敲的关键设计;而每开一局Q重新生成,谜面就完全不同。

附带翻转还有一个细节:若计算出的第二位置N恰好也是O(已翻转),则逻辑上会回落到把N位置设回X(第 480、590 行),形成一种"连锁但收敛"的行为。

胜负判定

每步翻转后重新打印整行(第 610-640 行),随后检查 10 个位置是否全部为O(第 650-670 行)。全部为O时,根据步数输出两种结语(第 680-710 行):

  • 步数C<=12VERY GOOD. YOU GUESSED IT IN ONLY C GUESSES.
  • 步数C>12TRY HARDER NEXT TIME. IT TOOK YOU C GUESSES.

最后询问是否再来一局(第 720-770 行),回答N开头则结束程序。

多语言移植实践对比

备选语言移植的价值在于:用不同语言的语法忠实还原同一套规则。以仓库中的三个实现为例,可以看到"同样的算法,不同的落地方式"。

Python:显式封装翻转逻辑

36_Flip_Flop/python/flipflop.py 用flip_dict = {"X": "O", "O": "X"}表达翻转(第 28 行),并把"附带位置计算 + 翻转"抽成独立的flip_bits函数(第 31-46 行),接收一个r_function: Callable[[int], float]回调来注入两条不同的公式——当m == n(连续输入同一数字)时使用第二条公式,否则使用第一条(第 97-111 行)。同时它明确注释了第 0 个元素的存在理由:"We add an extra 0-th item because this sometimes is set to something but we never check what it is for completion of the puzzle"(第 68-70 行)——即保留 1-based 索引以对齐 BASIC 的A$(N)语义,而最终胜负判定只检查row[1:]

Rust:结构体封装游戏状态

36_Flip_Flop/rust/src/game.rs 把游戏建模为Game结构体,字段包括board: [char; 10]last_moveentropy(即 BASIC 中的随机种子Q)与tries。两条公式被合并进get_other方法(第 83-94 行),通过equals_last_move布尔参数选择分支;flip方法(第 70-81 行)处理X/0互转,reset_boardreset_game(第 115-124 行)分别对应 BASIC 中"输入 0 重置版面"与"输入 11 开新局"两种语义——后者还会重新生成entropy = rand::random()。入口 36_Flip_Flop/rust/src/main.rs 通过morristown公共工具库打印标题与交互提示,主循环反复调用game.play()直至玩家不再继续。

MiniScript:备选语言的代表实现

作为00_Alternate_Languages/36_Flip_Flop目录下唯一的备选语言移植,00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms 由 Joe Strout 于 2023 年移植,并保留了原始创作署名。它同样采用[""] + ["X"] * 10的技巧维持 1-based 索引(第 43 行),getInput函数循环校验输入必须为整数且落在0..11(第 32-39 行),并且把两条公式完整保留:tan(q + n/q - n) - sin(q/n) + 336*sin(8*n)(第 60 行)与0.592 * (1 / tan(q/n + q)) / sin(n*2 + q) - cos(n)(第 72 行),与 BASIC 原版逐项对应。

移植要点与注意事项

综合上述实现,可以把 Flip Flop 移植中容易踩坑的点归纳如下:

要点BASIC 原版行为移植建议
索引体系A$数组 1-based 访问(A$(N)Python/MiniScript 用占位第 0 元素保持 1-based,Rust 用(i - 1) as usize转 0-based
随机种子Q=RND(1),一局内固定每局重新随机,同局内复用;输入 0 重置版面重置种子
两条公式N==M与否切换将"上一步输入"作为状态显式保存,供分支判断
输入校验非整数、>11判非法循环读取直到合法,非法时输出ILLEGAL ENTRY--TRY AGAIN.
特殊输入0重置版面,11开新局在分支前先处理,注意11会重置计数器与种子
胜负判定全部为O且步数<=12输出VERY GOODTRY HARDER NEXT TIME两种结语,注意区分

如何运行这些实现

仓库是只读的,你可以通过查看与本地运行来验证上述行为:

  • BASIC 原版:使用兼容 Vintage BASIC 的解释器运行 36_Flip_Flop/flipflop.bas;
  • Pythonpython flipflop.py(位于 36_Flip_Flop/python/flipflop.py);
  • Rust:进入 36_Flip_Flop/rust 后cargo run(依赖见Cargo.toml);
  • MiniScript:在 MiniScript 环境(如 Mini Micro)中加载 00_Alternate_Languages/36_Flip_Flop/MiniScript/flipflop.ms 执行。

如果你想为 Flip Flop 贡献一个新的备选语言移植,请参照00_Alternate_Languages的目录约定:将代码放入对应子目录并附上 README,保持控制台应用的原始观感,同时像上述实现一样在注释中说明任何与原版行为不一致的地方——这类移植仅作教育用途,但这恰恰是理解"同一算法在不同语言中的表达差异"的最佳练习。

  • 示例工程

【免费下载链接】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 19:02:43

电脑声音太小?Cool Edit录音增强与音频后期处理全攻略

上周有个粉丝私信我&#xff0c;说想用 Cool Edit 录一首歌&#xff0c;结果折腾了两天&#xff0c;录进去的声音比蚊子叫还小&#xff0c;电脑本身放歌也总觉得差口气。我问他麦克风增益开了没&#xff0c;他反问我"什么是增益"。这个对话我见过太多次了——多数人下…

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

SCMA瑞利信道下的PM-MPA检测器MATLAB仿真与避坑指南

简介&#xff1a;面向5G非正交多址技术研究者的MATLAB实现包&#xff0c;聚焦SCMA系统下的PM-MPA检测算法。资源基于消息传递与最大后验概率思想&#xff0c;提供瑞利信道环境中的完整仿真链路&#xff0c;适合通信工程高年级学生、算法工程师及科研人员参考复现。包内共5个文件…

作者头像 李华
网站建设 2026/9/23 18:55:57

DeepSeek企业知识库微调实战:从文档清洗到LoRA部署

简介&#xff1a;本资源是一份面向企业AI工程师与知识系统架构师的实战指南&#xff0c;聚焦DeepSeek大模型在跨行业知识库建设中的落地路径与微调方法论&#xff0c;解决传统知识管理系统语义理解弱、数据孤岛难打通、个性化服务缺失等共性难题。文档共24页PDF&#xff0c;结构…

作者头像 李华
网站建设 2026/9/23 18:55:55

DeepSeek+MIDI实现AI作曲:从乐谱生成到工程落地的完整指南

简介&#xff1a;面向AI音乐创作开发者的实战指南&#xff0c;聚焦DeepSeek与MIDI技术的融合应用&#xff0c;系统讲解从MIDI数据采集、清洗、特征提取&#xff0c;到模型架构设计、训练调优&#xff0c;再到音乐参数生成与MIDI文件输出的完整链路。文档共26页&#xff0c;以“…

作者头像 李华