新しく発言する  EXIT  インデックスへ

パソコンが相手をしない「リバーシゲーム」


  パソコンが相手をしない「リバーシゲーム」 荒田浩二 2008/09/07 22:24:58 
  !<その2> 荒田浩二 2008/09/07 22:28:58 
  !<その3> 荒田浩二 2008/09/07 22:34:40 
  !<その4> 荒田浩二 2008/09/07 22:36:50 
  !<その5> 荒田浩二 2008/09/07 22:38:44 
  !<その6> 荒田浩二 2008/09/07 22:42:31 
  !<その7> 荒田浩二 2008/09/07 22:46:36 
  !<その8> 荒田浩二 2008/09/07 22:50:34 
  !<その9> 荒田浩二 2008/09/07 22:53:02 
  !<その10> 荒田浩二 2008/09/07 22:55:29 
  !<その11> 荒田浩二 2008/09/07 22:56:46 

  パソコンが相手をしない「リバーシゲーム」 荒田浩二 2008/09/07 22:24:58   ツリーへ
パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:24:58
オセロとも呼ばれるリバーシゲームです。思考エンジンは持ってません。検討用です。
メニュー画面で、マスを8*8だけでなく3〜16に設定できます。
ゲーム中に[戻る][進む]ボタンで手を変化できます(終局後も戻るボタンは有効)。
パスは自動認識しますが、[PASS]ボタンで意図的なパスもできます(ルールでは不可)。
[EDIT]ボタンで盤面に石を任意に置いたり消すことができます。
<裏技>
メニュー画面では16*16マスまでしか設定できませんが、変数m,nの値を変更すれば80*80や240*8といった設定も可能です。
ただし配列の大きさがマス数の2乗に比例するので盤面を表示するまでに数分かかることもあります。

REM ** REVERSI Lesson **
DECLARE EXTERNAL SUB init.menu,init.choose,init.radio,mouse.operation
DECLARE EXTERNAL PICTURE box.button01,box.rect
PUBLIC NUMERIC m,n,b,w,board,ground,iss,putcol,pix,pixd(5,2)
PUBLIC STRING cc$(0 TO 11)
! [設定メニュー] デフォルトの値
LET m=8 ! マスの列数(横;alphabet),m=3〜16に変更可(最大248?)
LET n=8 ! マスの行数(縦;数字),n=3〜16に変更可(最大81?),m>=n
LET b=1 ! 先手色(黒),b=0〜9に変更可
LET w=0 ! 後手色(白),w=0〜9に変更可
LET board=10 ! 盤面(濃緑),石とは違う色,board=2〜11
LET ground=11 ! 背景の色(青緑),石や盤面と違う色,ground=2〜11
LET iss=0 ! 初期の石の配置 0=交差,1=平行
LET putcol=12 ! 着手点表示色(蛯茶),表示しない時はputcol=0
LET pix=4 ! モニターの解像度選択(1280*800),pix=1〜5
MAT READ cc$ ! 色名
DATA 白,黒,青,緑,赤,水,黄,紫,灰,藍,濃緑,碧
MAT READ pixd ! モニターの解像度データ
DATA 800,600, 1024,768, 1280,720, 1280,800, 1280,1024
IF m<n THEN SWAP m,n
CALL menu ! 設定メニュー(スキップ可)
!
LET pixx=INT(pixd(pix,1)*0.98)-1 !一画面に収まる最大画素数
LET pixy=INT(pixd(pix,2)*0.85)-1
LET bp=INT(MIN(pixx/(m+2),pixy/(n+2))) ! マスの一辺の画素数
LET ic=4 ! 初期の石の個数
LET mem=(m+2)*(n+2)+m*n+(m*n-ic+1)*m*n+(m*n-ic)*3 ! 配列の要素数の合計
IF bp=5 THEN LET putcol=0 ! bp=5 は、着手点表示なしならば可
IF bp<5 OR mem>44000000 THEN CALL mem_error ! メモリーオーバー
SET BITMAP SIZE bp*(m+2)+1,bp*(n+2)+1
SET WINDOW 0,m+2,n+2,0
DIM r(0 TO m+1,0 TO n+1),r3(m,n),rr(ic TO m*n,m,n),kif(m*n-ic,3)
MAT r=board*CON ! r(x,y)は盤面(x列,y行)の色
DRAW start ! 初期画面描画
CALL scan ! 盤面スキャン
DRAW counter ! 石数表示
LET c=b ! c=手番の色(先手は黒番)
DRAW turn(c) ! 手番表示
DEF count=countb+countw ! 盤面上の石数
DEF hand=countb+countw-ic+1 ! 手数
IF bp<15 THEN SET POINT STYLE 2 ! マスが小さい時,着手点表示を十字形に
LET putx=1
LET puty=1
!<その2>に続く
  !<その2> 荒田浩二 2008/09/07 22:28:58   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:28:58
