SHIROのIchigoJam日記

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

ラス1ババ抜きゲーム

IchigoJamとMixJuice×2台で通信対戦するババ抜きゲームです。ラスト1枚だけの勝負です(^_^)
MixJuiceで相互通信する簡単なプログラミング教材を想定して作ってみました。

※MixJuiceでのサーバー・クライアント通信設定は、こちらの記事を参照してください。
www.ichigojaman.jp
2台のIchigoJamをTX・RXでつないでシリアル通信でも遊べます。

f:id:shiro0922:20201026144524j:plain

f:id:shiro0922:20201026144444j:plain

遊び方

  • スタート時はサーバー側が「1」のカード、クライアント側が「1」「J」(ジョーカー)の2枚のカードを持っています。
  • サーバー側が先手で、「?」と表示されます。クライアント側の左のカードを引くか、右のカードを引くかを、カーソルキーの左か右を押して選びます。手持ちと同じ「1」のカードを引けば勝ち、ジョーカーを引くと上がれず、クライアント側のターンへ移ります。
  • 今度はクライアント側のターンで、「?」と表示されます。サーバー側の左のカードを引くか、右のカードを引くかを、カーソルキーの左か右で選びます。「1」のカードを引ければ勝ち、ジョーカーを引くと攻守交代です。
  • どちらかのプレイヤーが「1」を引いたら終了します。勝ったプレイヤーは「WIN」、負けたプレイヤーは「LOSE」と表示されます。

※MixJuiceのサーバー→クライアントへのTCP通信が遅いため、一手に5秒ほど待たされることがあります。
f:id:shiro0922:20201026144602j:plain

プログラム

サーバー側(先手)

10 '*BABA1 SERVER
20 CLV:VIDEO 3:UART 0,0
30 @YOU
40 CLS:BEEP:?"1":?
50 ?"?";:CLK
60 K=INKEY():IF K<28 OR K>29 CONT
70 BEEP
80 IF K=28 ?"LEFT"
90 IF K=29 ?"RIGHT"
100 UART 9:?CHR$(K):UART 0,1
110 C=INKEY():IF !C OR C=256 CONT
120 LC 1:?CHR$(C):UART 0,0
130 IF C=49 GOTO @GEND
140 @OPP
150 CLS:BEEP
160 IF RND(2) ?"1J" ELSE ?"J1"
170 ?:?"WAITING...":CLK:UART 0,1
180 K=INKEY():IF K<28 OR K>29 CONT
190 IF K=28 ?"LEFT"
200 IF K=29 ?"RIGHT"
210 C=SCR(K-28,0)
220 UART 9,0:?CHR$(C):UART 0
230 LC K-28:?CHR$(127)
240 WAIT 300:IF C!=49 GOTO @YOU
250 BEEP 30,30
260 LC 0,4:?"***LOSE!***"
270 END
280 @GEND
290 BEEP 10,30
300 LC 0,4:?"***WIN!***"

240行の「WAIT 300」は、MixJuiceのサーバー→クライアントへのTCP通信が遅いため、時間待ちとして入れています。IchigoJam×2台をシリアル接続する時は「WAIT 300」を削除してください。

クライアント側(後手)

10 '*BABA1 CLIENT
20 CLV:VIDEO 3:UART 0,0
30 @OPP
40 CLS:BEEP
50 IF RND(2) ?"1J" ELSE ?"J1"
60 ?:?"WAITING...":CLK:UART 0,1
70 K=INKEY():IF K<28 OR K>29 CONT
80 IF K=28 ?"LEFT"
90 IF K=29 ?"RIGHT"
100 C=SCR(K-28,0)
110 UART 9,0:?CHR$(C):UART 0
120 LC K-28:?CHR$(127)
130 IF C=49 GOTO @GEND
140 @YOU
150 CLS:BEEP:?"1":?
160 ?"?";:CLK
170 K=INKEY():IF K<28 OR K>29 CONT
180 BEEP
190 IF K=28 ?"LEFT"
200 IF K=29 ?"RIGHT"
210 UART 9:?CHR$(K):UART 0,1
220 C=INKEY():IF !C OR C=256 CONT
230 LC 1:?CHR$(C):UART 0,0
240 IF C!=49 GOTO @OPP
250 BEEP 10,30
260 LC 0,4:?"***WIN!***"
270 END
280 @GEND
290 BEEP 30,30
300 LC 0,4:?"***LOSE!***"

