シンプルでおくぶかい頭脳ゲーム・Ostleを、PBシミュレータに載せました。


Rev.1 2023/8/4 評価値計算、入力制御を改善しました。(赤字)


対応機種

プログラム・サイズは1,566ステップです。PB-100実機+拡張メモリでも動作しますが、時間が掛かる為推奨しません。Pokecom GO(no wait)モードだとサクサク動作します。

Ostleゲームについて

・初期盤面は図の通り。自分の駒は□、相手の駒は■、穴は●です。

・自分の駒は一度に1マス押せます。押すときは相手/自分関係なく何個でも同時に押せます。

・盤の外に相手の駒を押し出すと駒を取れます。

・相手の駒を2個取ると勝利です。

・穴も1マスずつ押せます。

・穴に相手の駒を押し出しても取ることができます。

・ただし、穴が動けるのは空いているマスにだけです。

・一つ前の盤面に戻すのは禁止です。

遊び方

PB-100画面には一度に盤面の1行分しか表示できません。そこで、市販されているOstleボードゲームの実物を手元に準備し、画面表示を移しかえてプレイすることをお勧めします。DAISO版なら¥110で入手できます。

プログラムを入力し、shift+[0]またはP0にてRUN[EXE]すると、スタートです。中断後の再開は、P0にてRUN 6[EXE]です。

Player(あなた)が□、CPUが◆です。先攻はあなた(Playerターン)です。

[2][4][6][8]キーでカーソルを操作し、[5]キーを押して動かしたいPlayer駒□又は穴●を選択します。 次に、動かしたい方向に応じて[2][4][6][8]キーを押すと、駒が移動し、CPUターンに移ります。無効なキー入力の場合は、盤面が再表示され、キー入力がやり直しとなります。CPU思考中はカーソルが消えます。

どちらかの駒が盤外に押し出されたか穴に落ちた場合は、これまでに喪失した駒数が表示されます。

どちらかの駒の喪失が2になると、勝者を表示してゲームオーバーです。

注意

・Ostleの公式ルールにありますが、自分の一手前の盤面に戻すことは禁止されています。これは、双方行き詰った時に、押したり引いたりを永遠に繰り返すと、ゲームが進まなくなるためと思われます。このルールをCPU側は遵守しますが、Player側のチェックはしません。従って、Player自身で気を付けて下さい。(変数があと3つあれば実装できるのですが…)

・CPU思考は時間がかかります。これは、CPUの手全てについて局面評価をするためで、なおかつ盤データを圧縮しているためです。各プラットフォームでの所要時間実測値を参考に示します。

Ostle PB一手の所要時間比較

つぶやき

一手先の局面を評価するところまでは押し込みましたが、「身を切らせて骨を断つ」ような戦略的な思考には及びません。とにかくPB-BASICの変数の少なさに苦労しました。その為に盤面データの圧縮が必要になり、処理時間が長くなる原因となっています。どなたか、目から鱗の上手いアルゴリズムで高速化できませんか? もちろん、PB-BASICフォーマットで!

Ostle PB説明書 R1.pdf
Ostle PB flowchart.pdf
Ostle PB flowchart 2.pdf

ゲームカード。ただし、実機では一手打ったら風呂に入りますw

PB-SIM形式

[P0]

2 VAC:PRINT "Ostle PB"

4 L=682:M=48:N=341

5 D=12:GOTO 76

6 $="_\SQ\DI\BX":PRINT

8 FOR E=0 TO 4