!<その2>
! メインルーチン
DO
CALL sarch ! 着手可能点のサーチ
IF sarev=0 THEN
LET pass_auto=1 ! 無条件パス
DRAW pass ! パス
CALL sarch
IF sarev=0 OR count=m*n THEN DRAW gameset ! 終局処理
END IF
LET rev=0 ! 返せる石数
DO
CALL click ! 左クリック
CALL neighbor(x,y,c) ! 隣接する石をチェック
LOOP UNTIL rev<>0
LET kif(hand,1)=c ! 第hand手目の色
LET kif(hand,2)=x ! 列(alphabet)
LET kif(hand,3)=y ! 行(数字)
LET maxhand=MAX(maxhand,hand)
IF pass_auto=1 THEN CALL pass_off ! 無条件パスの解除
CALL scan
DRAW counter
IF c=b THEN LET c=w ELSE LET c=b
DRAW turn(c)
LOOP

! 以下、副プログラム
SUB click ! 左クリック
DO
GET POINT : x,y
LET event=1
IF x>=ex AND x<=ex+bw AND y>=ey AND y<=ey+bh THEN
CALL edit ! 盤面編集モード
ELSEIF pass_auto=0 AND x>=px AND x<=px+bw AND y>=py AND y<=py+bh THEN
LET pass_on=1
DRAW pass ! パス
ELSEIF hand>1 AND x>=ix-0.1 AND x<=ix+imw AND y>=by AND y<=by+bgh THEN
CALL backstart ! 最初に戻る
ELSEIF hand>1 AND kif(hand-1,2)<>0 AND x>=bx AND x<=bx+bgw AND y>=by AND y<=by+bgh THEN
CALL back ! 一手戻る
ELSEIF hand<=m*n-ic AND kif(hand,2)<>0 AND x>=gx AND x<=gx+bgw AND y>=by AND y<=by+bgh THEN
CALL goes ! 一手進む
ELSEIF maxhand<>count-ic AND x>=mx AND x<=mx+imw+0.1 AND y>=by AND y<=by+bgh THEN
CALL goesmaxhand ! 最後に進む
ELSEIF x>=sx AND x<=sx+bw AND y>=sy AND y<=sy+bh THEN
CALL program_stop ! 終了
ELSE
LET event=0
END IF
IF event=1 AND gameset_on=1 THEN DRAW gameset_off ! 終局面からの復帰
IF event=1 AND pass_auto=1 THEN CALL pass_off ! 無条件パスの解除
LET x=INT(x)
LET y=INT(y)
LOOP UNTIL x>=1 AND x<=m AND y>=1 AND y<=n AND r(x,y)=board
END SUB
SUB sarch ! 着手可能点のサーチ
LET sarch_on=1 ! サーチ中
LET sarev=0
FOR x=1 TO m
FOR y=1 TO n
IF r(x,y)=board THEN CALL neighbor(x,y,c)
IF sarev=1 THEN
LET sarch_on=0
EXIT SUB
END IF
NEXT y
NEXT x
LET sarch_on=0
END SUB
SUB neighbor(x,y,col) ! 隣接する石をチェック
FOR i=-1 TO 1 STEP 1
FOR j=-1 TO 1 STEP 1
IF r(x+i,y+j)<>col AND r(x+i,y+j)<>board THEN
CALL revcheck(x,y,col,i,j)
END IF
IF sarch_on=1 AND sarev=1 THEN EXIT SUB
NEXT j
NEXT i
END SUB
!<その3>に続く
  !<その3> 荒田浩二 2008/09/07 22:34:40   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:34:40