十勇士パソコンクラブのサイトで、このプログラムを含むプログラミングテキストを公開しています。
www.white.umic.jp

タイピング30

以前作ったタイピング練習プログラム
www.ichigojaman.jp
をちょっと改造して、BASICコマンドを30問固定で出題するようにしてみました。

f:id:shiro0922:20201002023713p:plain

起動するとBASICコマンドが出題されるので、その通りにタイプしてください。
30問入力すると、タイム(秒)が表示されて終了します。

f:id:shiro0922:20201002023727p:plain

プログラム

100~390行の問題文は自由に変えられるので、「英単語30」「ローマ字30」「カタカナ語30」など、好きなシリーズが作れます。

10 '*TYPING 30 BASIC
20 CLV:CLT:Q=1
30 CLS:?"Q";Q:?
40 GSB 90+Q*10:X=0:BEEP
50 C=SCR(X,2)
60 IF !C IF Q=30 GOTO 90 ELSE Q=Q+1:GOTO 30
70 K=INKEY():IF K!=C CONT
80 ?CHR$(C);:X=X+1:GOTO 50
90 BEEP 10,30:?:?:?"TIME=";TICK()/60:END
100 ?"RUN":RTN
110 ?"LIST":RTN
120 ?"LOAD":RTN
130 ?"SAVE":RTN
140 ?"FILES":RTN
150 ?"NEW":RTN
160 ?"LED 1":RTN
170 ?"PRINT":RTN
180 ?"INPUT":RTN
190 ?"LOCATE":RTN
200 ?"CLS":RTN
210 ?"CLV":RTN
220 ?"IF":RTN
230 ?"THEN":RTN
240 ?"ELSE":RTN
250 ?"FOR I=1 TO 10":RTN
260 ?"NEXT":RTN
270 ?"BEEP":RTN
280 ?"WAIT":RTN
290 ?"END":RTN
300 ?"RETURN":RTN
310 ?"GOTO 120":RTN
320 ?"GOSUB 340":RTN
330 ?"INKEY()":RTN
340 ?"TICK()":RTN
350 ?"RND(10)":RTN
360 ?"SCR(0,0)":RTN
370 ?"BTN(LEFT)":RTN
380 ?"CHR$(1)":RTN
390 ?"X=X+1":RTN

列車30

試しに作ってみました。Ctrl+Shiftでカタカナモードにしてから打ってください。鉄道好きな子が喜ぶかも(^_^)

10 '*TYPING 30 TRAIN
20 CLV:CLT:Q=1
30 CLS:?"Q";Q:?
40 GSB 90+Q*10:X=0:BEEP
50 C=SCR(X,2)
60 IF !C IF Q=30 GOTO 90 ELSE Q=Q+1:GOTO 30
70 K=INKEY():IF K!=C CONT
80 ?CHR$(C);:X=X+1:GOTO 50
90 BEEP 10,30:?:?:?"TIME=";TICK()/60:END
100 ?"ノゾミ":RTN
110 ?"ヒカリ":RTN
120 ?"コダマ":RTN
130 ?"ミズホ":RTN
140 ?"サクラ":RTN
150 ?"ツバメ":RTN
160 ?"ハヤブサ":RTN
170 ?"ハヤテ":RTN
180 ?"ヤマビコ":RTN
190 ?"ナスノ":RTN
200 ?"ツバサ":RTN
210 ?"コマチ":RTN
220 ?"トキ":RTN
230 ?"タニガワ":RTN
240 ?"カガヤキ":RTN
250 ?"ハクタカ":RTN
260 ?"アサマ":RTN
270 ?"ツルギ":RTN
280 ?"アオバ":RTN
290 ?"アサヒ":RTN
300 ?"アサカゼ":RTN
310 ?"アケボノ":RTN
320 ?"フジ":RTN
330 ?"イズモ":RTN
340 ?"セト":RTN
350 ?"ハクツル":RTN
360 ?"ニホンカイ":RTN
370 ?"スイセイ":RTN
380 ?"アカツキ":RTN
390 ?"ホクトセイ":RTN

