C言語テトリスのソースコードを修正

「あなたもできる!C言語テトリスを40分で作る方法 - DQNEO起業日記」
http://dqn.sakusakutto.jp/2012/11/cpp_tetris.html
に掲載されていたテトリス、入力してみた。


https://github.com/DQNEO/CppTetris にあるtetris.cppをテキストエディタで表示させて、別のテキストエディタ(今回はgnupackに入ってるEmacs24.2)で入力する。


コンパイラは、gnupack-devel 10.02 (mingwgccが入っている)を使う。
block.rcとblock.bmpは元のをそのまま使わせてもらう。
make.batに書かれているとおりに、コマンドをminttyコンソールに入力して、ビルド。
動いた。元と同じように書いたので当たり前だけど。
f:id:itouhiro:20121111224124p:plain


tetris.cppざっと読んでみて、気がついたこと:

  • ほとんどC言語。bool型が使われてることと、for (int i=0;式の変数定義、引数のデフォルト値使ってる点だけC++
  • Win32APIを生で使ってる。Windows95でも動作するプログラミング。ランタイムが別に必要なることもないし、実行ファイルも小さいという利点はあるけど、ソースコードの見渡しの効率は悪いかも
  • CreateCompatibleDCとか使ってダブルバッファしてるので画面更新のチラツキはなし。


tetris.exe遊んでみて気がついたこと:

  1. 次のブロックが出てくるまで数秒待たされることがよくある。
  2. 凸の形のブロックが出てこない。
  3. カーソルだけで操作できるのだが、ちょっと操作が軽すぎるような。 回転させすぎて失敗、ということが多い。

不具合修正


「数秒待たされる」「凸が出てこない」に関しては単なるケアレスミス。以下のように修正すればよい。

--- tetris.cpp.6266726997       2012-11-10 12:36:44.000000000 +0900
+++ tetris.cpp  2012-11-12 01:00:34.084027300 +0900
@@ -26,7 +26,7 @@
     {2, {{0, -1},{1, 0}, {1 ,1}}},  // key1
     {2, {{0, -1},{-1,0}, {-1,1}}},  // key2
     {1, {{0,  1},{1, 0}, {1 ,1}}},  // square
-    {4, {{0, -1},{1, 0}, {1 ,0}}},  // T
+    {4, {{0, -1},{1, 0}, {0 ,1}}},  // T
 };

 typedef struct _TAG_STATUS {
@@ -169,7 +169,7 @@

         current.x = 5;
         current.y = 21;
-        current.type = random(7) * 1;
+        current.type = random(7) + 1;
         current.rotate = random(4);
         if(!putBlock(current)) {
             gameOver();


カーソルの移動は、たとえば以下のように手直しする。

--- tetris1.cpp 2012-11-11 22:26:28.280197600 +0900
+++ tetris.cpp  2012-11-11 23:02:18.410178000 +0900
@@ -94,15 +94,29 @@
 bool processInput() {
     bool ret = false;
     STATUS n = current;
+    static int cursorLast = 0;
+
     if (GetAsyncKeyState(VK_LEFT)) {
-        n.x--;
+        if (cursorLast != VK_LEFT) {
+            n.x--;
+            cursorLast = VK_LEFT;
+        }
     } else if (GetAsyncKeyState(VK_RIGHT)) {
-        n.x++;
+        if (cursorLast != VK_RIGHT) {
+            n.x++;
+            cursorLast = VK_RIGHT;
+        }
     } else if (GetAsyncKeyState(VK_UP)) {
-        n.rotate++;
+        if (cursorLast != VK_UP) {
+            n.rotate++;
+            cursorLast = VK_UP;
+        }
     } else if (GetAsyncKeyState(VK_DOWN)) {
         n.y--;
+        cursorLast = VK_DOWN;
         ret = true;
+    } else {
+        cursorLast = 0;
     }

     if (n.x != current.x || n.y != current.y || n.rotate != current.rotate) {

カーソル ← → ↑ を押しっぱなしだと連続入力にならないように変えた。回転しすぎはなくなったけど、カーソル横は押しっぱなしで移動できたほうが操作しやすいかも。カーソル横連打しても移動が間に合わないことがあるから。


これでプレイしやすくなった。
f:id:itouhiro:20121112011651p:plain






続き: C言語テトリスソースコードを読む http://itouhiro.hatenablog.com/entry/20121119/tetris