!<その3>
SUB revcheck(x,y,col,i,j) ! 返せる石をチェック
FOR k=2 TO MAX(m,n)-1
IF r(x+SGN(i)*k,y+SGN(j)*k)=board THEN EXIT FOR
IF r(x+SGN(i)*k,y+SGN(j)*k)=col THEN
IF sarch_on=1 THEN
LET sarev=1
EXIT SUB
END IF
IF rev=0 THEN
DRAW put(x,y,col) ! 着手点
IF putcol<>0 THEN DRAW putat(x,y) ! 着手点表示
END IF
FOR k2=1 TO k-1
DRAW put(x+SGN(i)*k2,y+SGN(j)*k2,col)
NEXT k2
LET rev=rev+(k-1) ! 返せる石数
EXIT FOR
END IF
NEXT k
END SUB
PICTURE put(x,y,col) ! 石の描画
SET DRAW MODE HIDDEN
DRAW rect(board) WITH SCALE(0.8,0.8)*SHIFT(x+0.1,y+0.1)
SET DRAW MODE EXPLICIT
WAIT DELAY 0.1
IF col<>board THEN
SET DRAW MODE HIDDEN
SET LINE WIDTH LW
SET AREA COLOR col
IF bp>=15 THEN
DRAW CIRCLE WITH SCALE(0.33)*SHIFT(x+0.5,y+0.5)
SET DRAW MODE EXPLICIT
WAIT DELAY 0.1
SET DRAW MODE HIDDEN
PAINT x+0.5,y+0.5
ELSE
DRAW DISK WITH SCALE(0.33)*SHIFT(x+0.5,y+0.5)
END IF
SET DRAW MODE EXPLICIT
END IF
WAIT DELAY 0.1
END PICTURE
PICTURE putat(x,y) ! 着手点表示
SET DRAW MODE HIDDEN
ASK PIXEL VALUE(putx+0.65,puty+0.65) apv
SET POINT COLOR apv
PLOT POINTS : putx+0.5,puty+0.5
SET POINT COLOR putcol
PLOT POINTS : x+0.5,y+0.5
SET DRAW MODE EXPLICIT
LET putx=x
LET puty=y
END PICTURE
SUB scan ! 盤面スキャン
LET countb=0
LET countw=0
FOR i=1 TO m
FOR j=1 TO n
ASK PIXEL VALUE(i+0.65,j+0.65) r3(i,j)
IF r3(i,j)=b THEN
LET countb=countb+1
ELSEIF r3(i,j)=w THEN
LET countw=countw+1
END IF
NEXT j
NEXT i
IF edit_on<>1 THEN
FOR i=1 TO m
FOR j=1 TO n
LET rr(count,i,j)=r3(i,j)
NEXT j
NEXT i
END IF
FOR i=1 TO m
FOR j=1 TO n
LET r(i,j)=r3(i,j)
NEXT j
NEXT i
END SUB
PICTURE counter ! 石数表示
ASK TEXT HEIGHT ath
SET TEXT HEIGHT 0.4
SET DRAW MODE HIDDEN
DRAW rect(ground) WITH SCALE(m-0.9,0.8)*SHIFT(0,n+1.1)
PLOT TEXT ,AT 0.75,n+1.5:cc$(b)&":"&STR$(countb)
PLOT TEXT ,AT m/2+0.1,n+1.5:cc$(w)&":"&STR$(countw)
SET DRAW MODE EXPLICIT
SET TEXT HEIGHT ath
END PICTURE
!<その4>に続く
  !<その4> 荒田浩二 2008/09/07 22:36:50   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:36:50
!<その4>
PICTURE turn(t) ! 手番表示
SET DRAW MODE HIDDEN
DRAW rect(ground) WITH SCALE(0.9,1.2)*SHIFT(m+1.1,n/2)
PLOT TEXT ,AT m+1.5, n/2+0.4:cc$(t)&"番"
SET LINE WIDTH 1
SET AREA COLOR t
IF bp>=15 THEN
DRAW CIRCLE WITH SCALE(0.2)*SHIFT(m+1.5,n/2+0.9)
PAINT m+1.5,n/2+0.9
ELSE
DRAW DISK WITH SCALE(0.2)*SHIFT(m+1.5,n/2+0.9)
END IF
SET DRAW MODE EXPLICIT
END PICTURE
PICTURE pass ! パス
BEEP
DRAW rect(ground) WITH SCALE(0.95,1.2)*SHIFT(m+1.05,n/2)
DRAW button01(1,ground,"PASS",bth,ground) WITH SCALE(bw,bh)*SHIFT(px,py)
PLOT TEXT ,AT m+1.5,n/2+0.6:"パス!"
WAIT DELAY 0.8
IF pass_on=1 THEN
DRAW button01(0,5,"PASS",bth,ground) WITH SCALE(bw,bh)*SHIFT(px,py)
LET pass_on=0
END IF
IF c=b THEN LET c=w ELSE LET c=b
DRAW turn(c)
END PICTURE
SUB pass_off ! 無条件パスの解除
SET DRAW MODE HIDDEN
!DRAW rect(ground) WITH SCALE(bw+0.1,bh+0.1)*SHIFT(px-0.05,py-0.05)
DRAW button01(0,5,"PASS",bth,ground) WITH SCALE(bw,bh)*SHIFT(px,py)
LET pass_auto=0
SET DRAW MODE EXPLICIT
END SUB
SUB backstart ! 最初に戻る
BEEP
FOR i=1 TO m
FOR j=1 TO n
IF r(i,j)<>rr(ic,i,j) THEN DRAW put(i,j,rr(ic,i,j))
NEXT j
NEXT i
CALL scan
DRAW counter
LET c=b
DRAW turn(c)
END SUB
SUB back ! 一手戻る
BEEP
FOR i=1 TO m
FOR j=1 TO n
IF r(i,j)<>rr(count-1,i,j) THEN DRAW put(i,j,rr(count-1,i,j))
NEXT j
NEXT i
CALL scan
DRAW counter
IF hand-1<>0 AND kif(hand-1,2)<>0 AND putcol<>0 THEN DRAW putat(kif(hand-1,2),kif(hand-1,3))
LET c=kif(hand,1)
DRAW turn(c)
END SUB
SUB goes ! 一手進む
BEEP
FOR i=1 TO m
FOR j=1 TO n
IF r(i,j)<>rr(count+1,i,j) THEN DRAW put(i,j,rr(count+1,i,j))
NEXT j
NEXT i
IF kif(hand,2)<>0 AND putcol<>0 THEN DRAW putat(kif(hand,2),kif(hand,3))
CALL scan
DRAW counter
IF hand<=m*n-ic AND kif(hand,2)<>0 THEN
LET c=kif(hand,1)
ELSEIF kif(hand-1,1)=b THEN
LET c=w
ELSE
LET c=b
END IF
DRAW turn(c)
END SUB
SUB goesmaxhand ! 最後に進む
BEEP
FOR i=1 TO m
FOR j=1 TO n
IF r(i,j)<>rr(maxhand+ic,i,j) THEN DRAW put(i,j,rr(maxhand+ic,i,j))
NEXT j
NEXT i
IF kif(maxhand,2)<>0 AND putcol<>0 THEN DRAW putat(kif(maxhand,2),kif(maxhand,3))
CALL scan
DRAW counter
IF kif(maxhand,1)=b THEN LET c=w ELSE LET c=b
DRAW turn(c)
END SUB
!<その5>に続く
  !<その5> 荒田浩二 2008/09/07 22:38:44   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:38:44