元素周期表30

高校の化学の範囲ですが、問題番号がそのまま原子番号になっているので、勉強になるかも。

10 '*TYPING 30 PERIODIC TABLE
20 CLV:CLT:Q=1
30 CLS:?"Q";Q:?
40 GSB 90+Q*10:X=0:BEEP
50 C=SCR(X,2)
60 IF !C IF Q=30 GOTO 90 ELSE Q=Q+1:GOTO 30
70 K=INKEY():IF K!=C CONT
80 ?CHR$(C);:X=X+1:GOTO 50
90 BEEP 10,30:?:?:?"TIME=";TICK()/60:END
100 ?"H":RTN
110 ?"He":RTN
120 ?"Li":RTN
130 ?"Be":RTN
140 ?"B":RTN
150 ?"C":RTN
160 ?"N":RTN
170 ?"O":RTN
180 ?"F":RTN
190 ?"Ne":RTN
200 ?"Na":RTN
210 ?"Mg":RTN
220 ?"Al":RTN
230 ?"Si":RTN
240 ?"P":RTN
250 ?"S":RTN
260 ?"Cl":RTN
270 ?"Ar":RTN
280 ?"K":RTN
290 ?"Ca":RTN
300 ?"Sc":RTN
310 ?"Ti":RTN
320 ?"V":RTN
330 ?"Cr":RTN
340 ?"Mn":RTN
350 ?"Fe":RTN
360 ?"Co":RTN
370 ?"Ni":RTN
380 ?"Cu":RTN
390 ?"Zn":RTN

都道府県47

これは地理の勉強になりそうです。何とか1Kバイトに収まりました。

10 '*TYPING 47 TODOFUKEN
20 CLV:CLT:Q=1
30 CLS:?"Q";Q:?
40 GSB 90+Q*10:X=0:BEEP
50 C=SCR(X,2)
60 IF !C IF Q=47 GOTO 90 ELSE Q=Q+1:GOTO 30
70 K=INKEY():IF K!=C CONT
80 ?CHR$(C);:X=X+1:GOTO 50
90 BEEP 10,30:?:?:?"TIME=";TICK()/60:END
100 ?"ホッカイドウ":RTN
110 ?"アオモリ":RTN
120 ?"イワテ":RTN
130 ?"ミヤギ":RTN
140 ?"アキタ":RTN
150 ?"ヤマガタ":RTN
160 ?"フクシマ":RTN
170 ?"イバラキ":RTN
180 ?"トチギ":RTN
190 ?"グンマ":RTN
200 ?"サイタマ":RTN
210 ?"チバ":RTN
220 ?"トウキョウ":RTN
230 ?"カナガワ":RTN
240 ?"ニイガタ":RTN
250 ?"トヤマ":RTN
260 ?"イシカワ":RTN
270 ?"フクイ":RTN
280 ?"ヤマナシ":RTN
290 ?"ナガノ":RTN
300 ?"ギフ":RTN
310 ?"シズオカ":RTN
320 ?"アイチ":RTN
330 ?"ミエ":RTN
340 ?"シガ":RTN
350 ?"キョウト":RTN
360 ?"オオサカ":RTN
370 ?"ヒョウゴ":RTN
380 ?"ナラ":RTN
390 ?"ワカヤマ":RTN
400 ?"トットリ":RTN
410 ?"シマネ":RTN
420 ?"オカヤマ":RTN
430 ?"ヒロシマ":RTN
440 ?"ヤマグチ":RTN
450 ?"トクシマ":RTN
460 ?"カガワ":RTN
470 ?"エヒメ":RTN
480 ?"コウチ":RTN
490 ?"フクオカ":RTN
500 ?"サガ":RTN
510 ?"ナガサキ":RTN
520 ?"クマモト":RTN
530 ?"オオイタ":RTN
540 ?"ミヤザキ":RTN
550 ?"カゴシマ":RTN
560 ?"オキナワ":RTN

