SHIROのIchigoJam日記

マイコン「IchigoJam」(イチゴジャム)の電子工作とプログラミングをメインに

IchigoTrek-4K

IchigoJamのICを大容量版に変えた「IchigoJam拡張版」が試用できるようになっています。
私も以前いただいたIC基板(ICはLPC1115/303)が手元にあったので、試してみました。
プログラムメモリが1KB→4KB、配列変数の個数が102個→614個に拡大します。
IchigoJamもついに4Kだ!(メモリが)

※その後、4K+PanCake環境が使えるボード「IchigoCake BASIC」が発売されました。
hello002.stores.jp

この環境を活かしたプログラムとして、昔懐かしいスタートレック風ゲーム「IchigoTrek-4K」を作ってみました。
(今は著作権が厳しいので、いろいろ名前を変えました)

遊び方

  • あなたは宇宙船Ichigo-1(イチゴ1号)の船長です。あなたに与えられたミッションは、指定された年限内に全宇宙のエイリアンを破壊することです。
  • 宇宙は8×8のクォドラント(星域)に分かれており、クォドラント内は8×8のセクター(区域)に分かれています。
  • Ichigo-1の機器・コマンドは以下のとおりです。
    • ロングレンジセンサー(Long Range Sensor)
      • 全宇宙のクォドラント情報を表示します。3桁の数字は、1桁目がエイリアン数、2桁目が基地の数(全宇宙で3カ所)、3桁目が星の数です。なお、Ichigo-1が既に訪問したクォドラント、および隣接したクォドラントの情報しか表示されません。
    • ショートレンジセンサー(Short Range Sensor)
      • Ichigo-1がいるクォドラント内のセクター情報が表示されます。イチゴマークがIchigo-1、エイリアンマークがエイリアン、「*」は星、「B」は基地です。
    • 1:ワープエンジン(Warp Engine):所要時間1年
      • 他のクォドラントへワープ航法で移動します。行き先のクォドラントを(X,Y)座標(それぞれ1〜8)で指定します。宇宙の外へは移動できません。
    • 2:インパルスエンジン(Impulse Engine):所要時間0.3年
      • 他のセクターへ通常航法で移動します。行き先のセクターを(X,Y)座標(それぞれ1〜8)で指定します。座標にマイナスの値、あるいは9以上の値を入れると、隣接するクォドラントへ移動できます。
    • 3:フェイザー砲(Phaser Cannon):所要時間0.1年
      • クォドラント内のエイリアンや星に対して、エネルギーを放射して攻撃します。投入するエネルギー量を入力します。対象が複数ある場合は、エネルギーが等配分されます。エイリアンは80〜120ポイント以上(ランダム)、星は100ポイント以上をぶつければ破壊できます。基地は攻撃対象になりません。
    • 4:光子魚雷(Photon Torpedo):所要時間0.1年
      • クォドラント内のエイリアンや星に対して、魚雷で攻撃します。目標のセクターを(X,Y)座標(それぞれ1〜8)で指定します。初期保有数は5発で、発射すると1発ずつ減ります。基地は攻撃対象になりません。
    • 5:ウェイト(Wait):所要時間0.5年
      • 何もせずに0.5年待ちます。故障した機器の回復を待ちたい時などに使います。この機能は故障しません。
  • エイリアンの攻撃、機器故障、回復
    • クォドラント内にエイリアンがいる場合は、攻撃を受けてエネルギーを消耗します。
      その際に機器が故障して使えなくなることがあります。故障した機器は時間が経つと回復します。
      基地に入港する(隣接したセクターに移動する)と、全ての機器が修理され、エネルギーや光子魚雷もフル充填されます。
      なお、たまにMr.Fukunoが現れて、故障した機器をすぐに直してくれることがあります(^_^)
  • 終了条件
    • 指定された年限(Years)が0になるまでに、エイリアンを全て破壊すればミッションクリアです。破壊したエイリアン数と残り年数に応じて、評価スコアが表示されます。
      年限を過ぎてしまったり、途中でエネルギーが0以下になってしまうとゲームオーバーです。
  • その他
    • 時により宇宙嵐(Space storm)が発生して、機器が損傷することがあります。
    • ワープエンジン・インパルスエンジン・フェイザー砲・光子魚雷のパラメータ入力時に「0」を入力すると、キャンセルとなってコマンド入力に戻ります。時間やエネルギーも消費しません。

私が初めて「スタートレック」ゲームを遊んだのは、PC-8001の16KB版でした。
メモリ4KBでどうかと思ったのですが、8割方の機能を載せられました。
私は作りながらつい熱中して遊んでしまいましたが、今時の子ども達はこうした古典的なゲームを面白いと思ってくれるかな?