!<その5>
SUB edit ! 盤面編集モード
LET edit_on=1 ! 編集中
DRAW button01(1,ground,"EDIT",bth,ground) WITH SCALE(bw,bh)*SHIFT(ex,ey)
BEEP
WAIT DELAY 0.5
DRAW button01(0,3,"戻る",bth,ground) WITH SCALE(bw,bh)*SHIFT(ex,ey)
PLOT TEXT ,AT ex+0.4,ey+0.8:"左:"& cc$(b)
PLOT TEXT ,AT ex+0.4,ey+1.15:"右:"& cc$(w)
PLOT TEXT ,AT ex+0.4,ey+1.5:" W:消"
DO
DO
DO
CALL mouse.operation(cli,x,y,xx,yy) ! マウス操作
LOOP UNTIL cli=2 OR cli=3 OR cli=4
IF cli=4 AND x>=ex AND x<=ex+bw AND y>=ey AND y<=ey+bh THEN
DRAW button01(1,ground,"戻る",bth,ground) WITH SCALE(bw,bh)*SHIFT(ex,ey)
BEEP
WAIT DELAY 0.5
DRAW rect(ground) WITH SCALE(1,1.8)*SHIFT(ex,ey)
DRAW button01(0,3,"EDIT",bth,ground) WITH SCALE(bw,bh)*SHIFT(ex,ey)
DRAW turn(c)
LET edit_on=0
CALL scan
DRAW counter
EXIT SUB
END IF
IF cli=4 AND x>=sx AND x<=sx+bw AND y>=sy AND y<=sy+bh THEN CALL program_stop ! 終了
LET x=INT(x)
LET y=INT(y)
LOOP UNTIL x>=1 AND x<=m AND y>=1 AND y<=n
SELECT CASE cli
CASE 4
LET col=b
CASE 2
LET col=w
CASE 3
LET col=board
END SELECT
DRAW put(x,y,col)
WAIT DELAY 0.3
CALL scan
DRAW counter
LOOP
END SUB ! editの終端
PICTURE gameset ! 終局処理
BEEP
IF countb>countw THEN
LET winc=b
LET win$=cc$(b)&"勝利"
ELSEIF countw>countb THEN
LET winc=w
LET win$=cc$(w)&"勝利"
ELSE
LET winc=board
LET win$="引分け"
END IF
SET DRAW MODE HIDDEN
DRAW rect(ground) WITH SCALE(0.95,n)*SHIFT(m+1.05,1)
SET LINE COLOR winc
SET LINE WIDTH LW
PLOT LINES:m+1.1,n-1;m+1.9,n-1;m+1.9,n+0.5;m+1.1,n+0.5;m+1.1,n-1
FOR i=1 TO 3
PLOT TEXT ,AT m+1.5,n-1+0.1+1.3/6*(2*i-1):win$(i:i)
NEXT i
SET AREA COLOR winc
DRAW DISK WITH SCALE(0.2)*SHIFT(m+1.5,n+0.75)
PLOT TEXT ,AT m/2+1,0.3 :"終了ボタンをクリック"
SET DRAW MODE EXPLICIT
SET LINE COLOR 1
LET gameset_on=1
END PICTURE
PICTURE gameset_off ! 終局面からの復帰
LET gameset_on=0
SET DRAW MODE HIDDEN
DRAW rect(ground) WITH SCALE(0.9,2.1)*SHIFT(m+1.05,n-1.05)
DRAW turn(c)
DRAW rect(ground) WITH SCALE(m,0.5)*SHIFT(1,0)
SET DRAW MODE EXPLICIT
END PICTURE
!<その6>に続く
  !<その6> 荒田浩二 2008/09/07 22:42:31   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:42:31