三目並べ

子どもの頃に地面やアスファルトに書いて遊んだ人が多いと思う「三目並べ」を作ってみました。
f:id:shiro0922:20200930082917p:plain

遊び方

  • プログラムを動かすと、3×3のます目が表示されます。自分(YOU)かコンピュータ(CPU)か、ランダムにどちらかが先手になります。
  • 自分(YOU)の手の時は、上下左右の矢印キーでカーソルを移動して、スペースキーで打ってください。自分の手は「○」(丸)で表示されます。
  • コンピュータ(CPU)の手の時は、プログラムが自動で考えて手を打ってきます。コンピュータの手は「×」で表示されます。
  • どちらかの手が、縦・横・斜めのどこかで三目そろうと、そのプレイヤーの勝利(WIN)です。どちらもそろわずに9手が終わった場合は引き分け(DRAW)です。

f:id:shiro0922:20200930083451p:plain

f:id:shiro0922:20200930083503p:plain

プログラム

1 '*3MOKU
2 CLV:VIDEO 5:CLS
3 LET [10],7,3,11,3,15,3,11,3,7
4 FOR N=1 TO 3:?"...":NEXT
5 IF RND(2) GOTO 14
6 LC 0,3:?"YOU"
7 X=X-BTN(28)*(X>0)+BTN(29)*(X<2)
8 Y=Y-BTN(30)*(Y>0)+BTN(31)*(Y<2)
9 LC X,Y,1:Z=X+Y*3:WAIT 5
10 IF !BTN(32) OR [Z]!=0 GOTO 7
11 [Z]=1:LC X,Y:?"O":S=S+1:BEEP
12 T=1:GSB 30
13 IF E=3 OR S=9 GOTO 26
14 LC 0,3:?"CPU"
15 G=0:H=0:T=-1
16 FOR Y=0 TO 2
17 FOR X=0 TO 2
18 GSB 30
19 W=[Z+10]+E*E*20+F*F*10
20 IF W>H && [Z]=0 G=Z:H=W
21 NEXT:NEXT
22 Z=G:X=Z%3:Y=Z/3
23 [Z]=-1:LC X,Y:?"X":S=S+1:BEEP 30
24 T=-1:GSB 30
25 IF E!=3 && S!=9 GOTO 6
26 LC 4,3
27 IF E=3 ?"WIN!";:BEEP 10,30
28 IF S=9 ?"DRAW";:BEEP 30,30
29 CLK:END
30 Z=X+Y*3:L=[Z+10]:E=0:F=0
31 FOR M=0 TO 3
32 C=0:D=0
33 IF L&(1<<M) GSB LINE()+4+M*3
34 IF C>E E=C
35 IF D>F F=D
36 NEXT:RTN
37 FOR U=0 TO 2
38 A=[U+Y*3]:GSB 49
39 NEXT:RTN
40 FOR V=0 TO 2
41 A=[X+V*3]:GSB 49
42 NEXT:RTN
43 FOR U=0 TO 2
44 A=[U*4]:GSB 49
45 NEXT:RTN
46 FOR U=0 TO 2
47 A=[2+U*2]:GSB 49
48 NEXT:RTN
49 C=C+(A=T):D=D+(A=-T):RTN

