「Emacs 遊戲機」完全指南

2020-03-02 09:36:00

又是週一,你正在為你的老闆 Lumbergh (LCTT 譯註:《上班一條蟲》中的副總裁)努力倒騰那些 無聊之極的文件。為什麼不玩玩 Emacs 中類似 zork 的文字冒險遊戲來讓你的大腦從單調的工作中解脫出來呢?

但說真的,Emacs 中既有遊戲,也有古怪的玩物。有些你可能有所耳聞。這些玩意唯一的共同點就是,它們大多是很久以前就新增到 Emacs 中的:有些東西真的是相當古怪(如你將在下面看到的),而另一些則顯然是由無聊的員工或學生們編寫的。它們全有一個共同點,都帶著一種奇思妙想和隨意性,這在今天的 Emacs 中很少見。Emacs 現在變得十分嚴肅,在某種程度上,它已經與 20 世紀 80 年代那些遊戲被編寫出來的時候大不一樣。

漢諾塔

漢諾塔 是一款古老的數學解密遊戲,有些人可能對它很熟悉,因為它的遞迴和疊代解決方案經常被用於電腦科學教學輔助。

Tower of Hanoi Screenshot

Emacs 中有三個命令可以執行漢諾塔:M-x hanoi 預設為 3 個碟子; M-x hanoi-unixM-x hanoi-unix-64 使用 unix 時間戳的位數(32 位或 64 位)作為預設盤子的個數,並且每秒鐘自動移動一次,兩者不同之處在於後者假裝使用 64 位時鐘(因此有 64 個碟子)。

Emacs 中漢諾塔的實現可以追溯到 20 世紀 80 年代中期——確實是久得可怕。它有一些自定義選項(M-x customize-group RET hanoi RET),如啟用彩色碟子等。當你離開漢諾塔緩衝區或輸入一個字元,你會收到一個諷刺的告別資訊(見上圖)。

5x5

5x5 game grid

5x5 的遊戲是一個邏輯解密遊戲:你有一個 5x5 的網格,中間的十字被填滿;你的目標是通過按正確的順序切換它們的空滿狀態來填充所有的單元格,從而獲得勝利。這並不像聽起來那麼容易!

輸入 M-x 5x5 就可以開始玩了,使用可選的數位引數可以改變網格的大小。這款遊戲的有趣之處在於它能向你建議下一步行動並嘗試找到該遊戲網格的解法。它用到了 Emacs 自己的一款非常酷的符號 RPN 計算器 M-x calc(在《Emacs 快樂計算》這篇文章中,我使用它來解決了一個簡單的問題)。

所以我喜歡這個遊戲的原因是它提供了一個非常複雜的解題器——真的,你應該通過 M-x find-library RET 5x5 來閱讀其原始碼——這是一個試圖通過暴力破解遊戲解法的“破解器”。

建立一個更大的遊戲網格,例如輸入 M-10 M-x 5x5,然後執行下面某個 crack 命令。破解器將嘗試通過疊代獲得最佳解決方案。它會實時執行該遊戲,觀看起來非常有趣:

  • M-x 5x5-crack-mutating-best: 試圖通過變異最佳解決方案來破解 5x5。
  • M-x 5x5-crack-mutating-current: 試圖通過變異當前解決方案來破解 5x5。
  • M-x 5x5-crack-random: 嘗試使用隨機方案解破解 5x5。
  • M-x 5x5-crack-xor-mutate: 嘗試通過將當前方案和最佳方案進行互斥或運算來破解 5x5。

文字動畫

你可以通過執行 M-x animation-birthday-present 並給出你的名字來顯示一個奇特的生日禮物動畫。它看起來很酷!

xkcd

這裡用的 animate 包也用在了 M-x butterfly 命令中,這是一個向上面的 XKCD 漫畫致敬而新增到 Emacs 中的命令。當然,漫畫中的 Emacs 命令在技術上是無效的,但它的幽默足以彌補這一點。

黑箱

我將逐字參照這款遊戲的目標:

遊戲的目標是通過向黑盒子發射光線來找到四個隱藏的球。有四種可能: 1) 射線將通過盒子不受干擾; 2) 它將擊中一個球並被吸收; 3) 它將偏轉並退出盒子,或 4) 立即偏轉,甚至不能進入盒子。

所以,這有點像我們小時候玩的戰艦遊戲,但是……是專為物理專業高學歷的人準備的吧?

這是另一款新增於 20 世紀 80 年代的遊戲。我建議你輸入 C-h f blackbox 來閱讀玩法說明(文件巨大)。

泡泡

Bubbles game