!<その6>
SUB program_stop ! 終了
BEEP
SET DRAW MODE HIDDEN
DRAW button01(1,ground,"終了",bth,ground) WITH SCALE(bw,bh)*SHIFT(sx,sy)
DRAW rect(ground) WITH SCALE(m,0.5)*SHIFT(1,0)
IF m>=6 THEN SET TEXT HEIGHT 0.5 ELSE SET TEXT HEIGHT 0.3
SET TEXT COLOR 0
PLOT TEXT ,AT m/2+1,0.3 :"プログラムを終了しました"
SET DRAW MODE EXPLICIT
STOP
END SUB
PICTURE start ! 初期画面描画
SET DRAW MODE HIDDEN
LET LW=2 ! 線の太さ
IF m>16 OR n>14 THEN LET LW=1
DRAW rect(ground) WITH SCALE(m+2,n+2)
DRAW rect(board) WITH SCALE(m,n)*SHIFT(1,1)
SET LINE COLOR 1
SET LINE WIDTH LW
FOR i=1 TO n+1 ! ヨコ線
PLOT LINES:1,i;m+1,i
NEXT i
FOR j=1 TO m+1 ! タテ線
PLOT LINES:j,1;j,n+1
NEXT j
SET AREA COLOR 1 ! 丸点
DRAW DISK WITH SCALE(0.04)*SHIFT(3,3)
DRAW DISK WITH SCALE(0.04)*SHIFT(m-1,3)
DRAW DISK WITH SCALE(0.04)*SHIFT(3,n-1)
DRAW DISK WITH SCALE(0.04)*SHIFT(m-1,n-1)
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT HEIGHT 0.25
FOR i=1 TO m ! alphabet表示
IF i<=26 THEN
PLOT TEXT ,AT i+0.5,0.7:CHR$(96+i)
ELSEIF i<=52 THEN
PLOT TEXT ,AT i+0.5,0.7:CHR$(38+i)
ELSE
PLOT TEXT ,AT i+0.5,0.7:STR$(i)
END IF
NEXT i
FOR j=1 TO n ! 数字表示
PLOT TEXT ,AT 0.7,j+0.5:STR$(j)
NEXT j
LET bw=0.8 ! ボタン幅
LET bh=0.5 ! ボタン高
LET bth=0.5*bh ! ボタン文字高さ
LET ex=m+1.1 ! ボタンの左上点x
LET ey=0.25 ! ボタンの左上点y
DRAW button01(0,3,"EDIT",bth,ground) WITH SCALE(bw,bh)*SHIFT(ex,ey)
LET px=m+1.1
LET py=n/2+1.25
DRAW button01(0,5,"PASS",bth,ground) WITH SCALE(bw,bh)*SHIFT(px,py)
LET sx=0.1
LET sy=0.25
DRAW button01(0,8,"終了",bth,ground) WITH SCALE(bw,bh)*SHIFT(sx,sy)
LET bgw=0.7 ! [back][go]ボタン幅
LET bgh=0.6 ! [back][go]ボタン高
LET by=n+1.2
LET imw=0.2+0.2 ! [最初に戻る]ボタン幅
LET ix=m-0.25-0.5
DRAW button01(0,8,"",1,ground) WITH SCALE(imw,bgh)*SHIFT(ix,by)
LET bx=m+0.05-0.3
DRAW button01(0,8,"",1,ground) WITH SCALE(bgw,bgh)*SHIFT(bx,by)
LET gx=m+0.85-0.3
DRAW button01(0,8,"",1,ground) WITH SCALE(bgw,bgh)*SHIFT(gx,by)
LET mx=m+1.65-0.3
DRAW button01(0,8,"",1,ground) WITH SCALE(imw,bgh)*SHIFT(mx,by)
SET AREA COLOR 1 ! ボタンの模様
DRAW rect(1) WITH SCALE(0.12,bgh-0.2)*SHIFT(ix+0.14,by+0.1)
PLOT AREA:bx+0.1,by+bgh/2;bx+bgw-0.1,by+bgh-0.1;bx+bgw-0.1,by+0.1
PLOT AREA:gx+bgw-0.1,by+bgh/2;gx+0.1,by+bgh-0.1;gx+0.1,by+0.1
DRAW rect(1) WITH SCALE(0.12,bgh-0.2)*SHIFT(mx+0.14,by+0.1)
SET DRAW MODE EXPLICIT ! 画面に描画
WAIT DELAY 0.3
!<その7>に続く
  !<その7> 荒田浩二 2008/09/07 22:46:36   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:46:36
!<その7>
IF iss=0 THEN
DRAW put(INT(m/2),INT(n/2+1),b) ! 初期の石の配置
DRAW put(INT(m/2+1),INT(n/2),b)
DRAW put(INT(m/2),INT(n/2),w)
DRAW put(INT(m/2+1),INT(n/2+1),w)
ELSEIF m/2<>INT(m/2) AND n/2=INT(n/2) THEN
DRAW put(INT(m/2),INT(n/2),w)
DRAW put(INT(m/2+1),INT(n/2),w)
DRAW put(INT(m/2),INT(n/2+1),b)
DRAW put(INT(m/2+1),INT(n/2+1),b)
ELSE
DRAW put(INT(m/2),INT(n/2),b)
DRAW put(INT(m/2),INT(n/2+1),b)
DRAW put(INT(m/2+1),INT(n/2),w)
DRAW put(INT(m/2+1),INT(n/2+1),w)
END IF
END PICTURE ! startの終端
SUB mem_error ! メモリーオーバー
BEEP
SET TEXT COLOR "RED"
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT HEIGHT 3
PLOT TEXT ,AT 20,20 : "memory over STOP !!"
PLOT TEXT ,AT 20,26 : "マス数を減らして !!"
STOP
END SUB
END

