IchigoJam定番プログラムの「かわくだりゲーム」が宇宙に飛び立ちました。

キミは天の川を、小惑星に当たらずに何光年進むことができるか?

asteroidbelt はるか遠方より小惑星が近づいてきます。
(天の川を一点透視図法で表現しています。)
ぶつからないよう矢印キーで避けてください。
宇宙空間なので慣性の法則により、宇宙船は同じ方向に動き続けるので注意。


10 'アマノガワクダリ ゲーム
20 CLS:CLV:CLT:X=16
30 FOR I= 0 TO 14
40 LC 14-I,I+8:?"/":LC 16+I,I+8:?"\";
50 NEXT
60 [0]=RND(30)+1
70 FOR I= 16 TO 1 STEP -1
80 IF [I] THEN LC ([I]-16)*I/16+15,7+I:?" ";
90 [I]=[I-1]
100 IF [I] THEN LC ([I]-16)*I/16+15,7+I:?".";
110 NEXT
120 IF SCR(X,23)=46 THEN LC X,23:? CHR$(244):LC 0,0:?"ダッシュツ キョリ=";TICK();"コウネン":END
130 K=INKEY()
140 IF K THEN W=(K=RIGHT)-(K=LEFT):IF W THEN V=W
150 LC X,23:?" ";
160 X=X+V
170 IF X<0  X=0
180 IF X>30 X=30
190 LC X,23:?CHR$(240);
200 GOTO 60