M-x bubble 遊戲相當簡單:你必須用盡可能少移動清除儘可能多的“泡泡”。當你移除氣泡時,其他氣泡會掉落並黏在一起。這是一款有趣的遊戲,此外如果你使用 Emacs 的圖形化使用者介面,它還支援影象顯示。而且它還支援滑鼠。

你可以通過呼叫 M-x bubbles-set-game-<difficulty> 來設定難度,其中 <difficulty> 可以是這些之一:easymediumdifficultharduserdefined。此外,你可以使用:M-x custom-group bubbles 來更改圖形、網格大小和顏色。

由於它即簡單又有趣,這是 Emacs 中我最喜歡的遊戲之一。

幸運餅乾

我喜歡 fortune 命令。每當我啟動一個新 shell 時,這些與文學片段、謎語相結合的刻薄、無益、常常帶有諷刺意味的“建議”就會點亮我的一天。

令人困惑的是,Emacs 中有兩個包或多或少地做著類似的事情:fortunecookie。前者主要用於在電子郵件簽名中新增幸運餅乾訊息,而後者只是一個簡單的 fortune 格式閱讀器。

不管怎樣,使用 Emacs 的 cookie 包前,你首先需要通過 customize-option RET cookie RET 來自定義變數 cookie-file 告訴它從哪找到 fortune 檔案。

如果你的作業系統是 Ubuntu,那麼你先安裝 fortune 軟體包,然後就能在 /usr/share/games/fortune/ 目錄中找到這些檔案了。

之後你就可以呼叫 M-x cookie 隨機顯示 fortune 內容,或者,如果你想的話,也可以呼叫 M-x cookie-apropos 查詢所有匹配的餅乾。

破譯器

這個包完美地抓住了 Emacs 的功利本質:這個包為你破解簡單的替換密碼(如“密碼謎題”)提供了一個很有用的介面。你知道,二十多年前,有些人確實迫切需要破解很多基本的密碼。正是像這個模組這樣的小玩意讓我非常高興地用起 Emacs 來:一個只對少數人有用的模組,但是,如果你突然需要它了,那麼它就在那裡等著你。

那麼如何使用它呢?讓我們假設使用 “rot13” 密碼:在 26 個字元的字母表中,將字元旋轉 13 個位置。 通過 M-x ielm (Emacs 用於 執行 Elisp 的 REPL 環境)可以很容易在 Emacs 中進行嘗試:

*** Welcome to IELM ***  Type (describe-mode) for help.ELISP> (rot13 "Hello, World")"Uryyb, Jbeyq"ELISP> (rot13 "Uryyb, Jbeyq")"Hello, World"ELISP>

簡而言之,你將明文旋轉了 13 個位置,就得到了密文。你又旋轉了一次 13 個位置,就返回了最初的明文。 這就是這個包可以幫助你解決的問題。

那麼,decipher 模組又是如何幫助我們的呢?讓我們建立一個新的緩衝區 test-cipher 並輸入你的密文(在我的例子中是 Uryyb,Jbeyq)。

你現在面對的是一個相當複雜的介面。現在把游標放在紫色行的密文的任意字元上,並猜測這個字元可能是什麼:Emacs 將根據你的選擇更新其他明文的猜測結果,並告訴你目前為止字母表中的字元是如何分配的。

你現在可以用下面各種助手命令來關閉選項,以幫助推斷密碼字元可能對應的明文字元:

  • D: 列出示意圖(該加密演算法中雙字元對)及其頻率
  • F: 表示每個密文字母的頻率
  • N: 顯示字元的鄰近資訊。我不確定這是幹啥的。
  • MR: 儲存和恢復一個檢查點,允許你對工作進行分支以探索破解密碼的不同方法。

總而言之,對於這樣一個深奧的任務,這個包是相當令人印象深刻的!如果你經常破解密碼,也許這個程式包能幫上忙?

醫生

doctor

啊,Emacs 醫生。其基於最初的 ELIZA,“醫生”試圖對你說的話進行心理分析,並試圖把問題複述給你。體驗幾分鐘,相當有趣,它也是 Emacs 中最著名的古怪玩意之一。你可以使用 M-x doctor 來執行它。

Dunnet

Emacs 自己特有的類 Zork 文字冒險遊戲。輸入 M-x dunnet 就能玩了。這是一款相當不錯的遊戲,簡單的說,它是另一款非常著名的 Emacs 遊戲,很少有人真正玩到通關。

如果你發現自己能在無聊的文件工作之間空出時間來,那麼這是一個超級棒的遊戲,內建“老板螢幕”,因為它是純文字的。

哦,還有,不要想著吃掉那塊 CPU 卡 :)