MODULE init
PUBLIC SUB menu,choose,radio
SHARE NUMERIC x,a2,a3,a4,a5,bb
EXTERNAL SUB menu ! 設定メニュー
DECLARE EXTERNAL NUMERIC m,n,b,w,board,ground,iss,putcol,pix,pixd(,)
DECLARE EXTERNAL STRING cc$()
DECLARE EXTERNAL PICTURE box.button01,box.rect
SET WINDOW 0,40,46,1
SET DRAW MODE HIDDEN
LET a1=9 ! 項目名の右端
LET a2=a1-1
LET a3=2 ! ボタン間の距離
LET a4=0.45 ! ラジオボタンの半径
LET a5=0.3 ! 選択点の半径
DRAW rect(8) WITH SCALE(40,46)*SHIFT(0,1) ! 背景色(灰)
SET TEXT COLOR 2
SET TEXT HEIGHT 1.7
SET TEXT JUSTIFY "CENTER","BOTTOM"
PLOT TEXT ,AT 40/2,4 : "<< REVERSI Lesson 設定メニュー >>"
SET TEXT COLOR 1
SET TEXT HEIGHT 1
LET bb=2 ! 選択点の色(青)
LET m9=16
DIM st$(3 TO m9)
FOR i=3 TO m9
LET st$(i)=STR$(i)
NEXT i
SET TEXT JUSTIFY "RIGHT","BOTTOM"
LET L1=6
LET L2=9
PLOT TEXT ,AT a1,L1+0.5 : "マス数(横) :"
PLOT TEXT ,AT a1,L2+0.5 : "マス数(縦) :"
CALL radio(L1,st$,3,m9,m)
CALL radio(L2,st$,3,m9,n)
LET L3=13
LET L4=16
PLOT TEXT ,AT a1,L3+0.5 : "先手の石の色 :"
PLOT TEXT ,AT a1,L4+0.5 : "後手の石の色 :"
CALL radio(L3,cc$,0,9,b)
CALL radio(L4,cc$,0,9,w)
LET L5=20
PLOT TEXT ,AT a1,L5+0.5 : "盤面の色 :"
CALL radio(L5,cc$,2,11,board)
LET L6=24
PLOT TEXT ,AT a1,L6+0.5 : "背景の色 :"
CALL radio(L6,cc$,2,11,ground)
SET TEXT JUSTIFY "RIGHT","BASE"
LET L7=28.5
PLOT TEXT ,AT a1,L7 : "初期の配置 :"
SET TEXT JUSTIFY "LEFT","BASE"
PLOT TEXT ,AT 11,L7 : "交差"
PLOT TEXT ,AT 17,L7 : "平行"
DRAW CIRCLE WITH SCALE(a4)*SHIFT(10,L7-a4)
DRAW CIRCLE WITH SCALE(a4)*SHIFT(16,L7-a4)
SET AREA COLOR 0
PAINT 10,L7-a4
PAINT 16,L7-a4
SET AREA COLOR bb
IF putcol<>0 THEN LET a6=10 ELSE LET a6=16
DRAW DISK WITH SCALE(a5)*SHIFT(a6,L7-a4)
!<その8>に続く
  !<その8> 荒田浩二 2008/09/07 22:50:34   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:50:34
!<その8>
LET L8=31.5
SET TEXT JUSTIFY "RIGHT","BASE"
PLOT TEXT ,AT a1,L8 : "着手点の表示 :"
SET TEXT JUSTIFY "LEFT","BASE"
PLOT TEXT ,AT 11,L8 : "あり"
PLOT TEXT ,AT 17,L8 : "なし"
DRAW CIRCLE WITH SCALE(a4)*SHIFT(10,L8-a4)
DRAW CIRCLE WITH SCALE(a4)*SHIFT(16,L8-a4)
SET AREA COLOR 0
PAINT 10,L8-a4
PAINT 16,L8-a4
SET AREA COLOR bb
IF putcol<>0 THEN LET a6=10 ELSE LET a6=16
DRAW DISK WITH SCALE(a5)*SHIFT(a6,L8-a4)
LET L9=34.5
SET TEXT JUSTIFY "RIGHT","BASE"
PLOT TEXT ,AT a1,L9 : "画面の解像度 :"
SET TEXT JUSTIFY "LEFT","BASE"
SET AREA COLOR 0
FOR i=1 TO 5
PLOT TEXT,AT 4.5+6*i,L9:STR$(pixd(i,1))&"*"&STR$(pixd(i,2))
DRAW CIRCLE WITH SCALE(a4)*SHIFT(4+6*i,L9-a4)
PAINT 4+6*i,L9-a4
NEXT i
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(4+6*pix,L9-a4)
LET mx=18 ! [設定]ボタン表示
LET my=43 ! ボタンの左上点
LET mbw=4 ! ボタン幅
LET mbh=2 ! ボタン高
DRAW button01(0,5,"設 定",0.6*mbh,8) WITH SCALE(mbw,mbh)*SHIFT(mx,my)
SET DRAW MODE EXPLICIT
SET TEXT HEIGHT 1
! メニュー選択操作
DO
DO
GET POINT : x,y
IF x>=mx AND x<=mx+4 AND y>=my AND y<=my+1.8 THEN EXIT DO
SET DRAW MODE HIDDEN
SELECT CASE y
CASE 5 TO 7.5 ! m=3〜16 マス数(横)
CALL choose(L1+1,3,m9,m)
CASE 8 TO 10.5 ! n=3〜16 マス数(縦)
CALL choose(L2+1,3,m9,n)
CASE 12 TO 14.5 ! b=0〜9 先手の石の色
CALL choose(L3+1,0,9,b)
CASE 15 TO 17.5 ! w=0〜9 後手の石の色
CALL choose(L4+1,0,9,w)
CASE 19 TO 21.5 ! board=2〜11 盤面の色
CALL choose(L5+1,2,11,board)
CASE 23 TO 25.5 ! ground=2〜11 背景の色
CALL choose(L6+1,2,11,ground)
CASE 27.2 TO 29 ! iss=0,1 初期の配置
IF x>=9 AND x<=13 THEN
SET AREA COLOR 0
FLOOD 16,L7-a4
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(10,L7-a4)
LET iss=0
ELSEIF x>=15 AND x<=19 THEN
SET AREA COLOR 0
FLOOD 10,L7-a4
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(16,L7-a4)
LET iss=1
END IF
!<その9>に続く
  !<その9> 荒田浩二 2008/09/07 22:53:02   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:53:02
