組譯器實在太無聊了, 整天和 elf section, x86 machine code 搏鬥, 真苦! 我寫了太
多練功型的程式, 這些程式大多是幫助我理解某個概念, 實用性不高, 成就感也不大, 我
決定先暫停組譯器, 來寫個自己也會用的程式。
就是你了, 皮卡丘, 阿, 不是 ... 是俄羅斯方塊。
俄羅斯方塊大家都會玩, 但不是每個人都會寫俄羅斯方塊, 稍微思考後, 覺得還蠻難的,
沒有任何突破點, 絲毫無法下手寫程式。
( https://goo.gl/v7epTz )
fig 0. 決戰俄羅斯
這個程式我 200x 年就想寫了, 不過直到最近 (201706) 我才真的動手, 大概是練功型程
式我真的有點膩了, fig 0 是決戰俄羅斯, 我想寫的是這個版本, 和一般的俄羅斯方塊有
什麼不同呢? 他有一些特殊方塊, 會有特殊功能。我很喜歡那些特殊功能的方塊, 能增加
遊戲性, 當然還有其雙人的對戰功能, 也很有趣, 在同一個螢幕上就可以 2 人對戰, 不
用透過網路。
俄羅斯方塊要完成好多部份, 把目標簡化很重要, 這個步驟我已經非常熟悉, 第一個想到
的就是, 先來實作移動方塊吧! 這樣感覺簡單了一些, 但其實還是沒方向 ...
俄羅斯方塊有很多不同的方塊, 英文術語是 - Tetromino ( https://goo.gl/2QH42E ),
我決定先實作 z Tetromino。
( https://goo.gl/2EGPPi ): two stacked horizontal dominoes with the top
one offset to the left.
最後的成果就是 fig 1。
( https://goo.gl/MDmSa1 )
fig 1. 移動 z Tetromino
這個 console mode 程式應該嚇壞你了, 怎麼這麼醜, 但他包含了整個概念, 把繪製漂亮
的 UI 功能抽離出來, 這樣會比較容易專住在主要核心上, 要畫出好看的圖形可不是件容
易的事情, 先不把焦點放在圖形處理上。只要 c++ 標準程式庫就可以執行了, 其中用到
了 sleep, 這個可能不是標準, 但用 for loop 也可以完成 delay 的動作。
z Tetromino 可以順利的移動, 也可以旋轉, 並且不會超過邊界。這一回合就只做這件
事, 感覺簡單了一些, 但實際上我在筆記本上畫了不少方塊圖, 才得以想到方法, 完成這
個功能。
( https://goo.gl/kVzrmN )
fig 2. z Tetromino 設計方式
一個方塊是由 4 個點構成, 只要好好的描述好這 4 個點, 就可以完成移動、旋轉。
z Tetromino 由 fig 2 那 4 個點構成, p0, p1, p2, p3:
p0: (2,3)
p1: (3,3)
p2: (3,4)
p3: (4,4)
往右移動就是在改變 p0, p1, p2, p3 這些座標, 你一定也想到要怎麼做了吧! 把所有點
的 x 加 1 就搞定了。
p0: (3,3)
p1: (4,3)
p2: (4,4)
p3: (5,4)
換成程式碼就是這樣:
int right()
{
++p0_.x_;
++p1_.x_;
++p2_.x_;
++p3_.x_;
}
簡單到不用說明, 上、下、左也是一樣的道理。
再來要怎麼畫出畫面呢? 宣告 2X2 array container_[10][20] 來處理, 把
p0: (2,3)
p1: (3,3)
p2: (3,4)
p3: (4,4)
的座標標成 1, 其他標 0, 就會有類似的東西:
1111111111
1000000001
1000000001
1011000001
1001100001
1000000001
1000000001
1000000001
1000000001
1000000001
1000000001
1000000001
1111111111
程式只要去檢查這個 array 所有值, 是 1 的就畫 1, 0 的就畫 0, 這樣就可以畫出整個
俄羅斯方塊的畫面。
另外一個難題是碰撞偵測, 我怎麼知道方塊到底了, 外圍的 1 是我的邊框, 在 down()
的函式會更新 4 個點的座標, 檢查新座標的位置是不是 1, 若是, 就表示遇到邊框或是
其他方塊, 原理就是這樣。
下次再來談談旋轉, 其實也一樣, 把 4 個點的座標改動而已。
我本來打算參考 fig 3 的書來實做俄羅斯方塊, 不過我收到時, 已經做出 2 個方塊可以
移動、旋轉, 也可以消掉方塊的版本了, 儘管如此, 此書還是有不少可以參考的地方,
厄 ... 這本書是使用 trubo pascal 完成俄羅斯方塊。
不過我也不打算看別人的想法, 我要自己想出來怎麼寫俄羅斯方塊。
( https://goo.gl/XxS4VE )
fig 3. 2017/06/20 09:23:17 訂購於 https://tw.bid.yahoo.com/item/100125001955,
0170623 收到 200+80
目前的版本:
可以2人一起玩了。
一人玩 2 個部份還真的有點手忙腳亂。
畫面是用 printf 印出來的。
這個程式用到了 c++17, 所以要用 g++-7 編譯。
而畫面繪製用到了 coroutine。
支援3種特殊方塊, 2 種普通方塊。
畫面:
https://goo.gl/photos/KgsrChwmZoPYdDDJ8
// 本文使用 Blog2BBS 自動將Blog文章轉成縮址的BBS純文字 http://goo.gl/TZ4E17 //