自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何讓Emacs俄羅斯方塊變得更難

系統(tǒng)
你知道嗎,Emacs 捆綁了一個俄羅斯方塊的實現(xiàn)?只需要輸入 M-x tetris 就行了。

 

你知道嗎,Emacs 捆綁了一個俄羅斯方塊的實現(xiàn)?只需要輸入 M-x tetris 就行了。

在對文本編輯器的討論中,Emacs 鼓吹者經常提到這一點。“沒錯,但是你那個編輯器能運行俄羅斯方塊嗎?”我很好奇,這會讓大家相信 Emacs 更優(yōu)秀嗎?比如,為什么有人會關心他們是否可以在文本編輯器中玩游戲呢?“沒錯,但是你那臺吸塵器能播放 mp3 嗎?”

有人說,俄羅斯方塊總是很有趣的。像 Emacs 中的所有東西一樣,它的源代碼是開放的,易于檢查和修改,因此 我們可以使它變得更加有趣。所謂更加有趣,我的意思是更難。

讓游戲變得更難的一個最簡單的方法就是“隱藏下一個塊預覽”。你無法在知道下一個塊會填滿空間的情況下有意地將 S/Z 塊放在一個危險的位置——你必須碰碰運氣,希望出現(xiàn)最好的情況。下面是沒有預覽的情況(如你所見,沒有預覽,我做出的某些選擇帶來了“可怕的后果”):

預覽框由一個名為 tetris-draw-next-shape 1 的函數(shù)設置:

  1. (defun tetris-draw-next-shape ()
  2. (dotimes (x 4)
  3. (dotimes (y 4)
  4. (gamegrid-set-cell (+ tetris-next-x x)
  5. (+ tetris-next-y y)
  6. tetris-blank)))
  7. (dotimes (i 4)
  8. (let ((tetris-shape tetris-next-shape)
  9. (tetris-rot 0))
  10. (gamegrid-set-cell (+ tetris-next-x
  11. (aref (tetris-get-shape-cell i) 0))
  12. (+ tetris-next-y
  13. (aref (tetris-get-shape-cell i) 1))
  14. tetris-shape))))

首先,我們引入一個標志,決定是否允許顯示下一個預覽塊 2

  1. (defvar tetris-preview-next-shape nil
  2. "When non-nil, show the next block the preview box.")

現(xiàn)在的問題是,我們如何才能讓 tetris-draw-next-shape 遵從這個標志?最明顯的方法是重新定義它:

  1. (defun tetris-draw-next-shape ()
  2. (when tetris-preview-next-shape
  3. ;; existing tetris-draw-next-shape logic
  4. ))

但這不是理想的解決方案。同一個函數(shù)有兩個定義,這很容易引起混淆,如果上游版本發(fā)生變化,我們必須維護修改后的定義。

一個更好的方法是使用 advice。Emacs 的 advice 類似于 Python 裝飾器,但是更加靈活,因為 advice 可以從任何地方添加到函數(shù)中。這意味著我們可以修改函數(shù)而不影響原始的源文件。

有很多不同的方法使用 Emacs advice(查看手冊),但是這里我們只使用 advice-add 函數(shù)和 :around 標志。advice 函數(shù)將原始函數(shù)作為參數(shù),原始函數(shù)可能執(zhí)行也可能不執(zhí)行。我們這里,我們讓原始函數(shù)只有在預覽標志是非空的情況下才能執(zhí)行:

  1. (defun tetris-maybe-draw-next-shape (tetris-draw-next-shape)
  2. (when tetris-preview-next-shape
  3. (funcall tetris-draw-next-shape)))
  4.  
  5. (advice-add 'tetris-draw-next-shape :around #'tetris-maybe-draw-next-shape)

這段代碼將修改 tetris-draw-next-shape 的行為,而且它可以存儲在配置文件中,與實際的俄羅斯方塊代碼分離。

去掉預覽框是一個簡單的改變。一個更激烈的變化是,讓塊隨機停止在空中

本圖中,紅色的 I 和綠色的 T 部分沒有掉下來,它們被固定下來了。這會讓游戲變得 極其困難,但卻很容易實現(xiàn)。

和前面一樣,我們首先定義一個標志:

  1. (defvar tetris-stop-midair t
  2. "If non-nil, pieces will sometimes stop in the air.")