!<その9>
CASE 30.2 TO 32 ! putcol=12,0 着手点の表示
IF x>=9 AND x<=13 THEN
SET AREA COLOR 0
FLOOD 16,L8-a4
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(10,L8-a4)
LET putcol=12
ELSEIF x>=15 AND x<=19 THEN
SET AREA COLOR 0
FLOOD 10,L8-a4
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(16,L8-a4)
LET putcol=0
END IF
CASE 33.2 TO 35 ! pix=1〜5 画面の解像度
LET ri=INT((x-9)/6)+1
IF ri>=1 AND ri<=5 THEN
SET AREA COLOR 0
FLOOD 4+6*pix,L9-a4
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(4+6*ri,L9-a4)
LET pix=ri
END IF
CASE ELSE
END SELECT
SET DRAW MODE EXPLICIT
LOOP
IF m>=n AND b<>w AND board<>b AND board<>w AND ground<>b AND ground<>w AND ground<>board THEN
EXIT SUB
ELSE
DRAW button01(1,8,"設 定",0.6*mbh,8) WITH SCALE(mbw,mbh)*SHIFT(mx,my)
BEEP ! エラーメッセージ
WAIT DELAY 0.3
DRAW button01(0,5,"設 定",0.6*mbh,8) WITH SCALE(mbw,mbh)*SHIFT(mx,my)
SET DRAW MODE HIDDEN
SET TEXT JUSTIFY "CENTER","HALF"
DRAW rect(6) WITH SCALE(35,6.5)*SHIFT(2.5,35.5)
IF m<n THEN PLOT TEXT,AT 40/2,36.5:"盤が横長になるよう、マス数は横の方を大きく設定してください"
IF b=w THEN PLOT TEXT,AT 40/2,38:"先手と後手は、違う色に設定してください"
IF board=b OR board=w THEN PLOT TEXT,AT 40/2,39.5:"盤面は、石と違う色に設定してください"
IF ground=b OR ground=w OR ground=board THEN PLOT TEXT,AT 20,41:"背景は、石や盤面と違う色に設定してください"
SET DRAW MODE EXPLICIT
END IF
LOOP
END SUB ! menuの終端
EXTERNAL SUB choose(L,r0,r9,rb) ! menuラジオボタン選択
LET ri=ROUND((x-a2)/a3+r0-1,0)
IF ri>=r0 AND ri<=r9 THEN
SET AREA COLOR 0
FLOOD a2+a3*(rb-r0+1),L-a4
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(a2+a3*(ri-r0+1),L-a4)
LET rb=ri ! 実引数の値の変更(参照渡し)
END IF
END SUB
EXTERNAL SUB radio(L,ra$(),r0,r9,rb) ! menuラジオボタン描画
ASK TEXT JUSTIFY w$,h$
SET TEXT JUSTIFY "CENTER","BOTTOM"
SET AREA COLOR 0
FOR i=r0 TO r9
PLOT TEXT ,AT a2+a3*(i-r0+1),L : ra$(i)
DRAW CIRCLE WITH SCALE(a4)*SHIFT(a2+a3*(i-r0+1),L+1-a4)
PAINT a2+a3*(i-r0+1),L+1-a4
NEXT i
SET AREA COLOR bb
DRAW DISK WITH SCALE(a5)*SHIFT(a2+a3*(rb-r0+1),L+1-a4)
SET TEXT JUSTIFY w$,h$
END SUB
END MODULE
!<その10>に続く
  !<その10> 荒田浩二 2008/09/07 22:55:29   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:55:29
