使用 Bash 创建集中注意力游戏 PAIRS
探索使用 Bash 编写配对记忆游戏和一维数组的细微之处。
我一直是鲁德亚德·吉卜林的粉丝。他写了一些伟大的小说和故事,大多是关于英国殖民时代的印度。在我们现代的政治正确性中?不尽然,但尽管如此,他的书对于读者来说仍然很有趣,并且仍然被认为是那个时代的伟大文学作品。他的作品包括《丛林之书》、《勇敢的船长》、《如此而已的故事》和《成为国王的人》等等。
他还写了一部伟大的间谍小说,讲述了一个年轻的英国男孩,他被当作印度本地人抚养长大,然后被英国政府招募为间谍。男孩的名字就是书名:《基姆》。在故事中,基姆接受训练,拥有过目不忘的记忆力,训练方式是一种记忆游戏,游戏内容是展示一盘形状、大小和颜色各异的石头。然后把它藏起来,他必须背诵出尽可能多的图案。
由于某种原因,那个场景一直让我印象深刻,我甚至试图通过类似的游戏来教我的孩子们对周围环境保持警觉,比如“闭上你的眼睛。现在,刚才经过我们的汽车是什么颜色的?”由于我们大多数人都是糟糕的观察者(例如,看看相互矛盾的目击者事故报告就知道了),这对日常生活的普遍观察无疑是一个很好的练习。
虽然尝试将这种记忆游戏复制成程序很诱人,但现实情况是,仅凭 shell 脚本,这将是困难的。也许你可以显示一个网格中字母和数字的随机模式,然后清除屏幕,然后要求用户输入模式,但这实际上更像是面向屏幕的图形应用程序的游戏,而不是 shell 脚本。
但是,有一个简化的版本,你可以用一副扑克牌玩:集中注意力。你可能在人生的某个阶段自己玩过。你将牌面朝下放在网格中,然后一次翻开两张牌,尝试找到配对。在开始时,这只是随机猜测,但随着游戏的进行,它变得更像是对你空间记忆的考验,到最后,优秀的玩家几乎都知道每张未翻开的牌在他们回合开始时的位置。
设计 PAIRS当然,你可以用 shell 脚本复制它,并且由于它将是一个 shell 脚本,你还可以使牌对的数量可变。我们把这个游戏叫做 PAIRS。
作为最低要求,我们使用四对牌,这应该使调试变得容易。由于复制扑克牌值没有任何实际好处,因此使用字母同样容易,这意味着最多 26 对牌,或 52 个位置。并非每个值都会产生适当的分布或网格,但如果你的目标是每行 13 个,那么玩家就可以玩 1-4 行的可能性。
如果有点击点,可玩性会增强,但这只是一个 shell 脚本,伙计,所以你必须忍受国际象棋风格的网格表示法:行,槽。
显示效果可能类似于此模型
1 2 3 4 5 6 7 8 9 10 11 12 13
1: [-] [-] [-] [-] [-] [-] [-] [-] [-] [-] [-] [-] [-]
2: [-] [-] [-] [A] [-] [-] [-] [-] [-] [-] [-] [-] [-]
3: [-] [-] [-] [-] [-] [-] [-] [-] [E] [-] [-] [-] [-]
4: [-] [-] [-] [-] [-] [-] [-] [-] [-] [-] [-] [-] [Z]
字母 A 在 2,4,字母 E 在 3,9。不过,更好的是,因为第一个值应该始终是 1-4,你可以省略逗号以使内容更简洁,使 A 在 24,E 在 39。也会有三位数值,例如 413 的 Z,但这仍然很容易拆分和处理。
实际上,既然现在有一个 13x4 的网格模式,让我们重新思考游戏的灵活性。与其允许任意数量的牌对,不如让游戏不太灵活,并限制用户只能指定他们想要多少行 13 列。更重要的是,只有偶数行是可以接受的。(显然,对于单行 13 列,很难只显示牌对!)
数据表示Bash 对数组有不错的支持,所以我的第一个想法是将其设为线性数组,并简单地除以 13,根据需要将“显示”坐标转换为实际数组坐标。多维数组会更好,但 Bash 不提供对该特定数据结构的支持。有一种使用关联数组的变通方法,但这需要 Bash 4.x,而 MacOS X 仍然附带 Bash 3.x,这意味着我们的许多读者(嘘,我知道并非你们所有人都是全职 Linux 爱好者)将被排除在外。啊,真有趣,真有趣。
闲聊够了,让我们开始编码方面的内容,尽管我必须在我的下一篇文章中继续开发。
编码网格启动整个项目的合理起点是研究如何在 Bash 中使用一维数组。数组槽被分配一个值,如下所示
myArray[2]=value
并且以稍微笨拙的格式引用
echo ${myArray[2]}
Bash 希望你在使用前使用 declare 语句来标识数组—declare -a myArray
—你可以像这样分配初始值
declare -a myArray=(cat dog pig frog snake)
有一些关于 @ 和 * 的方便快捷方式需要学习,但让我们直接开始编码。
首先,这是我编写的 Bash 函数,用于使用 A-Z 值初始化数组(我将在另一个函数中打乱这些值)
initialize ()
{
# initialize the board with sequential letters
count=1 maxcount=$1
while [ $count -le $maxcount ]
do
addon=$(( 13 * ( $count - 1 ) ))
for slot in {1..13}
do
index=$(( $addon + $slot ))
letter=$(( $index % 26 ))
board[ $index ]=${letters[$letter]}
done
count=$(( $count + 1 ))
done
}
虽然看起来这里有很多需要考虑的,但该函数的核心是 while
循环内的 for
循环。while
循环遍历行,for
循环遍历每行 13 个槽。
最有趣的一行可能是这个
board[ $index ]=${letters[$letter]}
board 数组中给定槽的值将设置为 $letters
数组的 $letter
索引值。该数组在开头的声明中设置
declare -a letters=(A B C D E F G H I J K L M N O P Q R
S T U V W X Y Z)
结果很有趣,因为 Bash 真的希望使用从 0 开始的索引,而这里我将其全部用作从 1 开始的索引。但是,我将在我的下一篇文章中向你展示这一点,PAIRS 游戏编程冒险的延续!