10 V=E+5*INT(D/5:GOSUB #4:PRINT MID(W+1,1);:NEXT E

12 IF C=0 THEN 52

14 PRINT CSR1.1+5*FRAC(D/5);"<";CSR6;INT(D/5);

16 IF KEY<>"" THEN 16

18 $=KEY:IF $="" THEN 18

20 E=D/5:IF $="4";IF 0<5*FRAC E;D=D-1

22 IF $="6";IF 4>5*FRAC E;D=D+1

24 IF $="8";IF 0<INT E;D=D-5

26 IF $="2";IF 4>INT E;D=D+5

28 IF $<>"5" THEN 6

30 IF KEY<>"" THEN 30

32 V=D:GOSUB #4:IF W<>1;IF W<>3 THEN 6

34 PRINT CSR6;"\LA^\DA\RA?";:H=0

36 $=KEY:IF $="4";H=-1

38 IF $="6";H=1

40 IF $="8";H=-5

42 IF $="2";H=5

44 IF $="" THEN 36

45 IF H=0 THEN 6

46 IF W=1;GOSUB #3:GOTO 50

48 GOSUB #2:IF W<>0 THEN 6

50 D=D+H:C=1-C:GOTO 6

52 G=-3^7:Z=3

54 FOR D=0 TO 24:GOSUB 78:V=D:GOSUB #4:IF W<2 THEN 70

56 IF W=2 THEN 64

58 FOR H=-5 TO 5 STEP 2:IF ABS H=3 THEN 62

60 GOSUB 78:GOSUB #2:IF W=0;GOSUB #1

62 NEXT H:GOTO 70

64 FOR H=-5 TO 5 STEP 2:IF ABS H=3 THEN 68

66 GOSUB 78:GOSUB #3:GOSUB #1

68 NEXT H

70 NEXT D

72 Z=0:D=R:H=S:V=R:GOSUB #4:IF W=3;GOSUB #2:GOTO 76

74 GOSUB #3

76 I=L:J=M:K=N:D=D+H:C=1-C:GOTO 6

78 O=L:P=M:Q=N:F=0:RETURN


[P1]

2 FOR T=0 TO 4:U=5:V=T:GOSUB #6:U=-5:V=T+20:GOSUB #6

4 U=1:V=T*5:GOSUB #6:U=-1:V=T*5+4:GOSUB #6:NEXT T

8 FOR T=0 TO 24:V=T:GOSUB #4:IF W<>3 THEN 22

10 FOR U=-5 TO 5 STEP 2:IF ABS U=3 THEN 20

12 V=T+U:IF V<0 THEN 20

14 IF V>24 THEN 20

16 IF ABS U=1;IF INT(V/5)-INT(T/5)<>0 THEN 20

18 GOSUB #6

20 NEXT U:GOTO 24

22 NEXT T:STOP

24 IF O=I;IF P=J;IF Q=K;F=-4^5

26 F=F+RAN#:IF F>G;G=F:R=D:S=H

28 RETURN


[P2]

1 V=D+H:W=3:IF V<0 THEN 6

2 IF V>24 THEN 6

3 IF ABS H=1;IF INT(V/5)-INT(D/5)<>0 THEN 6

4 GOSUB #4:IF W<>0 THEN 6

5 W=3:GOSUB #5:V=D:W=0:GOSUB #5

6 RETURN


[P3]

1 E=0:V=D

2 GOSUB #4:IF W=3 THEN 8

3 B=W:W=E:GOSUB #5:E=B:V=V+H:IF V<0 THEN 8

4 IF V>24 THEN 8

5 IF ABS H=1;IF INT(V/5)-INT((V-H)/5)<>0 THEN 8

6 IF E=0;RETURN

7 GOTO 2

8 IF E=0;RETURN

9 IF Z=3;F=100*(3-2*E+10*(2-E)*FRAC A+(1-E)*INT A):RETURN

10 A=A+10^(E-2):PRINT:PRINT "Lost";10*FRAC A;"\SQ";INT A;"\DI"

11 IF INT A>=2;PRINT "\SQ Win!":END

12 IF 10*FRAC A>=2;PRINT "\DI Win.":END

13 RETURN


[P4]

1 X=10*FRAC(V/10:Y=INT(V/10

2 W=4*FRAC(INT(L(Y+Z)/4^X)/4:RETURN


[P5]

1 Y=INT(V/10:X=4^(10*FRAC(V/10))

2 X=X*(INT(L(Y+Z)/X/4)*4+W+FRAC(L(Y+Z)/X))

3 L(Y+Z)=RND(X,-1):RETURN


[P6]

1 GOSUB #4:IF W<>1;IF W<>2;RETURN

2 E=4-3*W

3 V=V+U:IF V<0 THEN 9

4 IF V>24 THEN 9

5 IF ABS U=1;IF INT(V/5)-INT((V-U)/5)<>0 THEN 9

6 GOSUB #4:IF W<>1;IF W<>2 THEN 9

7 IF ABS(W*E)=2;E=E*10^(1+(2-W)*INT A):GOTO 9

8 GOTO 3

9 F=F+E:RETURN


実機形式