• タイトル
    91X(電子工作マガジン2018年AUTUMN号掲載)

  • 開発環境
    IchigojamBASIC1.2.1

  • 内容
    マーカー(自機)を動かし、自分の領域を増やしていく陣取りゲームです。

  • 遊び方
    マーカーは矢印キーで移動し、自分のエリア(濃いアミカケ)内を自由に移動することができます。
    スペースキーを押しながら矢印キーを押すと、自分のエリア外にライン(薄いアミカケ)を引きながら移動することができます。
    再度自分のエリアに戻ってくると、ラインで囲った領域が新たに自分のエリアとなります。
    マーカーが敵に触れたり、作成中のラインに敵が触れるとゲームオーバーです。
    1回のラインで多くのエリアを確保すると得られる得点がアップします。

  • qix
  • 操作方法
    [↑]キー上移動
    [↓]キー下移動
    [←]キー左移動
    [→]キー右移動
    [SPACE]キーラインを引く

    画面の「S」はスコア、「A」は確保したエリア、「T」は残り時間です。

  • プログラムのしくみ
    機械語部分(プログラム1)とBASIC部分(プログラム2)に分かれています。
    機械語ルーチンは、初期画面作成、敵キャラクタの移動、塗りつぶしの3つの処理が含まれています。
    BASICルーチンは、キー入力、マーカー移動、サウンド等の処理をしています。

    変数表
    E,F,G頻出数字
    I,Jループ用一時変数
    A確保領域
    M自分の位置
    N自分の位置に元々あったキャラクタ
    C自分または敵の移動先キャラクタ
    V自分または敵の移動方向
    Q敵の頭の位置
    O敵の尾の位置
    P敵の長さ
    D線描画フラグ
    Kキー入力
    B新たに確保した領域
    Sスコア
    Wウエイト用

    機械語サブルーチン(プログラム1)
    USR(#700,0)
    塗りつぶし
    引数:無し
    戻値:領域数
    USR(#774,0)
    枠描画
    引数:無し
    戻値:無し
    USR(#77C,1)
    敵移動
    引数:上位4bit=キャラクタ(RND(14))+下位4bit=方向(RND(4))
    戻値:FF=GameOver/FE=retry_RND(4)/FD=error/00=no_error

  • プログラムの具体的な入力方法
    プログラム1は機械語プログラムですので、間違えないように入力してください。
    入力間違いがあるとエラーメッセージが出ずに、IchigoJamが操作不能になってしまう可能性があります。
    ですので、プログラムを入力したら、まずSAVEしてからRUNするようにしてください。
    もしIchigoJamが操作不能になってしまった場合は電源を入れ直してください。
    (保存していないプログラムは消えてしまいます)
    また、6行の「END」を、「(例)LRUN2」のようにプログラム2の保存番号に変更すると、プログラム1を実行後すぐにプログラム2を読み込んで実行することができます。
    プログラム1は通常のPOKE文だとメモリ容量を超えてしまうため、BASE16というアルゴリズムで圧縮してあります。
    (正確にはバイナリ→テキスト変換。POKE文を利用したプログラムに対して圧縮の意味)

  • プログラムの改造
    プログラム2のPに4を加えた数が敵の初期の長さになります。長くすると難しくなります。(短くすると正しく動作しません)
    Wは全体の動きを遅くするための数値です。初期値5から1面クリアごとに小さく(=早く)なります。増減させて難易度を変更できます。
    7行の9999は制限時間です。増減させて難易度を変更できます。

  • 91X(プログラム1)
    1 'QIX1
    2 Z="ONKEI@B@@@@ADGAHBNBFCF@AB@BB@ACBKBDBALMLM@EMB@BH@CM@HABHOGMKHNBHOEMLMAAIB@CI@@BC@@O@@JOHAOBC@@O@@GOHBABC@@O@@DOHD@BC@@O@@AOHNFNGLHEL@@BH@@M@G@DGB@B@LHEDMNNG@@B@":Y=#700:GSB8
    3 Z="B@BBB@BDMAEM@KAK@GM@@CBI@CM@@DBI@AM@@@BI@BMA@AC@@CBCMCEE@ACBKBDBO@MKONKMONKD@FB@I@BGCO@AGOAHKNBFCF@AGFAHB@BB@ACJM@EEI@EEOKMACMDFAOCEFNALBLBBAB@AE@EEI@EEB@CJOKME":Y=#750:GSB8
    4 Z="@CB@GNALBABALHEEHHEEB@CALHEEHHEEONKLG@DG@@KE@BKD@ODF@HBFCF@BOLCFCNDDKEAL@B@II@DF@CBBA@D@@@BBJLEJB@CLCLDDDAAN@FM@AOBA@BBH@CM@BABA@CBH@@M@D@BAOOB@FBEL@DBJ@FMAHOBB":Y=#7A0:GSB8
    5 Z="FBEDDBDFHACBB@BAFBEDDAN@ONB@@@BJCNMAFCAHB@CK@@BA@@O@CMOH@@BHCGMAAOBA@@O@CHOH@@BHCBMABABA@@O@CCOH@@BHBMMAD@BA@@O@BNOH@@BHBHMADADFHACAB@CDBAG@B@CCMKAK@@BBJKEBKCEJ":Y=#7F0:GSB8
    6 Z="CKDDB@CK@@BA@@O@ANOH@@BHA@MAAOBA@@O@AIOH@@BH@KMABABA@@O@ADOH@@BH@FMAD@BA@@O@@OOH@@BH@AMAOMB@@GN@@@B@AJDFB@CBA@G@@KDDMKAK@@BBKCEB@BKL@@KMG@DG@@B@EJELH@BJ@BMMHOBJ":Y=#840:GSB8
    7 Z="@@MJONB@G@DG":Y=#890:GSB8:END
    8 W=Y+LEN(Z)/2-1:FORX=YTOW:POKEX,PEEK(Z)&15<<4+PEEK(Z+1)&15:Z=Z+2:NEXT:RTN
    

    91X(プログラム2)
    1 'QIX2
    '全体初期設定
    2 E=143:F=32:G=23:s=0:p=0:W=5
    '面初期設定
    3 CLS:A=USR(#774,0):A=0:LC21,G:?"T:";:M=#921:N=3:V=1:P=P+4:W=W-1:PLAY"T700EREDRDRDE2REFRFGR0R0"
    'QIX配置
    4 Z=#9A0+RND(512):IFPEEK(Z)GOTO4ELSEPOKEZ,134:Y=Z:FORI=0TOP:Y=Y+V:IFY<#960Y=Y+F:V=1:I=I-1ELSEIFPEEK(Y)Y=Y+31:IFPEEK(Y)Y=Y-33:IFPEEK(Y)Y=Y+1:V=-F:I=I-1
    5 POKEY,134:NEXT:CLT:C=3:N=4:V=0:wait120:GOTOG
    'QIX移動
    6 J=J+1:IFJ>9J=Y:Y=Z:Z=J:J=0:POKEZ,E:GOTO6
    7 a=usr(#7B4,rnd(14)<<4+rnd(4)):IFa=#FF||TICK()>9999POKEZ+V,E:POKEZ,E:GOTOFelseifa=#FEgoto6
    10 J=0:LCG,G:?9999-TICK();:WAITW
    '自移動
    11 V=0:D=0:K=PEEK(#1002):IF!KGOTO6ELSEIFK&16D=1
    12 IFK&1V=-1ELSEIFK&2V=1ELSEIFK&4V=-FELSEIFK&8V=F
    13 C=PEEK(M+V):IFD&&(C>128&&C74LC12,10:?" CLEAR ";:play"t999erer9grgr9brb":WAITE:GOTO3
    24 IFC=3POKEM,N:M=M+V:N=PEEK(M):POKEM,42
    25 IF!C&&DPOKEM,N:M=M+V:N=4:POKEM,42
    26 GOTO6
    32 lc9,9:?"GAME OVER":play"t500fr9fgfrfgedc":LC0,0:OK
    

    91X(プログラム1のアセンブラリスト)
    '塗りつぶし	引数:無し/戻値:領域数
    push	{r1-r7,LR}
    mov	r0,#90
    lsl	r0,r0,4		'仮想LC0,0(#900)
    add	r7,r0,r1	'R7=実VRAM
    mov	r6,#2E		'#BE0-#900=#2E0
    lsl	r6,r6,4		'R6=仮想LC0,23(#BE0)
    @VRAMTOP		'敵側塗りつぶし(#20)	R2=カウンタ
    mov	r2,#20					
    @LOOP1			'敵側探索
    add	r2,1
    cmp	r2,r6
    bgt	@FILL		'塗りつぶし
    ldrb	r0,[r2,r7]				
    cmp	r0,#20					
    beq	@LBL1					
    cmp	r0,#81					
    blt	@LOOP1
    cmp	r0,#8E
    bgt	@LOOP1
    @LBL1			'!= ,!=O,!=o
    add	r1,r2,r7
    sub	r1,#20		'R1=チェックVRAM
    mov	r3,#00		'R3=R1の上
    gosub	@CHKNULL				
    mov	r3,#1F		'R3=R1の左
    gosub	@CHKNULL			
    mov	r3,#21		'R3=R1の右
    gosub	@CHKNULL				
    mov	r3,#40		'R3=R1の下
    gosub	@CHKNULL				
    bla	@LOOP1					
    @CHKNULL
    ldrb	r0,[r1,r3]
    cmp	r0,#00
    beq	@PUTSPC
    ret
    @PUTSPC
    mov	r0,#20		'R0=CHR$(#20)=SPACE
    strb	r0,[r1,r3]
    bla	@VRAMTOP
    @FILL			'自領域塗りつぶし(#00)
    mov	r0,#00		'R0=領域数(戻値)
    mov	r2,#20		'R2=カウンタ
    mov	r4,#20
    @LOOP2
    ldrb	r1,[r2,r7]				
    sub	r3,r1,r4
    beq	@LBL3					
    cmp	r1,#03
    beq	@LBL2
    cmp	r1,#04
    beq	@LBL2
    cmp	r1,#00
    bne	@LBL4
    @LBL2
    add	r0,#01					
    mov	r3,#03
    @LBL3
    strb	r3,[r2,r7]				
    @LBL4
    add	r2,1
    cmp	r2,r6					
    blt	@LOOP2					
    pop	{r1-r7,PC}
    
    'nop
    'nop
    
    '--枠描画
    '枠	引数:無し/戻値:無し
    push	{r1-r7}
    mov	r0,#0,6
    mov	r7,#90
    lsl	r7,r7,4		'仮想LC0,0(#900)
    add	r7,r7,r1	'R7=実LC0,0
    mov	r6,#BE
    lsl	r6,r6,4		'仮想LC0,23(#BE0)
    add	r6,r6,r1	'R6=実LC0,23
    mov	r2,#20		'R2=カウンタ
    @KABELOOP1
    sub	r2,#01
    strb	r0,[r2,r7]	'上枠
    strb	r0,[r2,r6]	'下枠
    bne	@KABELOOP1
    mov	r5,r7
    add	r5,#1F		'#91F
    add	r6,r5,1		'#920
    mov	r2,#2C		'R2=カウンタ(#2C0)
    lsl	r2,r2,4
    @KABELOOP2
    strb	r0,[r2,r5]	'右枠
    strb	r0,[r2,r6]	'左枠
    sub	r2,#20
    bpl	@KABELOOP2	'r2>#00(=r2+r5>#900)
    mov	r0,#03
    add	r6,r7,#01
    mov	r1,#21
    strb	r0,[r1,r7]
    strb	r0,[r1,r6]
    add	r1,#20
    strb	r0,[r1,r7]
    'mov	r0,#2A		'#2A="*"
    strb	r0,[r1,r6]
    pop	{r1-r7}
    ret
    
    'nop
    'nop
    
    '--QIX移動
    '使用変数:q,o
    '引数(R0)	上位4bit=キャラクタ(RND(14))
    '		下位4bit=方向(RND(4))
    '戻値(R0)	FF=GameOver/FE=retry_RND(4)/FD=error/00=no error
    push	{LR}
    push	{r1-r10}
    mov	r7,r1		'R7=実VRAM先頭アドレス
    mov	r6,#08
    lsl	r6,r6,#08
    add	r6,#FC
    add	r6,r7		'R6=#8FC=Y(=o)
    add	r5,r6,#02	'R5=#8FE=Z(=q)
    lsr	r2,r0,#04
    mov	r8,r2		'R8=キャラクタ(RND(14))
    mov	r2,#03
    and	r0,r2
    'mov	r9,r0		'R9=方向(RND(4))
    mov	r2,#00
    ldrh	r4,[r5,r2]	
    sub	r4,#20		
    add	r4,r7
    sub	r1,r0,#1	'RND=1	上
    beq	@Q_EAT		'R1=0
    mov	r1,#1F
    cmp	r0,#02		'RND=2	左
    beq	@Q_EAT		'R1=31
    mov	r1,#21
    cmp	r0,#03		'RND=3	右
    beq	@Q_EAT		'R1=33
    mov	r1,#40		'R1=64 RND=0	下
    @Q_EAT
    mov	r0,#FF
    ldrb	r2,[r4,r1]	'R2=Q+V
    cmp	r2,#04
    bne	@Q_NL_CK		
    mov	r2,#8F
    strb	r2,[r4,r1]		
    mov	r2,r8
    add	r2,#81
    mov	r1,#20
    strb	r2,[r4,r1]		
    bla	@Q_EXIT
    
    @Q_NL_CK
    mov	r0,#FE
    cmp	r2,#00
    bne	@Q_EXIT			
    add	r3,r4,r1
    sub	r3,#20		
    mov	r1,#00
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_EXIT
    mov	r1,#1F
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_EXIT
    mov	r1,#21
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_EXIT
    mov	r1,#40
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_EXIT
    mov	r1,r8		'R8=キャラクタ(RND(14))
    add	r1,#81
    add	r4,#20
    strb	r1,[r4,#00]		
    add	r3,#20		
    sub	r3,r3,r7
    mov	r2,#00
    strh	r3,[r5,r2]		
    
    ldrh	r3,[r6,r2]		
    add	r3,r7
    sub	r3,#20		
    
    mov	r1,#00
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_TAIL
    mov	r1,#1F
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_TAIL
    mov	r1,#21
    gosub	@Q_CHECK	
    cmp	r0,#00
    bne	@Q_TAIL
    mov	r1,#40
    gosub	@Q_CHECK
    cmp	r0,#00
    bne	@Q_TAIL
    mov	r0,#FD		'error
    BLA	@Q_EXIT
    @Q_TAIL
    mov	r0,#00
    mov	r2,r3
    add	r2,#20
    strb	r0,[r2,#00]	
    add	r3,r1
    sub	r3,r3,r7
    mov	r2,#00
    strh	r3,[r6,r2]	'O=O+[I]
    @Q_EXIT
    pop	{r1-r10}
    pop	{PC}
    ret
    'sub
    @Q_CHECK
    mov	r0,#00
    ldrb	r2,[r3,r1]	'R2=Q+V-r1	
    cmp	r2,#80
    ble	@Q_CHK_RET		
    cmp	r2,#8F
    bge	@Q_CHK_RET		
    mov	r0,#FE		'rnd(4) retry
    @Q_CHK_RET
    ret
    


    MixJuiceでのダウンロードURLは下記になります。
    91x(1) http://tagiyasoft.blog.jp/91x1.bin
    91x(2) http://tagiyasoft.blog.jp/91x2.bin

    以下のように入力してD/Lしてください。
    NEW
    ? MJ GET http://tagiyasoft.blog.jp/91x1.bin
    ? MJ GET http://tagiyasoft.blog.jp/91x2.bin
    

    ブラウザでD/LしてIchigoJamに転送する場合は、通信ソフトでバイナリ送信をしてください。
    (例:TeraTermの場合は、メニューの[ファイル]-[ファイル送信]で当該ファイルを送信します)

  • 参考ゲーム
    QIX