!<その10>

REM ** ボタン描画 **
MODULE box
PUBLIC SUB button01,rect
EXTERNAL PICTURE button01(push,buttoncol,text$,texth,backcol)
ASK LINE COLOR alc
ASK LINE WIDTH alw
ASK AREA COLOR aac
ASK TEXT JUSTIFY atjx$,atjy$
ASK TEXT HEIGHT ath
SET LINE COLOR backcol ! 枠線の修正(backcol=ボタンの背景色)
SET LINE WIDTH 2
PLOT LINES : 0,0;1,0;1,1;0,1;0,0 ! 左上が基準点
DRAW rect(buttoncol)
LET linecol=1-push ! push(0=ボタンOFF,1=ボタンON)
LET linewidth=2-push
SET LINE COLOR linecol ! 右下線(0=白,1=黒)
SET LINE WIDTH linewidth ! 線の太さ(1=細,2=太)
PLOT LINES : 0,1;1,1;1,0;
SET LINE COLOR ABS(linecol-1) ! 左上線
SET LINE WIDTH MOD(linewidth,2)+1
PLOT LINES : 0,0;0,1
SET TEXT JUSTIFY "CENTER","HALF"
SET TEXT HEIGHT texth ! 問題座標の値で指定
PLOT LABEL ,AT 0.5,0.5 : text$
SET LINE COLOR alc
SET LINE WIDTH alw
SET AREA COLOR aac
SET TEXT JUSTIFY atjx$,atjy$
SET TEXT HEIGHT ath
END PICTURE
EXTERNAL PICTURE rect(col) ! 長方形の塗りつぶし
SET AREA COLOR col
PLOT AREA : 0,0;1,0;1,1;0,1
END PICTURE
END MODULE
!<その11>に続く
  !<その11> 荒田浩二 2008/09/07 22:56:46   ツリーへ
Re: パソコンが相手をしない「リバーシゲーム」  返事を書く  ノートメニュー
荒田浩二 <knrztrhoel> 2008/09/07 22:56:46
!<その11>
REM ** マウス操作 **
MODULE mouse
PUBLIC SUB operation
SHARE NUMERIC p,w,s,check,t0,t1
LET p=1000 !! 長押し時間(p秒以上押し続ける)
LET w=0.4 ! Wクリックの間隔(押してからw秒以内に2度目を押す)
LET s=0.3 ! ドラッグ無効時間(押してからs秒以内に放すと左クリック扱い)
EXTERNAL SUB operation(a,x0,y0,x,y)
MOUSE POLL x,y,l,r
SELECT CASE check
CASE 0 ! 操作開始のチェック
LET x0=x
LET y0=y
IF l=0 AND r=0 THEN ! ボタン解放の確認
LET a=0
ELSEIF a<>0 THEN
LET a=-1 ! 前回の操作を無効化
ELSE ! 操作の開始
LET t0=TIME
LET check=1
END IF
CASE 1 ! ボタンのチェック
LET t1=TIME
IF l=1 THEN
LET a=0.1 ! 左ボタンが押された状態
CALL press(a,x0,y0,x,y) ! 長押しの判定
ELSEIF r=1 THEN
LET a=0.2 ! 右ボタンが押された状態
LET check=3
! CALL complete(a,x0,y0,x,y) ! ボタンを押して右クリック完了
ELSE
LET a=0 ! 左ボタンが放された状態
LET check=2
! CALL complete(a,x0,y0,x,y) ! Wクリックを無効化
END IF
CASE 2 ! Wクリックの有無のチェック
IF l=1 THEN
LET a=0.3 ! 左ボタンが2度押された状態
LET check=3
! CALL complete(a,x0,y0,x,y) ! ボタンを押してWクリック完了
ELSEIF TIME-t0>w THEN
CALL complete(a,x0,y0,x,y)
END IF
CASE 3 ! ボタン解放のチェック
IF l=0 AND r=0 THEN CALL complete(a,x0,y0,x,y)
END SELECT
END SUB
EXTERNAL SUB complete(a,x0,y0,x,y) ! 操作の完了
LET check=0
IF a=0.2 THEN
LET a=2 ! 右クリック
ELSEIF a=0.3 THEN
LET a=3 ! Wクリック
ELSEIF t1-t0<=s OR (x=x0 AND y=y0 AND t1-t0<p) THEN
LET a=4 ! 左クリック
ELSEIF x<>x0 OR y<>y0 THEN
LET a=5 ! ドラッグ(移動先は x,y)
ELSE
LET a=1 ! 長押し(ボタンを放して完了,副プログラムpressを無効にした時)
END IF
END SUB
EXTERNAL SUB press(a,x0,y0,x,y) ! 長押しの判定
IF x=x0 AND y=y0 AND t1-t0>=p THEN
LET check=0 ! 操作の完了
LET a=1 ! 長押し(ボタンを押し続けて完了)
END IF
END SUB
END MODULE

 インデックスへ  EXIT
新規発言を反映させるにはブラウザの更新ボタンを押してください。