プログラムリスト

(9/22修正)フェイザー砲のエネルギー計算のバグを修正、宇宙嵐を追加、光子魚雷の最大数を5発にするなどゲームバランスの調整、画面表示の調整・ゲーム進行の高速化
(9/25修正)表示のバグ修正

1 '*IchigoTrek-4K
2 CLV:CLS:A=20+RND(8):Z=(A+3+RND(6))*10
3 FORI=1TO3:GSB26:[J]=[J]+16:NEXT:J=J-64:R=J/8:Q=J-R*8:GSB29
4 FORI=1TOA:GSB26:[J]=[J]+256:NEXT:FORJ=64TO127:[J]=[J]+RND(6):NEXT
5 FORC=48TO57:FORB=0TO7:POKE(C+192)*8+B,~PEEK(C*8+B):NEXT:NEXT
6 [130]="Long Range Sensor":[131]=16:[134]=44
7 [135]="Short Range Sensor":[136]=17:[139]=47
8 [140]="Warp Engine":[141]=10:[142]=10:[144]=66
9 [145]="Impulse Engine":[146]=13:[147]=3:[149]=69
10 [150]="Phaser Cannon":[151]=12:[152]=1:[154]=79
11 [155]="Photon Torpedo":[156]=13:[157]=1:[159]=88
12 [160]="Wait":[161]=3:[162]=5:[164]=95
13 [128]=A:E=3000:T=5:GSB33:GSB27
14 GSB28:?">Command=";:INPUTC:IFC<1ORC>5CONT
15 D=C+2:IF[128+D*5]>0GSB107:GOTO14
16 BEEP:?"---";:GSB42:?"---"
17 GSB[129+D*5]:IF!CGOTO14
18 W=[127+D*5]:Z=Z-W:GSB28
19 IFA<=0GOTO23
20 IFE<=0ORZ<=0GOTO25
21 GSB108:GSB102:GSB114
22 GOTO14
23 GSB117:?"### Mission completed!! ###"
24 S=[128]*Z/10*Z:?"Your Score=";S:END
25 GSB116:?"* Mission failed *":END
26 J=64+RND(64):IF[J]&16CONT ELSERTN
27 GSB44:GSB47
28 GSB50:WAIT99:POKE#B40,0:COPY#B41,#B40,191:LC0,18:RTN
29 FORI=-1TO1:FORJ=-1TO1:M=Q+I:IFM<0||M>7GOTO32
30 N=R+J:IFN<0||N>7GOTO32
31 K=M+N*8+64:[K]=[K]|4096
32 NEXT:NEXT:RTN
33 FORI=0TO63:[I]=46:NEXT
34 S=Q+R*8+64:L=[S]&#F00/256:K=237:IFLGSB39
35 L=[S]&#F0/16:K=66:IFLGSB39
36 L=[S]&15:K=42:IFLGSB39
37 X=RND(8):Y=RND(8):IF[X+Y*8]<>46GOTO37
38 RTN
39 FORI=1TOL
40 J=RND(64):IF[J]<>46GOTO40
41 [J]=K:NEXT:RTN
42 J=125+D*5:K=[J]:L=[J+1]:GSB43:RTN
43 FORI=0TOL:?CHR$(PEEK(K+I));:NEXT:RTN
44 LC0,0:FORK=64TO127:IF[K]&4096&&(![133])?HEX$([K],3);ELSE?"***";
45 ?" ";:NEXT:IF[133]RTN
46 LCQ*4,R:S=Q+R*8:?HEX$([S+64],3):I=#900+S*4:FORJ=0TO2:POKEI+J,PEEK(I+J)+192:NEXT:RTN
47 FORJ=0TO7:LC0,J+9:FORI=0TO7:IF[138]?"*";ELSE?CHR$([I+J*8]);
48 NEXT:NEXT:IF![138]LCX,Y+9:?CHR$(255)
49 RTN
50 LC9,9:?"Quadrant(";Q+1;",";R+1;")"
51 LC9,10:?"Sector  (";X+1;",";Y+1;")"
52 LC9,12:?"Energy =";E;"   "
53 LC9,13:?"Torpedo=";T;" "
54 LC9,15:?"Years  =";Z/10;".";Z%10;" "
55 LC9,16:?"Aliens =";A;" "
56 LC23,9:?"Status--"
57 LC23,10:?" LRS    "
58 LC23,11:?" SRS    "
59 LC23,12:?"1WpE    "
60 LC23,13:?"2IpE    "
61 LC23,14:?"3Psr    "
62 LC23,15:?"4Tpd    "
63 LC23,16:?"5Wit"
64 FORI=1TO6:J=[128+I*5]:IFJLC23,9+I:?"*":LC28,9+I:?J/10;".";J%10
65 NEXT:RTN
66 GSB96:IF!CRTN
67 E=E-(ABS(Q-U)+ABS(R-V))*50
68 Q=U:R=V:GSB117:GSB29:GSB44:GSB33:GSB47:GSB74:RTN
69 GSB98:IF!CRTN
70 GSB117:E=E-(ABS(X-U)+ABS(Y-V))*30:X=U:Y=V
71 M=Q-(U<0&&Q>0)+(U>7&&Q<7):N=R-(V<0&&R>0)+(V>7&&R<7)
72 IFQ<>M||R<>NQ=M:R=N:GSB33:GSB29:GSB44
73 GSB47
74 B=0:FORI=-1TO1:FORJ=-1TO1:U=X+I:IFU<0||U>7GOTO77
75 V=Y+J:IFV<0||V>7GOTO77
76 IF[U+V*8]=66B=1
77 NEXT:NEXT:IF!BRTN
78 GSB117:E=3000:T=5:FORI=1TO7:[128+I*5]=0:NEXT:GSB27:?"Docked.":RTN
79 ?"Energy=";:INPUTP:IFP<0||P>ECONT
80 IF!PC=0:RTN
81 E=E-P:S=64+Q+R*8:O=[S]&#F00/256+[S]&15:IFOF=P/OELSEF=100
82 FORJ=0TO7:FORI=0TO7:K=I+J*8
83 IF[K]=237&&(80+RND(40)<F)GSB86
84 IF[K]=42&&99<FGSB87
85 NEXT:NEXT:GSB47:GSB44:RTN
86 GSB117:?CHR$(237);"destroyed! ";:[K]=46:A=A-1:[S]=[S]-256:RTN
87 GSB117:?"*destroyed! ";:[K]=46:[S]=[S]-1:RTN
88 IF!TC=0:RTN
89 GSB98:IFU<0||U>8||V<0||V>8CONT
90 IF!CRTN
91 T=T-1:K=U+V*8:S=64+Q+R*8
92 IF[K]=237GSB86
93 IF[K]=42GSB87
94 GSB47:GSB44:RTN
95 ?"0.";[162];" year passed.":RTN
96 K="Quadrant":L=7:GSB99:IFU<0||U>8||V<0||V>8CONT
97 RTN
98 K="Sector":L=5:GSB99:RTN
99 ?"For ";:GSB43:?":X(1-8)=";:INPUTU:IF!UC=0:RTN
100 ?"For ";:GSB43:?":Y(1-8)=";:INPUTV:IF!VC=0
101 U=U-1:V=V-1:RTN
102 K=[Q+R*8+64]&#F00/256:IF!KRTN
103 M=0:FORI=1TOK:GSB116:?CHR$(237);"attack! ";:N=RND(100):M=M+N*I:E=E-N:NEXT:GSB28
104 IFRND(200)>MRTN
105 D=RND(6)+1:I=128+D*5:IF[I]CONT
106 [I]=RND(30)+10
107 P=[128+D*5]:GSB116:GSB42:?" is damaged!":?P/10;".";P%10;" year for repair.":GSB27:RTN
108 FORD=1TO7:J=128+D*5:IF![J]GOTO111
109 IF!RND(10)GSB112:GOTO111
110 [J]=[J]-W:IF[J]<=0GSB113
111 NEXT:GSB28:RTN
112 ?CHR$(255);"Mr.Fukuno appeared!"
113 GSB117:[J]=0:GSB42:?" is fixed!":GSB27:RTN
114 IF!RND(20)?"Space storm!":GSB105
115 RTN
116 FORB=1TO10:BEEP30,1:WAIT2:NEXT:RTN
117 FORB=1TO3:BEEP10,2:WAIT7:NEXT:RTN

