bomb11.aiffも入れる必要があります。
/***************************************************************** // 爆弾捜しゲーム // アイディアは違うけど、プログラムは // Copyright (C) 1993,2012 by AIG-SOFT // うわぁ、約20年ぶりに移植したのか! /***************************************************************** /* 定数 じゃなくて 変数 font("IPAGothic") int fzenhan int WX=64 int WY=width(WX,,fzenhan) int xw=1:/* 全角1文字の桁数 if fzenhan then xw=2 /***************************************************************** int MX =(WX/2)-2 :/* マップ最大横幅(-2は枠用) int MY =19 :/* マップ最大縦幅 int MXX=5 :/* マップ最小横幅 int MYY=4 :/* マップ最小縦幅 int BOMB='*' :/* 爆弾コード int ERR=9 :/* 判定間違い int BMBIT=bit(7) :/* 爆弾在るはずビット int CHBIT=bit(6) :/* わかんないビット int OPBIT=(BMBIT or CHBIT) :/* オープン状態を示すビット int NOPBIT=(not OPBIT) :/* キャラクターのみを取り出すビット /* 画面表示ホーム座標 int SX=2 :/* sx>=2 & sx+(MX+1)*2<画面x幅 int SY=4 :/* sy>=4 & sy+MY+1 <画面y幅 int ESC=&h1B int CR =&h0d /***************************************************************** /* グローバル変数 dim char map( (64/2),19) :/* (MX,MY)だけど変数だから使えない 現在マップ dim char map0((64/2),19) :/* (MX,MY) 表示用仮想画面 dim int touchNo(10) :// タッチエリア番号 int touchCnt :// タッチエリア数 int wx,wy :/* マップ幅 int seed,bomb :/* 全爆弾数,爆弾ありそう数 int all :/* 開けるべき全ますの数 int ts,dt :/* 開始時間、経過時間 /***************************************************************** int ret int minbomb,maxbomb /* フィールド幅、爆弾個数設定 str widthStr,heightStr,bombStr,defaultStr,messageStr if isLocalizeJapan() then { widthStr ="横幅" heightStr="縦幅" minbomb=MXX*MYY/8 :/* 最小1/8 maxbomb=wx*wy/2 :/* 最大1/2 bombStr="爆弾数" defaultStr="標準" messageStr="メッセージ" } else { widthStr ="width " heightStr="height" minbomb=MXX*MYY/8 :/* 最小1/8 maxbomb=wx*wy/2 :/* 最大1/2 bombStr="bombs" defaultStr="default" messageStr="message" } print widthStr ;"(";MXX;"~";MX;")"; dim str menues(3)={"10","20","30"} menues(3)=defaultStr wx=selectMenu(widthStr,menues):// selectMenu()の最終項目は特別 if wx=3 then wx=2 wx=(wx+1)*10 print wx // input wx print heightStr;"(";MYY;"~";MY;")"; menues={"5","10","15","19"} repeat wy=selectMenu2(heightStr,menues) until wy<>-1 wy=5*(wy+1) print wy // input wy if wx<MXX then wx=MXX if wx>MX then wx=MX if wy<MYY then wy=MYY if wy>MY then wy=MY minbomb=MXX*MYY/8 :/* 最小1/8 maxbomb=wx*wy/2 :/* 最大1/2 print bombStr;"(";minbomb;"~";maxbomb")"; menues={"50","100","150","200"} seed=selectMenuWithMessage(bombStr,messageStr,menues) seed=50*(seed+1) print seed // input seed if seed<minbomb then seed=minbomb if seed>maxbomb then seed=maxbomb int sno=a_setPlayData("bomb11.aiff") a_play(sno) /* メインルーチン repeat /* 乱数初期化 srand2() /* 爆弾配置 all=BombSeed(seed) bomb=0 BombCount() dt=0:/* 経過時間 /* 初期画面表示 InitScreen() /* キー操作 ret=CursorMove() /* 終わり判定 if ret=-2 then break:/* 強制終了 switch ret case -1:/* やり直し MapPrintAll(YES):/* 全表示 break case 0: /* Game clear GameClear() break case 1: /* Game over MapPrintAll(YES):/* 全表示 GameOver() break endswitch /* 再開処理 locate(20,2) if isLocalizeJapan() then { print "《もう一度しますか?》"; setFunctionKey(0,"はい" ,CR) setFunctionKey(1,"いいえ",ESC) } else { print "<< Try Again ? >>"; setFunctionKey(0,"YES",CR) setFunctionKey(1,"NO" ,ESC) } displayFunctionKey(YES,0,1) repeat ret=inkey() until ret<>0 displayFunctionKey(NO,0,1) // タッチエリアの解除 // 一旦解除してから再設定しないと重なり続ける resetTouchArea() until (ret=ESC) a_end(sno):// 音声バッファー解放 if isLocalizeJapan() then { print "終了" } else { print "end" } end /***************************************************************** /* 関数群 /***************************************************************** func int CursorMove() /* カーソル移動&操作 int x,y,c int t /* 初期座標 /* 爆弾が無い座標に置く for x=0 to wx-1 for y=0 to wy-1 if ((map(x,y) and NOPBIT)<>BOMB) then goto "CM1" next next label "CM1" ts=time():/* 開始時間 while YES /* カーソル位置を反転表示 c=map(x,y) tatrb(ATRB_REVERSE) locate2(x,y) print printChr$(c); tatrb(ATRB_NORMAL) // キー入力待ちしながら時計を回す // int cnt=0 while (not kbhit()) /* キー入力の無い間 t=time() if t-ts>dt then { :/* 秒が変った dt=dt+1 PrintTime(dt) // beep2(0) // print "cnt=";cnt } // inc(cnt) endwhile /* カーソル位置を普通表示 locate2(x,y) print printChr$(c); // // キー操作判定 c=inkey() beep2(0) :// click sound switch c case &h1b: /* やり直し return(-1) /* カーソルは画面端でロールする case '2': /* ↓ if y<wy-1 then y=y+1 else y=0 break case '4': /* ← if x>0 then x=x-1 else x=wx-1 break case '6': /* → if x<wx-1 then x=x+1 else x=0 break case '8': /* ↑ if y>0 then y=y-1 else y=wy-1 break case '5': /* Check CheckMapPoint(x,y) MapPrint() /* チェックでは全開きにはならない break case ' ': /* Open if OpenMapPoint(x,y) then return(YES):/* game over /* 表示 if MapPrint() then return(NO) break endswitch endwhile return (YES) endfunc /***************************************************************** func int MapPrint() /* マップを表示する&仮想画面変更 /* リターン値:0=まだ全ては開いていない , 1=全部開いた int x,y,c int all0=0 for y=0 to wy-1 for x=0 to wx-1 c=map(x,y) if map0(x,y)<>c then { /* 画面に変更がある locate2(x,y) print printChr$(c) map0(x,y)=c:/* 仮想画面も変更 } /* 開いているポイントを数える if ((c and OPBIT)=OPBIT) then all0=all0+1 next next return(all0=all) endfunc /***************************************************************** func MapPrintAll(mode;int) /* マップ全表示 /* mode : 0=そのままで , 1=すべて開いて(間違い判定付き) int x,y,c str ls for y=0 to wy-1 ls="" for x=0 to wx-1 c=map(x,y) if mode then { if (c and OPBIT)=BMBIT then { /* 爆弾ありとしているが・・ /* そこに爆弾がなければ間違い if (c and NOPBIT)<>BOMB then c=ERR } c=(c or OPBIT):/* 開く } ls=ls+printChr$(c) next locate2(0,y) print ls next // color(7) endfunc /***************************************************************** func str printChr$(c;int) /* キャラクター表示 /* c : bit6,7 = 開き済み(11)/チェックマーク(10)/爆弾マーク(01)/閉じている(00) /* bit0-5 = マップ状態 &h00~&h3f str cs int cc=(c and OPBIT) if cc=0 then { /* 閉じている return ("□") } if cc=CHBIT then { /* CHBIT チェックマーキング中 return ("?") } if cc=BMBIT then { /* 爆弾ありマーキング中 return ("☆") } if cc=OPBIT then { /* 開いている switch (c and NOPBIT) case 0:cs= "・":break case 1:cs= "1":break case 2:cs= "2":break case 3:cs= "3":break case 4:cs= "4":break case 5:cs= "5":break case 6:cs= "6":break case 7:cs= "7":break case 8:cs= "8":break case 9:/* 間違い cs= "×" break case '*':/* 爆弾 cs= "★" break endswitch } return (cs) endfunc /***************************************************************** func locate2(x;int,y;int) locate(SX+(x)*xw,SY+y) :/* *xw for 全角文字 endfunc /***************************************************************** func WakuPrint(yoko;str,tate;str,kado;str,fall;int) /* マップ枠表示 int i /* 横線 str yokos="" for i=0 to wx-1:yokos=yokos+yoko:next locate2(0,-1):print yokos locate2(0,wy):print yokos /* 縦線 if fall then { // 内側も消す=速い str tates=tate+space$(wx*xw)+tate for i=0 to wy-1 locate2(-1,i):print tates; next } else { // 枠だけ=遅い for i=0 to wy-1 locate2(-1,i):print tate; locate2(wx,i):print tate; next } /* 角 locate2(-1,-1):print kado; locate2(-1,wy):print kado; locate2(wx,-1):print kado; locate2(wx,wy):print kado; endfunc /***************************************************************** func InitScreen() /* 初期画面表示 cls() WakuPrint("-","|","+",YES) MapPrintAll(NO) locate(5,0) if isLocalizeJapan() then { print using "マップ幅:##×## 爆弾数:###/### 時間:#####";wx,wy,bomb,seed,dt /* 0 1 2 3 4 /* +0123456789012345678901234567890123456789012 /* +locate } else { print using "map size:##×## bombs :###/### time:#####";wx,wy,bomb,seed,dt } str open$,exit$ if isLocalizeJapan() then { open$="開く" exit$="中断" } else { open$="open" exit$="exit" } int x=WX/2-18 int y=SY+wy+2 // 012345678901234567890123456789 locate(x,y+0):print " ┏━┓" locate(x,y+1):print " ┃↑┃" locate(x,y+2):print " ┗━┛" locate(x,y+3):print "┏━┓┏━┓┏━┓ ┏━━┓" locate(x,y+4):print "┃←┃┃?┃┃→┃ ┃";open$;"┃" locate(x,y+5):print "┗━┛┗━┛┗━┛ ┗━━┛" locate(x,y+6):print " ┏━┓" locate(x,y+7):print " ┃↓┃" locate(x,y+8):print " ┗━┛" int i=0 touchNo(inc(i))=setTouchAreaWithText(x+ 6,y ,xw*3,3,'8',YES,125,0,5,100) touchNo(inc(i))=setTouchAreaWithText(x+ 6,y+6,xw*3,3,'2',YES,125,0,5,100) touchNo(inc(i))=setTouchAreaWithText(x ,y+3,xw*3,3,'4',YES,125,0,5,100) touchNo(inc(i))=setTouchAreaWithText(x+12,y+3,xw*3,3,'6',YES,125,0,5,100) // touchNo(inc(i))=setTouchAreaWithText(x+ 6,y+3,xw*3,3,'5',YES,150,50, 5,120):/* check touchNo(inc(i))=setTouchAreaWithText(x+22,y+3,xw*4,3,' ',YES,150, 5 ,5,120):/* open touchCnt=i // setFunctionKey(0,exit$,ESC) displayFunctionKey(YES,0,0) endfunc func resetTouchArea() // タッチエリアの解除 int i for i=0 to touchCnt removeTouchArea(touchNo(i)) next touchCnt=0 endfunc /***************************************************************** func PrintBombCount() /* 残り爆弾数表示 locate(5+26,0) print using "###";bomb endfunc /***************************************************************** func PrintTime(dt;int) /* 経過時間表示 locate(5+42,0) print using "#####";dt endfunc /***************************************************************** func GameClear() /* ゲームクリア時画面表示 /* 枠の模様を代える beep() WakuPrint("◇","◇","◇",NO) beep() locate(6,1) if isLocalizeJapan() then { print "§§ おめでとう! あなたは総ての爆弾を捜し当てました §§"; } else { print "<< Congratulations! You've turned up the bomb of all >>"; } endfunc /***************************************************************** func GameOver() /* ゲームオーバー時画面表示 /* 枠の模様を代える a_play(sno) WakuPrint("☆","☆","☆",NO) a_play(sno) locate(10,1) if isLocalizeJapan() then { print "@@ あなたは爆弾にぶち当たってしまいました @@"; } else { print "@@ You've hit a bomb @@"; } endfunc /***************************************************************** func CheckMapPoint(x;int,y;int) /* マップ上のポイントをチェックする int c c=map(x,y) c=(c and OPBIT) if c=OPBIT then { /* すでに開いている /* 開いている所を調べることは不用 beep() return() } if c=0 then { /* 閉じている -> 爆弾ありそう map(x,y)=(BMBIT or map(x,y)) bomb=bomb+1 PrintBombCount() return() } if c=BMBIT then { /* 爆弾ありそう -> チェックしてね map(x,y)=(c and NOPBIT)or CHBIT return() } if c=CHBIT then { /* チェックしてね -> 閉じる map(x,y)=(NOPBIT and map(x,y)) bomb=bomb-1 PrintBombCount() } endfunc /***************************************************************** func int OpenMapPoint(x;int,y;int) /* マップ上のポイントを開く int c c=map(x,y) if ((c and OPBIT)=OPBIT) then { /* すでに開いている /* 開いているところを再度開くことは不用 beep() return(NO):/* 警告以外は何もしない } if ((c and NOPBIT)=BOMB) then { /* 爆弾を開けてしまった a_play(sno) return(YES):/* game over } /* そこはまだ開いていない所なので開ける if (c=0) then { /* 周りに爆弾がない所ならペイント型で開く PaintMap(x,y) } else { /* 周りに1つでも爆弾がある時は1ポイントだけ開ける map(x,y)=(OPBIT or map(x,y)):/* 開けた印 } return(NO) endfunc /***************************************************************** func PaintMap(x;int,y;int) /* マップの(x,y)から0の点を開く /* 基本的にはペイントと同じルーチンになるが、境界まで開くのが違う int c,xs,xe if map(x,y)<>0 then { /* 最初の点が0でなければ終わり return() } /* 0 <- x : 左サーチ xe=x+1 :/* 右へ捜し始めるポイント while x>=0 c=map(x,y) if ((c and OPBIT)=0) then { map(x,y)=(OPBIT or map(x,y)) } if (c<>0) then break:/* 境界 /* 境界も開かれる // 境界は爆弾ではない。/ border is not bomb // なぜなら爆弾の周りには1~8が必ずあるから。 x=x-1:/* 左へ endwhile if x<0 then xs=0 else xs=x /* xs=線分左端(境界も含む) /* x -> wx-1 : 右サーチ while xe<=wx-1 c=map(xe,y) if (c and OPBIT)=0 then map(xe,y)=(OPBIT or map(xe,y)) if c<>0 then break:/* 境界 xe=xe+1 :/* 右へ endwhile if xe=wx then xe=xe-1 /* xe=線分右端(境界を含む) if y>0 then PaintMapSub(xs,xe,y-1):/* 上チェック if y<wy-1 then PaintMapSub(xs,xe,y+1):/* 下チェック endfunc /***************************************************************** func PaintMapSub(xs;int,xe;int,yy;int) /* PaintMap()サブルーチン:上下チェック用 int x,c for x=xs to xe c=map(x,yy) if c=0 then { PaintMap(x,yy) } else { if (c and OPBIT)=0 then map(x,yy)=(OPBIT or map(x,yy)):/* 境界も開く } next endfunc /***************************************************************** func int BombSeed(seeds;int) /* マップ内に爆弾をまく /* seeds : 爆弾個数 < wx*wyにすること /* 乱数の初期化は外部で行なうこと int x,y int all /* マップクリア for y=0 to wy-1 for x=0 to wx-1 map(x,y)=0 next next /* 要開き数:爆弾以外すべて all=wx*wy-seeds /* 爆弾配置 while seeds>0 x=rand2(wx) y=rand2(wy) if map(x,y)=0 then { /* 爆弾を置く map(x,y)=BOMB:/* マップ map0(x,y)=BOMB:/* 仮想画面 seeds=seeds-1 :/* 残りを1つ減らす }:/* そこにすでに爆弾がある時は別の場所を探す endwhile return(all) endfunc /***************************************************************** func BombCount() /* マップ内の爆弾状況を書き込む /* 各ポイント毎の周りの爆弾の数をあらかじめ書き込む int x,y,xx,yy,xs,ys,xe,ye,c for y=0 to wy-1 ys=y-1:if ys<0 then ys=0 ye=y+1:if ye>wy-1 then ye=wy-1 for x=0 to wx-1 if map(x,y)=BOMB then continue:/* 爆弾の所はスキップ xs=x-1:if xs<0 then xs=0 xe=x+1:if xe>wx-1 then xe=wx-1 /* 周りをカウント c=0 for yy=ys to ye for xx=xs to xe if map(xx,yy)=BOMB then c=c+1 next next /* c=0~8 map(x,y)=c:/* マップ map0(x,y)=c:/* 仮想画面 next next endfunc /***************************************************************** /* 汎用関数 /***************************************************************** func srand2() /* rand()乱数を初期化する int tm=time() tm=tm and &h0fff tm=tm * 16 srand(tm) endfunc func rand2(seed;int) return (rand() mod seed):/* 0~seed-1の乱数を発生 endfunc /*****************************************************************音声ファイル入り圧縮ファイル: XBbs.zip