- ベストアンサー
船のゲームを作っているのですが...
子供がゲームを作ってくれというので簡単な物を作ろうと試みています。内容はランダムで15*15グリッドのマスを作り、船はフリゲート艦…2マス、給士船…2マス、駆遂船…3マス、巡洋艦…3マス、母艦…4マス分を表示させるようにして且つ、上記の船はほかの船とオーバーラップしないようにしたいです。ちなみに横列は1-15、縦列はA-Oとしたいです。またプレイヤーが船を追撃させたか、ミスしたかをレポートもしたいです。ヒットした場合、ヒットした場所レポートしたいです。プレイヤーは60発の弾をもっていて60発使い切る前に全て沈没させたら勝ちとします。ゲームの終わりには、撃たれて沈没していない船を表示させる。という感じにしたいです。もう1週間くらい書いては直して書いては直しての連続です。ここに私が書いたプログラムを載せようと思ったのですが、どうも文字数の関係でしょうか?無理なようです。もっと効率的にやれば文が短くなると思うんですが、初心者の私には難しいです。どなたかこのようなゲームつくりに詳しい方教えてください。お願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ヒント <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=SHIFT_JIS"> <title>海戦ゲーム</title> <style> <!-- table.field td{ width:20px; height:20px; text-align:center;vertival-align:middle; } //--> </style> <script type="text/javascript"> <!-- var FIELD_SIZE=15; var BULLET =60; var HIT ="*"; var NEAR="○"; var FAULT="・"; var SEA=" "; function init(){ STATUS.BULLET.value =BULLET; STATUS.MESSAGE.value=""; } window.onload=init; var ships = [ { kind:"母艦", size:4, x:-1, y:-1, dir:-1, alive:true }, { kind:"巡洋艦", size:3, x:-1, y:-1, dir:-1, alive:true }, { kind:"駆逐船", size:3, x:-1, y:-1, dir:-1, alive:true }, { kind:"給仕艦", size:2, x:-1, y:-1, dir:-1, alive:true }, { kind:"フリーゲート艦", size:2, x:-1, y:-1, dir:-1, alive:true } ]; var shipCount=ships.length; //FIELD_SIZE*FIELD_SIZEのフィールド(内部モデル)を作成 var field = new Array(FIELD_SIZE); for(var i=0;i<FIELD_SIZE;i++){ field[i]=new Array(FIELD_SIZE); for(var j=0;j<field[i].length;j++) field[i][j]=SEA; } //海に、船を置く for(var i=0;i<ships.length;i++) putShip(ships[i]); function putShip(ship){ var pos, dir; do{ pos = makePos(); dir=makeNumber(2); //0 or 1 : 0 は 横、1 は縦 }while(haveSpace(pos, dir, ship.size)==false);//スペースが無いならやり直し ship.x =pos.x; ship.y =pos.y; ship.dir=dir; for(var i=0;i<ship.size;i++){ if(dir==1) field[pos.x+i][pos.y] =ship.kind.substr(0,1); else field[pos.x ][pos.y+i]=ship.kind.substr(0,1); } } function haveSpace(pos, dir, size){ for(var i=0;i<size;i++){ if(dir==1){ if(pos.x+i>=FIELD_SIZE || field[pos.x+i][pos.y]!=SEA)return false; } else{ if(pos.y+i>=FIELD_SIZE || field[pos.x][pos.y+i]!=SEA)return false; } } return true; } function makePos(){ do{ this.x = makeNumber(FIELD_SIZE); this.y = makeNumber(FIELD_SIZE); }while(field[this.x][this.y]!=SEA); return (this); } function makeNumber(n){ var x; while(n==(x=Math.floor(Math.random()*n))); //random:0<=x<=1 return (x); } function xy2f(x, y){ //field(x,y) to "Fnnmm" x= (x < 10)? "0"+x : x.toString(); y= (y < 10)? "0"+y : y.toString(); return ("F"+x+y); } function f2xy(f){ //"Fxxyy"→(x,y) this.x = eval(f.substr(1,2)); this.y = eval(f.substr(3,2)); return this; } function shot(cell){ if(STATUS.BULLET.value > 0 && shipCount > 0){ document.getElementById(cell.id).innerHTML=judge(cell); STATUS.BULLET.value=parseInt(STATUS.BULLET.value)-1;//弾を消費 shipCount=0;//生きてる船を数え直す for(var i=0;i<ships.length;i++){ if(alive(ships[i]))shipCount++; } if(shipCount==0) STATUS.MESSAGE.value="敵艦隊は全滅しました"; if(STATUS.BULLET.value == 0 || shipCount == 0) dispAll(); } } function alive(ship){ for(var i=0;i<ship.size;i++){ if(ship.dir==1){ if(field[ship.x+i][ship.y]!=HIT)return true; } else{ if(field[ship.x][ship.y+i]!=HIT)return true; } } return(ship.alive=false);//alive検査の中で、セットされることに注意 } function judge(cell){ var pos=new f2xy(cell.id); // alert(cell.id+",x:"+pos.x+",y:"+pos.y); if(field[pos.x][pos.y]!=SEA){ field[pos.x][pos.y]=HIT; STATUS.MESSAGE.value="命中"; return(HIT); } if(nearPos(pos)){ STATUS.MESSAGE.value="近弾"; return(NEAR); } STATUS.MESSAGE.value="はずれ"; return(FAULT); } function nearPos(pos){ for(var i=-1;i<=1;i++){ for(var j=-1;j<=1;j++){ if(j==0 && i==0) continue; if(pos.x+i < 0 || FIELD_SIZE <= pos.x+i )continue;//フィールド外 if(pos.y+j < 0 || FIELD_SIZE <= pos.y+j )continue;//フィールド外 if(field[pos.x+i][pos.y+j]!=SEA) return(true); } } return(false); } function dispAll(){ for(var i=0;i<FIELD_SIZE;i++){ for(var j=0;j<FIELD_SIZE;j++){ if(field[i][j]!=SEA) document.getElementById(xy2f(i,j)).innerHTML=field[i][j]; } } } //--> </script> </head> <body> <p> この海域に、敵艦隊が潜んでいます。ミサイルで撃破して下さい。<br> 命中すると「*」近くに落ちると「○」はずれると「・」が表示されます<br> もう一度やる時は、リロードして下さい。<br> </p> <script type="text/javascript"> document.write("<p>"); for(var i=0;i<ships.length;i++) document.writeln(ships[i].kind +"1隻 全長:"+ships[i].size+"<br>"); document.write("の船がいます<br></p>"); </script> <table class="field" border="1" cellspacing="0" bordercolor="black"> <script type="text/javascript"> //FIELD_SIZE*FIELD_SIZEのマスを作る for(var i=0;i<FIELD_SIZE;i++){ document.writeln("<tr>"); for(var j=0;j<FIELD_SIZE;j++){ document.write("<td id='"+ xy2f(i,j)+"' onclick='shot(this)'> </td>"); } } </script> </table> <form name="STATUS"> 残弾:<input name="BULLET" type="text" value="60" size="2" READONLY> 情報:<input name="MESSAGE" type="text" value="" size="20" READONLY> </form> </body> </html>
その他の回答 (2)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
field[15][15] のような配列で"場"を準備して、 種類によってF(フリーゲート艦)とかキャラクタを設定するとか1とか種類をあらわす数字を設定するようにすれば良いかと思います。 配置が正しいモノであるかどうか(連接するべきであるとか、マスからはみ出さない、他の艦にかぶらない)などは、その時々の状況によって適当な関数を使って検査するようにすればいいかと思います。 ヒットした場所や縦横のインターフェースなどは、プログラムで適当に、内部の状態と対応させてやればいいです。 まあ、やりたいようにやるのが一番かと思いますが、 いきなり全部やろうとするのではなくて、 1つ1つ実現するようにしていった方がいいのではないかと思います。 大きくはトップダウンで物事を考えていくと方向性が決めやすいのではないかと思います。 また、「こうしたい」、「教えてくれ」ではプログラムの作成を依頼しているのと同じなので、そういうものは、OKWebでは、禁止されていまし、 また、あれもこれもでは、回答する方も、結局1つのアプリケーションを作るのと同じになり大変ですので、回答も付きにくくなります。 できたら、1つの処理に限って、こうしたいと思ってこうしたがうまくいかない、どうすればいいかというような質問をされるのがよろしいかと思います。 質問文には、長い文章は載せることはできませんが、補足には、長い文章を載せることができます。 懸案の部分を補足してください。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
何が知りたいのかがわかりません。