目前,Emacs 俄羅斯方塊的工作方式 類似這樣子:活動部件有 x 和 y 坐標。在每個時鐘滴答聲中,y 坐標遞增(塊向下移動一行),然后檢查是否有與現(xiàn)存的塊重疊。如果檢測到重疊,則將該塊回退(其 y 坐標遞減)并設置該活動塊到位。為了讓一個塊在半空中停下來,我們所要做的就是破解檢測函數(shù) tetris-test-shape

這個函數(shù)內部做什么并不重要 —— 重要的是它是一個返回布爾值的無參數(shù)函數(shù)。我們需要它在正常情況下返回布爾值 true(否則我們將出現(xiàn)奇怪的重疊情況),但在其他時候也需要它返回 true。我相信有很多方法可以做到這一點,以下是我的方法的:

  1. (defun tetris-test-shape-random (tetris-test-shape)
  2. (or (and
  3. tetris-stop-midair
  4. ;; Don't stop on the first shape.
  5. (< 1 tetris-n-shapes )
  6. ;; Stop every INTERVAL pieces.
  7. (let ((interval 7))
  8. (zerop (mod tetris-n-shapes interval)))
  9. ;; Don't stop too early (it makes the game unplayable).
  10. (let ((upper-limit 8))
  11. (< upper-limit tetris-pos-y))
  12. ;; Don't stop at the same place every time.
  13. (zerop (mod (random 7) 10)))
  14. (funcall tetris-test-shape)))
  15.  
  16. (advice-add 'tetris-test-shape :around #'tetris-test-shape-random)

這里的硬編碼參數(shù)使游戲變得更困難,但仍然可玩。當時我在飛機上喝醉了,所以它們可能需要進一步調整。

順便說一下,根據(jù)我的 tetris-scores 文件,我的 最高分 是:

  1. 01389 Wed Dec 5 15:32:19 2018

該文件中列出的分數(shù)默認最多為五位數(shù),因此這個分數(shù)看起來不是很好。

給讀者的練習

  1. 使用 advice 修改 Emacs 俄羅斯方塊,使得每當方塊下移動時就閃爍顯示訊息 “OH SHIT”。消息的大小與塊堆的高度成比例(當沒有塊時,消息應該很小的或不存在的,當最高塊接近天花板時,消息應該很大)。
  2. 在這里給出的 tetris-test-shape-random 版本中,每隔七格就有一個半空中停止。一個玩家有可能能計算出時間間隔,并利用它來獲得優(yōu)勢。修改它,使間隔隨機在一些合理的范圍內(例如,每 5 到 10 格)。
  3. 另一個對使用 Tetris 使用 advise 的場景,你可以試試 autotetris-mode。
  4. 想出一個有趣的方法來打亂塊的旋轉機制,然后使用 advice 來實現(xiàn)它。

  1. Emacs 只有一個巨大的全局命名空間,因此函數(shù)和變量名一般以包名做前綴以避免沖突。 

  2. 很多人會說你不應該使用已有的命名空間前綴而且應該將自己定義的所有東西都放在一個預留的命名空間中,比如像這樣 my/tetris-preview-next-shape,然而這樣很難看而且沒什么意義,因此我不會這么干。  

 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2015-01-22 15:36:46

游戲源碼

2014-10-08 10:04:14

代碼解釋俄羅斯方塊

2011-06-13 18:21:12

2021-01-12 12:16:55

鴻蒙HarmonyOS游戲

2021-12-29 11:56:16

Linux俄羅斯方塊

2020-05-19 17:26:21

Python俄羅斯方塊游戲開發(fā)

2014-05-26 10:07:18

Javascript俄羅斯方塊

2016-06-13 10:21:49

二維碼條形碼二進制

2015-04-28 09:21:28

JSJS俄羅斯方塊游戲帝國

2023-09-25 12:35:27

Python

2023-09-26 08:51:29

PygamePython語言

2014-06-09 12:47:35

俄羅斯方塊

2012-11-05 10:50:50

程序員萬圣節(jié)俄羅斯方塊

2020-12-17 10:02:16

鴻蒙Hi3861開發(fā)板

2009-06-08 09:59:24

谷歌俄羅斯方塊版權

2011-11-17 16:14:25

Jscex

2020-12-11 12:45:04

鴻蒙Hi3861游戲

2022-11-29 16:35:02

Tetris鴻蒙

2023-10-17 10:20:53

VueReact

2011-07-06 10:12:26

Objective-CCSSJavaScript
點贊
收藏

51CTO技術棧公眾號