TETRISもどき

サンプルプログラムです。
昔、PIC-BASIC用に作った「ブロックの落ちるパズルゲーム」を移植しました。

CLS
DIM B(3):DIM BK(3)
DIM D(16):DIM V(16)
*NEWGM
D(0)= &B110000000011
D(1)= &B110000000011
D(2)= &B110000000011
D(3)= &B110000000011
D(4)= &B110000000011
D(5)= &B110000000011
D(6)= &B110000000011
D(7)= &B110000000011
D(8)= &B110000000011
D(9)= &B110000000011
D(10)= &B110000000011
D(11)= &B110000000011
D(12)= &B110000000011
D(13)= &B110000000011
D(14)= &B111111111111
D(15)= &B111111111111
GOSUB *BORN
CNTD=0:LVL=10
*MAIN
CX=X:CY=Y
IF SW AND 2 THEN CNTD=LVL
IF SW AND 4 THEN
CX=CX-1:GOSUB *HITCK
IF HIT=0 THEN X=CX
ENDIF
IF SW AND 8 THEN
CX=CX+1:GOSUB *HITCK
IF HIT=0 THEN X=CX
ENDIF
IF SW AND 16 THEN
GOSUB *TURN
GOSUB *HITCK
IF HIT THEN
FOR H=0 TO 2
B(H)=BK(H)
NEXT
ENDIF
ENDIF
CNTD=CNTD+1
IF CNTD > LVL THEN
CNTD=0
CX=X:CY=CY+1
GOSUB *HITCK
IF HIT THEN
GOSUB *FIX
IF D(0) AND &H3FC THEN GOTO *NEWGM
ELSE
Y=CY
ENDIF
ENDIF
FOR H=0 TO 15
V(H)=D(H)
NEXT
FOR I=0 TO 2
V(I+Y)=B(I) << X OR V(I+Y)
NEXT
FOR H=0 TO 15
FOR I=0 TO 11
IF 1<<I AND V(H) THEN
PSET I,H,1
else
PSET I,H,0
endif
NEXT
NEXT
GOTO *MAIN
*TURN
FOR H=0 TO 2
BK(H)=B(H):B(H)=0
NEXT
FOR H=0 TO 2
FOR H2=0 TO 2
B(H)=B(H) << 1
MSK=BK(H2) >> H AND 1
B(H)=B(H) OR MSK
NEXT
NEXT
RETURN
*HITCK
HIT=0
FOR H=0 TO 2
MSK=B(H)<<CX AND D(H+CY)
HIT=HIT OR MSK
NEXT
RETURN
*FIX
FOR H=0 TO 2
D(H+Y)=B(H)<<X OR D(H+Y)
NEXT
FOR H=0 TO 13
IF D(H)=&HFFF THEN
FOR I=H TO 1 STEP -1
D(I)=D(I-1)
NEXT
D(0)= &HC03
IF LVL>0 THEN LVL=LVL-1
ENDIF
NEXT
GOSUB *BORN
RETURN
*BORN
I=RND % 7
IF I=0 THEN
B(0)=&B010
B(1)=&B010
B(2)=&B010
ENDIF
IF I=1 THEN
B(0)=&B010
B(1)=&B010
B(2)=&B110
ENDIF
IF I=2 THEN
B(0)=&B010
B(1)=&B010
B(2)=&B011
ENDIF
IF I=3 THEN
B(0)=&B000
B(1)=&B111
B(2)=&B010
ENDIF
IF I=4 THEN
B(0)=&B110
B(1)=&B011
B(2)=&B000
ENDIF
IF I=5 THEN
B(0)=&B011
B(1)=&B110
B(2)=&B000
ENDIF
IF I=6 THEN
B(0)=&B110
B(1)=&B110
B(2)=&B000
ENDIF
I=RND % 4
WHILE(I>0)
GOSUB *TURN
I=I-1
WEND
X=5:Y=0
RETURN

これで、1836バイトです。もうちょっとで上限の2000バイトに届くくらいの超大作です。

・今回から行番号があってもなくてもプログラムが動くようになりました。行番号がないほうが行の追加がやりやすく、データ量を節約することができます。
・GOTO/GOSUBがラベル名に対応しました。
たとえば「GOTO *MAIN」と書くと、「*MAIN」と書かれたところへジャンプします。
・シフト命令に対応しました。演算子は「<<」「>>」です。



プログラムの実行画面です。ようするに「テトリス」もどきです。
遊び方ですが、左と右と下のスイッチでブロックを動かします。
Aスイッチでブロックが回転します。

処理スピードですが、、ものすごい遅いです。ブロックが落ちてきません。
どうにかして高速化させないとダメですね。PIC-BASICは中間コードで動いていますが、こっちはテキストのコードを毎回解読しながら動かしているので、遅くなってしまいます。


LEDで表示させるとこんな感じです。
実際には点灯がチカチカします。

(続き)
先のプログラムですが、「BITMAP」という命令を新しく作ってみました。

FOR H=0 TO 15
FOR I=0 TO 11
IF 1<<I AND V(H) THEN
PSET I,H,1
else
PSET I,H,0
endif
NEXT
NEXT

この部分を、、、

cls
bitmap V,0,0,16

、、、こう書き換えるだけで、キビキビ動くようになりました。

http://nicotak.com/nicobasic/edu2/tetris2.gif
BITMAPというのは配列の内容をビットマップ化して一気に描画する命令です。
書式は、

BITMAP 配列名 ,X座標 ,Y座標 ,配列の要素数

です。「配列の要素数」というのはビットマップの高さ(ドット数)を表します。
現時点では、NicoBASICはint型しか配列を作れませんので、ビットマップの幅は必然的に16ドットになります。