ネットを検索して調べると、「三目並べ」はプログラミングの課題として有名なようで、再帰呼び出しで全ての手(パターン)を調べてコストを計算して…とCPUの最善手を考えるようです。
このプログラムのCPUは、人間と同様に「縦・横・斜めの列の可能性が多い所へ打つ」「自分が3個そろいそうな所へ打つ」「相手が3個そろいそうだったら止める」という思考で、何とか1kバイトに収めました。
CPUもかなり完璧に考えるので、人間が真剣にプレイすると全てのゲームがドローになります。そうか、それでつまらないから、IchigoJamの三目並べのプログラムが今まで無かったんだな…(^_^;)

プログラム説明追記

IJUtilitiesで行番号追加・ラベル削除する前のリストを掲載します。
思考系ゲームを作る方の参考になれば嬉しいです。

'*3MOKU
CLV:VIDEO 5:CLS
LET [10],7,3,11,3,15,3,11,3,7
FOR N=1 TO 3:?"...":NEXT
IF RND(2) GOTO @CPU
@YOU
LC 0,3:?"YOU"
@YLOOP
X=X-BTN(28)*(X>0)+BTN(29)*(X<2)
Y=Y-BTN(30)*(Y>0)+BTN(31)*(Y<2)
LC X,Y,1:Z=X+Y*3:WAIT 5
IF !BTN(32) OR [Z]!=0 GOTO @YLOOP
[Z]=1:LC X,Y:?"O":S=S+1:BEEP
T=1:GSB @CHK
IF E=3 OR S=9 GOTO @GEND
@CPU
LC 0,3:?"CPU"
G=0:H=0:T=-1
FOR Y=0 TO 2
FOR X=0 TO 2
GSB @CHK
W=[Z+10]+E*E*20+F*F*10
IF W>H && [Z]=0 G=Z:H=W
NEXT:NEXT
Z=G:X=Z%3:Y=Z/3
[Z]=-1:LC X,Y:?"X":S=S+1:BEEP 30
T=-1:GSB @CHK
IF E!=3 && S!=9 GOTO @YOU
@GEND
LC 4,3
IF E=3 ?"WIN!";:BEEP 10,30
IF S=9 ?"DRAW";:BEEP 30,30
CLK:END
@CHK
Z=X+Y*3:L=[Z+10]:E=0:F=0
FOR M=0 TO 3
C=0:D=0
IF L&(1<<M) GSB LINE()+4+M*3
IF C>E E=C
IF D>F F=D
NEXT:RTN
@CHKX
FOR U=0 TO 2
A=[U+Y*3]:GSB @CHKT
NEXT:RTN
@CHKY
FOR V=0 TO 2
A=[X+V*3]:GSB @CHKT
NEXT:RTN
@CHKXY
FOR U=0 TO 2
A=[U*4]:GSB @CHKT
NEXT:RTN
@CHKYX
FOR U=0 TO 2
A=[2+U*2]:GSB @CHKT
NEXT:RTN
@CHKT
C=C+(A=T):D=D+(A=-T):RTN

配列変数[0]~[8]で、9個のマスの値を記憶します。(0=打たれていない、1=YOU、-1=CPU)
012
345
678
3行目のLETでの配列値の設定は、各マス目(0~8、添字は+10)の横(X)・縦(Y)・斜め(XY・YX)の列判定方向を表します。それぞれビット0・1・2・3です。
@CPUからの10数行がCPU思考部分です。9マスそれぞれで@CHKからの重み付け計算ルーチンを呼び出し、計算した重みに列判定配列の値も加算。最終的に重みが一番大きいマスへ打ちます。
@CHKからのマス目重み付け計算ルーチンでは、上記の列判定配列値を元に、@CHKX(横)、@CHKY(縦)、@CHKXY・@CHKYX(斜め)のサブルーチンを呼び出し、それぞれの列でYOUの石とCPUの石をカウントして、その最大値を返します。
この@CHK以下のルーチンは、両者の手を打った後の勝利判定にも共用していて、それで何とか1kバイトに収めています。