MixJuiceでもダウンロードできます。
?"MJ GET comich.net/ichigojam/ichigotrek4k.txt"

ソースリスト

IJUtilitiesで変換する前の、ラベルあり・行番号無しのリストです。詳しく中身を知りたい人は参考にしてください。4KB目一杯なので、圧縮されていて読みづらいですが…。

'*IchigoTrek-4K
CLV:CLS:A=20+RND(8):Z=(A+3+RND(6))*10
FORI=1TO3:GSB@RNDB:[J]=[J]+16:NEXT:J=J-64:R=J/8:Q=J-R*8:GSB@VISITQ
FORI=1TOA:GSB@RNDB:[J]=[J]+256:NEXT:FORJ=64TO127:[J]=[J]+RND(6):NEXT
FORC=48TO57:FORB=0TO7:POKE(C+192)*8+B,~PEEK(C*8+B):NEXT:NEXT
[130]="Long Range Sensor":[131]=16:[134]=44
[135]="Short Range Sensor":[136]=17:[139]=47
[140]="Warp Engine":[141]=10:[142]=10:[144]=66
[145]="Impulse Engine":[146]=13:[147]=3:[149]=69
[150]="Phaser Cannon":[151]=12:[152]=1:[154]=79
[155]="Photon Torpedo":[156]=13:[157]=1:[159]=88
[160]="Wait":[161]=3:[162]=5:[164]=95
[128]=A:E=3000:T=5:GSB@SETSEC:GSB@CLC
@GAMELOOP
GSB@CLC1:?">Command=";:INPUTC:IFC<1ORC>5CONT
D=C+2:IF[128+D*5]>0GSB@PRTDMG:GOTO@GAMELOOP
BEEP:?"---";:GSB@PRTD:?"---"
GSB[129+D*5]:IF!CGOTO@GAMELOOP
W=[127+D*5]:Z=Z-W:GSB@CLC1
IFA<=0GOTO@WIN
IFE<=0ORZ<=0GOTO@GOVER
GSB@DMG:GSB@ATA:GSB@STORM
GOTO@GAMELOOP
@WIN
GSB@BEEPP:?"### Mission completed!! ###"
S=[128]*Z/10*Z:?"Your Score=";S:END
@GOVER
GSB@BEEPD:?"* Mission failed *":END
@RNDB
J=64+RND(64):IF[J]&16CONT ELSERTN
@CLC
GSB@LRS:GSB@SRS
@CLC1
GSB@PANEL:WAIT99:POKE#B40,0:COPY#B41,#B40,191:LC0,18:RTN
@VISITQ
FORI=-1TO1:FORJ=-1TO1:M=Q+I:IFM<0||M>7GOTO@VISITQ1
N=R+J:IFN<0||N>7GOTO@VISITQ1
K=M+N*8+64:[K]=[K]|4096
@VISITQ1
NEXT:NEXT:RTN
@SETSEC
FORI=0TO63:[I]=46:NEXT
S=Q+R*8+64:L=[S]&#F00/256:K=237:IFLGSB@SETS
L=[S]&#F0/16:K=66:IFLGSB@SETS
L=[S]&15:K=42:IFLGSB@SETS
@SETSEC1
X=RND(8):Y=RND(8):IF[X+Y*8]<>46GOTO@SETSEC1
RTN
@SETS
FORI=1TOL
@SETS1
J=RND(64):IF[J]<>46GOTO@SETS1
[J]=K:NEXT:RTN
@PRTD
J=125+D*5:K=[J]:L=[J+1]:GSB@PRTSTR:RTN
@PRTSTR
FORI=0TOL:?CHR$(PEEK(K+I));:NEXT:RTN
@LRS
LC0,0:FORK=64TO127:IF[K]&4096&&(![133])?HEX$([K],3);ELSE?"***";
?" ";:NEXT:IF[133]RTN
LCQ*4,R:S=Q+R*8:?HEX$([S+64],3):I=#900+S*4:FORJ=0TO2:POKEI+J,PEEK(I+J)+192:NEXT:RTN
@SRS
FORJ=0TO7:LC0,J+9:FORI=0TO7:IF[138]?"*";ELSE?CHR$([I+J*8]);
NEXT:NEXT:IF![138]LCX,Y+9:?CHR$(255)
RTN
@PANEL
LC9,9:?"Quadrant(";Q+1;",";R+1;")"
LC9,10:?"Sector  (";X+1;",";Y+1;")"
LC9,12:?"Energy =";E;"   "
LC9,13:?"Torpedo=";T;" "
LC9,15:?"Years  =";Z/10;".";Z%10;" "
LC9,16:?"Aliens =";A;" "
LC23,9:?"Status--"
LC23,10:?" LRS    "
LC23,11:?" SRS    "
LC23,12:?"1WpE    "
LC23,13:?"2IpE    "
LC23,14:?"3Psr    "
LC23,15:?"4Tpd    "
LC23,16:?"5Wit"
FORI=1TO6:J=[128+I*5]:IFJLC23,9+I:?"*":LC28,9+I:?J/10;".";J%10
NEXT:RTN
@WPE
GSB@INQ:IF!CRTN
E=E-(ABS(Q-U)+ABS(R-V))*50
Q=U:R=V:GSB@BEEPP:GSB@VISITQ:GSB@LRS:GSB@SETSEC:GSB@SRS:GSB@IPEB:RTN
@IPE
GSB@INS:IF!CRTN
GSB@BEEPP:E=E-(ABS(X-U)+ABS(Y-V))*30:X=U:Y=V
M=Q-(U<0&&Q>0)+(U>7&&Q<7):N=R-(V<0&&R>0)+(V>7&&R<7)
IFQ<>M||R<>NQ=M:R=N:GSB@SETSEC:GSB@VISITQ:GSB@LRS
GSB@SRS
@IPEB
B=0:FORI=-1TO1:FORJ=-1TO1:U=X+I:IFU<0||U>7GOTO@IPEB1
V=Y+J:IFV<0||V>7GOTO@IPEB1
IF[U+V*8]=66B=1
@IPEB1
NEXT:NEXT:IF!BRTN
GSB@BEEPP:E=3000:T=5:FORI=1TO7:[128+I*5]=0:NEXT:GSB@CLC:?"Docked.":RTN
@PSR
?"Energy=";:INPUTP:IFP<0||P>ECONT
IF!PC=0:RTN
E=E-P:S=64+Q+R*8:O=[S]&#F00/256+[S]&15:IFOF=P/OELSEF=100
FORJ=0TO7:FORI=0TO7:K=I+J*8
IF[K]=237&&(80+RND(40)<F)GSB@DESA
IF[K]=42&&99<FGSB@DESS
NEXT:NEXT:GSB@SRS:GSB@LRS:RTN
@DESA
GSB@BEEPP:?CHR$(237);"destroyed! ";:[K]=46:A=A-1:[S]=[S]-256:RTN
@DESS
GSB@BEEPP:?"*destroyed! ";:[K]=46:[S]=[S]-1:RTN
@TPD
IF!TC=0:RTN
GSB@INS:IFU<0||U>8||V<0||V>8CONT
IF!CRTN
T=T-1:K=U+V*8:S=64+Q+R*8
IF[K]=237GSB@DESA
IF[K]=42GSB@DESS
GSB@SRS:GSB@LRS:RTN
@WIT
?"0.";[162];" year passed.":RTN
@INQ
K="Quadrant":L=7:GSB@INXY:IFU<0||U>8||V<0||V>8CONT
RTN
@INS
K="Sector":L=5:GSB@INXY:RTN
@INXY
?"For ";:GSB@PRTSTR:?":X(1-8)=";:INPUTU:IF!UC=0:RTN
?"For ";:GSB@PRTSTR:?":Y(1-8)=";:INPUTV:IF!VC=0
U=U-1:V=V-1:RTN
@ATA
K=[Q+R*8+64]&#F00/256:IF!KRTN
M=0:FORI=1TOK:GSB@BEEPD:?CHR$(237);"attack! ";:N=RND(100):M=M+N*I:E=E-N:NEXT:GSB@CLC1
IFRND(200)>MRTN
@DDMG
D=RND(6)+1:I=128+D*5:IF[I]CONT
[I]=RND(30)+10
@PRTDMG
P=[128+D*5]:GSB@BEEPD:GSB@PRTD:?" is damaged!":?P/10;".";P%10;" year for repair.":GSB@CLC:RTN
@DMG
FORD=1TO7:J=128+D*5:IF![J]GOTO@DMG1
IF!RND(10)GSB@DMGF:GOTO@DMG1
[J]=[J]-W:IF[J]<=0GSB@DMGX
@DMG1
NEXT:GSB@CLC1:RTN
@DMGF
?CHR$(255);"Mr.Fukuno appeared!"
@DMGX
GSB@BEEPP:[J]=0:GSB@PRTD:?" is fixed!":GSB@CLC:RTN
@STORM
IF!RND(20)?"Space storm!":GSB@DDMG
RTN
@BEEPD
FORB=1TO10:BEEP30,1:WAIT2:NEXT:RTN
@BEEPP
FORB=1TO3:BEEP10,2:WAIT7:NEXT:RTN

web版

福野さんがIchigoJam webの拡張版を作ってくれました。
それを使って、IchigoTrek-4Kを遊べる転送ページを作りました。
実機を持っていない人でも遊べます。以下のURLをクリック。
http://comich.net/ichigojam/ichigotrek4k.html

ただ、実行動作が不安定です。(実機でも現状不安定です)
動かない場合は、何度か「import」ボタンを押してください。
また、web版は画面表示が遅いので、センサー表示などで待たされます。