五子棋

gomoku

另一款寫於 20 世紀 80 年代的遊戲。你必須將 5 個方塊連成一條線,井字棋風格。你可以執行 M-x gomoku 來與 Emacs 對抗。遊戲還支援滑鼠,非常方便。你也可以自定義 gomoku 組來調整網格的大小。

生命遊戲

康威的生命遊戲 是細胞自動機的一個著名例子。Emacs 版本提供了一些啟動模式,你可以(通過 elisp 程式設計)調整 life-patterns 變數來更改這些模式。

你可以用 M-x life 觸發生命遊戲。事實上,所有的東西,包括顯示程式碼、注釋等等一切,總共不到 300 行,這也讓人印象深刻。

乒乓,貪吃蛇和俄羅斯方塊

tetris

這些經典遊戲都是使用 Emacs 包 gamegrid 實現的,這是一個用於構建網格遊戲(如俄羅斯方塊和貪吃蛇)的通用框架。gamegrid 包的偉大之處在於它同時相容圖形化和終端 Emacs:如果你在 GUI 中執行 Emacs,你會得到精美的圖形;如果你沒有,你看到簡單的 ASCII 藝術。

你可以通過輸入 M-x pongM-x snakeM-x tetris 來執行這些遊戲。

特別是俄羅斯方塊遊戲實現的非常到位,會逐漸增加速度並且能夠滾軸。而且既然你已經有了原始碼,你完全可以移除那個討厭的 Z 形塊,沒人喜歡它!

Solitaire

solitaire image

可惜,這不是紙牌遊戲,而是一個基於“釘子”的遊戲,你可以選擇一塊石頭(o)並“跳過”相鄰的石頭進入洞中(.),並在這個過程中去掉你跳過的石頭,最終只能在棋盤上留下一塊石頭,重複該過程直到棋盤被請空(只保留一個石頭)。

如果你卡住了,有一個內建的解題器名為 M-x solitire-solve

Zone

我的另一個最愛。這是一個螢幕保護裝置——或者更確切地說,是一系列的螢幕保護裝置。

輸入 M-x zone,然後看看螢幕上發生了什麼!

你可以通過執行 M-x zone-when-idle(或從 elisp 呼叫它)來設定螢幕保護裝置的空閒時間,時間以秒為單位。你也可以通過 M-x zone-leave-me-alone 來關閉它。

如果在你的同事看著的時候啟動它,你的同事肯定會抓狂的。

乘法解謎

mpuz

這是另一個腦筋急轉彎的益智遊戲。當你執行 M-x mpuz 時,將看到一個乘法解謎題,你必須將字母替換為對應的數位,並確保數位相加(相乘?)符合結果。

如果遇到難題,可以執行 M-x mpuz-show-solution 來解決。

雜項

還有更多好玩的東西,但它們就不如剛才那些那麼好玩好用了:

  • 你可以通過 M-x morse-regionM-x unmorse-region 將一個區域翻譯成莫爾斯電碼。
  • Dissociated Press 是一個非常簡單的命令,它將一個類似隨機穿行的馬爾可夫鏈生成器應用到緩衝區中的文字中,並以此生成無意義的文字。試一下 M-x dissociated-press
  • gametree 軟體包是一個通過電子郵件記錄和跟蹤國際象棋遊戲的複雜方法。
  • M-x spook 命令插入隨機單詞(通常是到電子郵件中),目的是混淆/超載 “NSA 拖網漁船” —— 記住,這個模組可以追溯到 20 世紀 80 年代和 90 年代,那時應該有間諜們在監聽各種單詞。當然,即使是在十年前,這樣做也會顯得非常偏執和古怪,不過現在看來已經不那麼奇怪了……

總結

我喜歡 Emacs 附帶的遊戲和玩具。它們大多來自於,嗯,我們姑且稱之為一個不同的時代:一個允許或甚至鼓勵奇思妙想的時代。有些玩意非常經典(如俄羅斯方塊和漢諾塔),有些對經典遊戲進行了有趣的變種(如黑盒)——但我很高興這麼多年後它們依然存在於 Emacs 中。我想知道時至今日,類似這些的玩意是否還會再納入 Emacs 的程式碼庫中;嗯,它們很可能不會——它們將被歸入包管理倉庫中,而在這個乾淨而無菌的世界中,它們無疑屬於包管理倉庫。

Emacs 要求將對 Emacs 體驗不重要的內容轉移到包管理倉庫 ELPA 中。我的意思是,作為一個開發者,這是有道理的,但是……對於每一個被移出並流放到 ELPA 的包,我們是不是在蠶食 Emacs 的精髓?