*入力時の注意
コピー&ペーストで入力する時は「\」および、全角カナを半角に変更してください。

  • タイトル
    MatchBit

  • 開発環境
    IchigoJamBASIC1.2.1
    IchigoLatte1.0.1

  • 内容
    マイコンが決めた1と0の並びを30秒の制限時間以内に当てるゲームです。
    クリアすると1桁ずつ増えていきます。

  • MatchBit
  • 遊び方
    「START!」の表示の後、キーを入力していきます。
    入力された数字(0または1)は回答欄の右端に入り、それまであった並びは1桁ずつ左にずれます。一番左にあった数字は削除されます。(これを左シフトと言います)
    マイコンが決めた数字と一致すればレベルクリアで、かかったタイムと積算時間が表示されます。

  • 操作方法
    RUNすると「Ready?」と表示され、カウントダウンが始まります。
    「START!」の表示で入力開始。
    どのキーを押してもOKです。("Esc"を除く)
    入力されたキーのアスキーコードが奇数なら1、偶数なら0が入力されます。

  • プログラムの具体的な入力方法
    左にJavaScript、右にBASICのプログラムが書かれています。
    IchigoLatteの場合は左のプログラムを、IchigoJamの場合は右のプログラムを入力してください。

  • プログラムについて
    プログラムは、IchigoJamのBASICから、IchigoLatteのJavaScriptへステップアップするための参考プログラムとして、あえて各命令が対になるように書いてあります。
    また、IchigoLatteに無い「BIN$」命令は新たに作成しています。

    各処理の内容は下記の通りです。

  • 各行の処理
    JavaScriptBASIC処理内容
    init()30 @I:'init変数設定
    readyGo()90 @R:'ready_goカウントダウン
    bin() BIN$()
    key() 260 @K:'key キー入力、一致確認、タイムアウト
    disp()400 @D:'disp結果表示
    match()460 @O:'match 一致した場合の表示
    gameOvr()540 @E:'game overゲームオーバー表示
    main()620 @M:'mainメイン処理


  • BASICからJavaScriptへステップアップのコツ
    BASICからJavaScriptへステップアップする際、最初に戸惑うのは「GOTO」命令が無いことと思います。
    「GOTO」を使わないプログラムを書くためには、プログラムの設計段階から考えなくてはなりません。

    まずBASICのプログラムリストを見てください。
    全ての処理が小さなサブルーチンになっていて、それらはほとんどがメイン処理(main以後)から呼び出されています。
    BASICではこの様な書き方はあまり見られないと思いますが(構造化BASICを除く)、これような書き方をすると「GOTO」をできるだけ使わない書き方ができます。

    今回作ったJavaScriptのプログラムでは「GOTO」を使う代わりに、「while」で行を戻る、「if」や「break」で行を飛ばす、「return()」で処理を飛ばす、といった手法を使っています。

    今日広く使われているプログラミング言語の多くは「GOTO」命令の使用を推奨していません。(これについては色々な意見はあります)
    「GOTO」を使わない処理の流れを考えるクセをつけておくと、JavaScript以外の言語を習得する際にも役に立ちます。

    なお、今回はBASICとJavaScriptの比較をテーマにしましたので、全ての変数がグローバル変数になっています。
    実際にJavaScriptでプログラムする場合は、関数の返り値やローカル変数を多用します。
    JavaScriptでのプログラムに慣れてきたら、変数のスコープも考えてプログラムを設計するようにしましょう。

    以上、簡単ではありますが上記プログラムがJavaScript学習の一助になれば幸いです。


  • MachBit
    JavaScriptBASIC
    //MachBit
    
    var l=0, n, t, u=0, r, s=0, x, y;
    
    function init(){
     l=l+1;
     x=0;
     n=1<<(l+1);
     y=rnd(n);
    }
    
    function readyGo(){
     var i=0;
     cls();
     log("LEVEL = ",l);
     lc(0,5);
     i=0;
     while(i<=l){
      log("?");
      i=i+1;
     }
     lc(0,2);
     log("Ready?");
     i=0;
     while(i<=4){
      lc(0,3);
      log(5-i);
      sleep(1000);
      i=i+1;
     }
     lc(0,3);
     log("START!\n\n");
    }
    
    function bin(b,d){
     while(d>0){
      log(((1<<(d-1))&b)!=0);
      d=d-1;
     }
    }
    
    function key(){
     var k;
     while(x!=y){
      k=0;
      while(!k){
       k=inkey();
       lc(20,6);
       log((30000-tick()+t)/1000," ");
       if(tick()-t>30000){
        return(0);
       }
      }
      k=k%2;
      x=(x<<1)+k;
      x=x&(n-1);
      lc(0,6);
      bin(x,l+1);
     }
     return(1);
    }
    
    function disp(){
     lc(0,5);
     bin(y,l+1);
     lc(0,11);
     log("Your Level = ",l,"\n");
     log("Your time  = ",u/1000,"sec\n");
     log("Total time = ",s/1000,"sec\n");
    }
    
    function match(){
     u=tick()-t;
     s=s+u;
     log("\n\nMATCH BIT!");
     disp();
     log("\nHIT [enter] key then next level");
     while(inkey()!=10){}
    }
    
    function gameOvr(){
     log("\ntime out");
     disp();
     lc(13,11);
     log(l-1);
     lc(0,15);
     log("GAME OVER\n");
    }
    
    function main(){
    
     while(1){
      init();
      readyGo();
      t=tick();
      if(!key()){
       break;
      }
      match();
     }
     gameOvr();
    }
    
    main();
    
    10 'MachBit
    20 GOTO@M
    
    
    30 @I:'init
    40 L=L+1
    50 X=0
    60 N=1<<(L+1)
    70 Y=RND(N)
    80 RTN
    
    90 @R:'ready_go
    
    100 CLS
    110 ?"LEVEL = ";L
    120 LC0,5
    
    130 FORI=0TOL
    140 ?"?";
    
    150 NEXT
    160 LC0,2
    170 ?"Ready?"
    
    180 FORI=0TO4
    190 LC0,3
    200 ?5-I
    210 WAIT60
    
    220 NEXT
    230 LC0,3
    240 ?"START!"
    250 RTN
    
    'BIN$(b,d)
    
    
    
    
    
    
    260 @K:'key
    
    
    
    
    270 K=INKEY()
    280 LC20,6
    290 ?(1800-TICK())/60;" "
    
    
    300 IFTICK()>1800R=0:RTN
    310 IF!KGOTO@K
    320 K=K%2
    330 X=(X<<1)+K
    340 X=X&(N-1)
    350 LC0,6
    360 ?BIN$(X,L+1)
    370 IFX!=YGOTO@K
    380 R=1
    390 RTN
    
    400 @D:'disp
    
    410 LC0,5:?BIN$(Y,L+1)
    
    420 LC0,11:?"Your Level = ";L
    430 ?"Your time  = ";U/60;"sec"
    440 ?"Total time = ";S/60;"sec"
    450 RTN
    
    460 @O:'match
    470 U=TICK()-T
    480 S=S+U
    490 ?:?:?"MATCH BIT!"
    500 GSB@D:'disp
    510 ?:?"HIT [enter] key then next level"
    520 @W:IFINKEY()!=10GOTO@W
    530 RTN
    
    540 @E:'game over
    550 ?:?"time out"
    560 GSB@D:'disp
    570 LC13,11
    580 ?L-1
    590 LC0,15
    600 ?"GAME OVER"
    610 RTN
    
    620 @M:'main
    630 CLV
    640 @L:'loop
    650 GSB@I:'init
    660 GSB@R:'ready_go
    670 CLT:T=TICK()
    680 GSB@K:'key
    
    
    
    690 IFRGSB@O:GOTO@L:'match:'loop
    700 GSB@E:'end
    710 END
    
    
    

    ダウンロードURLは下記になります。
    MachBit(JavaScript)  http://tagiyasoft.blog.jp/machbit_J.bin
    MachBit(BASIC)  http://tagiyasoft.blog.jp/machbit_B.bin


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

  • 参考ゲーム
    初歩のラジオ 1979年7月号  金庫破りゲーム「ルパン」

  • タイトル
    MissileDefense (電子工作マガジン2017年SUMMER号掲載)

  • 開発環境
    IchigoJamBASIC1.2.1

  • 内容
    敵国によるICBM発射の兆候をつかんだ我が軍は、ミサイル防衛システムを配備した。
    ICBMが本土上に着弾する前にそれらを撃墜し、我が国を守らなければならない。

  • MissileDefense
  • 遊び方
    RUNすると少し時間を置いて、上空からミサイルが軌跡を描きながら落下してきます。
    画面上の照準「+」を操作し、照準の位置に迎撃弾を発射することができます。
    迎撃弾を発射すると爆炎が発生し、爆炎にミサイルを突入させることでミサイルを撃破できます。
    迎撃弾は一度に3個までしか発射することができません。
    1発でもミサイルが地表に着弾してしまったらゲームオーバーです。

    迎撃した時の画面上の爆炎の数が1つの場合は15点、2つは10点、3つは5点です。
    2つのミサイルを同時に破壊した時は、さらに10点追加です。

  • 操作方法
    [↑]キー 上移動
     [↓]キー 下移動
    [←]キー 左移動
    [→]キー 右移動
    [スペース]キー 迎撃弾発射

    2つのキーを同時に押して斜めに移動することもできます。

  • プログラムのしくみ

    変数表(プログラム2)
    [0]~[3]ミサイル1の構造体:[0]発生フラグ,[1]長さ,[2]始点のX座標,[3]終点のX座標
    [4]~[15]ミサイル2~3の構造体:内容はミサイル1と同じ
    [30]~[32]爆炎1~3の位置
    [33]~[35]爆炎1~3の大きさ
    Sスコア
    Rスコアの加算値
    I,Jループ用
    N,M爆炎用一時変数
    Kキー入力値
    V照準移動方向
    T照準の位置
    U自機のX座標
    Lミサイル用インデックス
    Cミサイルのキャラクタ
    Yミサイル描画Y座標

    各行の処理(プログラム2)
    1行コメント(ファイル名)
    2行初期化
    3行タイマ
    4~9行爆炎処理
    10~14行ミサイル処理
    15~22行キー入力処理
    23~24行ミサイルの軌跡描画

  • プログラムの具体的な入力方法
    プログラム1は機械語サブルーチンになっていますので、間違えないように入力してください。 入力間違いがあるとエラーメッセージが出ずに、IchigoJamが操作不能になってしまう可能性があります。 ですので、プログラムを入力したら、まずSAVEしてからRUNするようにしてください。 もしIchigoJamが操作不能になってしまった場合は電源を入れ直してください。 (保存していないプログラムは消えてしまいます)

  • プログラムの改造
    プログラム2の、3行めの「tick()<50-s /10」は敵ミサイルの速度を設定するタイマーになっており、現在はスコア連動で徐々に早くなるようになっています。
    「s/10」の分母を大きくするとゆっくりになり、逆に小さくすると早くなります。

    敵ミサイルの発生率は10行の「RND(10)」により決まります。
    数値を大きくすると発生率が下がり、数値を小さくすると発生率が上がります。

    このプログラムはIchigoJam-ap(PCアプリケーション版)やIchigoJam-PC(PC_OS版)でも実行することができます。
    ただし、IchigoJam-apやIchigoJam-PCでは機械語を実行することができないのでプログラム1は入力せず、その代わりプログラム2の23~24行をプログラム3のように変更してください。
    全く同じ処理を、プログラム3はBASICで記述、プログラム1は機械語で記述したものです。
    PCのスペックにもよりますが、IchigoJam-apやIchigoJam-PCはBASICの処理でも十分な速度が出ます。
    動作環境によっては照準の移動が速すぎるので、21行の「'」を消してWAIT文が実行されるようにしてください。 WAIT文の数値を変更することで照準の速度を遅くすることができます。

  • MissileDefense(プログラム1)
    10 'MissileCommand1
    20 POKE #700,254,180,140,38,54,1,14,68,144,39,63,1,15,68,0,37
    30 POKE #710,44,34,18,1,243,120,210,24,179,120,210,26,106,67,22,35
    40 POKE #720,91,2,1,36,100,2,0,32,154,66,1,212,210,26,0,25
    50 POKE #730,91,8,100,8,248,209,115,120,180,120,2,25,184,92,3,40
    60 POKE #740,2,209,1,32,157,66,5,208,48,121,184,84,1,53,171,66
    70 POKE #750,222,218,0,32,254,188,112,71
    80 LRUN(プログラム2の保存番号)
    

    MissileDefense(プログラム2)
    1 'MissileCommand2
    2 CLV:CLS:POKE4098,0:U=#50:T=#A10:POKET,43
    3 IFTICK()<50-S/10GOTO15
    4 R=4:FORJ=33TO35:IF![J]GOTO9
    5 [J]=([J]+1)%7:N=ABS([J]*2-7):M=J-3:R=R-1:IFN=7POKE[M]-32,0:POKE[M]-1,0,0,0:POKE[M]+32,0:[M]=0
    6 IFN=5POKE[M]-32,0:POKE[M]-1,0,3,0:POKE[M]+32,0
    7 IFN=3POKE[M]-33,0,3,0:POKE[M]-2,0,3,3,3,0:POKE[M]+31,0,3,0
    8 IFN=1POKE[M]-33,3,3,3:POKE[M]-2,3,3,3,3,3:POKE[M]+31,3,3,3
    9 NEXT:CLT
    10 FORI=0TO3:L=I*4:IF![L]IFRND(10)GOTO13ELSE[L+2]=RND(32):[L+3]=RND(32):[L]=1
    11 C=219:GOSUB23:IF[L]=0C=0:GOSUB23:[L]=0:[L+1]=0:S=S+R:R=R+1
    12 [L+1]=[L+1]+1
    13 LC0,0:?"SCORE ";S*5:IF[L+1]=23LC0,5:?"GAME OVER":END
    14 NEXT
    15 K=PEEK(4098):V=0:IF!KGOTO3
    16 IFK&16FORI=30TO32:IF[I]=TI=32:NEXTELSEIF[I]NEXTELSE[I]=T:[I+3]=1:POKET,3:I=33:NEXT:GOTO3
    17 IFK&1V=V-1
    18 IFK&2V=V+1
    19 IFK&4V=V-32
    20 IFK&8V=V+32
    21 K=T+V:IFK>#91F&&K<#BC0IFVPOKET,0:POKEU,0:T=T+V:U=#BE0+T%32:POKET,43:POKEU,240:'WAIT10
    22 GOTO3
    23 POKE#8C0,[L],[L+1],[L+2],[L+3],C:IFUSR(#700,C)[L]=0
    24 RETURN
    

    MissileDefense(プログラム3)
    23 FORY=0TO[L+1]:P=#900+Y*(704+[L+3]-[L+2])/22+[L+2]:IFPEEK(P)=3&&Y=[L+1][L]=0:Y=22
    24 POKEP,C:NEXT:RETURN
    

    MissileDefense(プログラム1のアセンブラリスト)
    push	{r1-r7}
    mov	r6,#8c
    lsl	r6,r6,4	'r6=#8c0=[l]
    add	r6,r1	'#8c0 実アドレス
    mov	r7,#90
    lsl	r7,r7,4	'r7=#900=VRAM
    add	r7,r1	'VRAM 実アドレス
    mov	r5,0	'y=counter
    @loop1
    mov	r2,#2C
    lsl	r2,r2,4	'r2=#2c0=704=32*22
    ldrb	r3,[r6,3]	'R3=[L+3]
    add	r2,r2,r3
    ldrb	r3,[r6,2]	'R3=[L+2]
    sub	r2,r2,r3
    mul	r2,r5	'R2=y*(704+[L+3]-[L+2])
    '--DIV st--
    mov	r3,#16	'割算	r2/22
    lsl	r3,r3,9	'r3=22*2^4=#160
    mov	r4,#1	'r4=シフト_カウンタ
    lsl	r4,r4,9
    mov	r0,0	'r0=商
    @div_loop
    cmp	r2,r3
    bmi	@div_shift	'jmp r2<r3
    sub	r2,r2,r3
    add	r0,r0,r4
    @div_shift
    lsr	r3,r3,1
    lsr	r4,r4,1
    bne	@div_loop
    '--DIV ed--
    ldrb	r3,[r6,1]	'R3=[L+1]
    ldrb	r4,[r6,2]	'R4=[L+2]
    add	r2,r0,r4	'商+[L+2]
    ldrb	r0,[r7,r2]	'R3=peek(R2)
    cmp	r0,3
    bne	@nohit	'ifpeek(p)=3
    mov	r0,1
    cmp	r5,r3
    beq	@hit	'ify=[L+1]
    @nohit
    ldrb	r0,[r6,4]	'R0=c
    strb	r0,[r7,r2]	'pokeR2,R0
    add	r5,1	'counter ++
    cmp	r3,r5	'R3-R5=[L+1]-counter
    bge	@loop1
    mov	r0,0
    @hit
    pop	{r1-r7}
    ret

    MixJuiceでのダウンロードURLは下記になります。
    MissileDefense(Program1)  http://tagiyasoft.blog.jp/missiledefense1.bin
    MissileDefense(Program2)  http://tagiyasoft.blog.jp/missiledefense2.bin
    MissileDefense(Program3)  http://tagiyasoft.blog.jp/missiledefense3.bin

    以下のように入力してD/Lしてください。
    NEW
    ? MJ GET tagiyasoft.blog.jp/missiledefense1.bin
    ? MJ GET tagiyasoft.blog.jp/missiledefense2.bin
    

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

  • 参考ゲーム
    ミサイルコマンド

↑このページのトップヘ