質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

770閲覧

グリッド マス目表 ランダムの位置に画像を配置

williamsArk

総合スコア46

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2019/03/04 16:21

Javascript初心者の練習として、今ゲーム(マインスイーパー)を作っています。
縦横の線を引いて、クリックしたら「スタンプ」がつくところまでは行きました。
しかし、10*10のグリッドの中に、ランダムで爆弾を配置したいのですが、詰まってます。
一番下にbombCreationの関数を作って、とりあえずrowの配列にcolの配列を詰め込んだ状態にはして、
tiles[row][col]で何番目のタイルをクリックしたか(左上が0番目、右下が99番目)を得られるかなと思ったのですが、
仮にそれがうまくいったとしても、爆弾をどのようにランダムに表の中に混ぜ込むかに苦戦しています。
引数で(row,col)として、後々tiles[Math.random()][Math.random()]みたいにできるかなとも思ってますが。。。
アドバイスいただければ幸いです。

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Game</title> <link rel="css/styles.css"> </head> <body> <button onclick ="init();">クリアする</button> <br> <br> <canvas id="MyCanvas" style="padding:0;"></canvas> <div id="location"></div> <script> var canvas; var ctx; var canvas_magnification = 50; //表示倍率 var canvas_width = 10; //横マスの数 var canvas_height = 10; //縦マスの数 var canvas_pushed = false; //キャンバスのマスが押されているかどうか var bomNumber = 10; // 初期の見た目の設定 function init() { ctx.fillStyle = "rgb(255, 255, 255)"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawLines(); } function place(x, y) { var col = (Math.floor(x / canvas_magnification) + 1) + '番目'; var row = (Math.floor(y / canvas_magnification) + 1) + '番目'; document.getElementById('location').textContent = '上から ' + row + ' 左から ' + col; } // 線を引く関数 function drawLines() { // 色 ctx.strokeStyle = "#FF82B2"; // 太さ ctx.lineWidth = 2; ctx.beginPath(); //縦の線 for (var i = 0; i < canvas_width + 1; i++){ ctx.moveTo((i * canvas_magnification), 0); ctx.lineTo((i * canvas_magnification), canvas.height); } //横の線 for (var i = 0; i < canvas.height + 1; i++){ ctx.moveTo(0, (i * canvas_magnification)); ctx.lineTo(canvas.height, (i * canvas_magnification)) } ctx.stroke(); } //座標の位置を把握 document.addEventListener("click", function(e) { var rect = e.target.getBoundingClientRect(); mouseX = e.clientX - rect.left; mouseY = e.clientY - rect.top; var col = Math.floor(mouseX / canvas_magnification); var row = Math.floor(mouseY / canvas_magnification); var img = new Image(); img.src ="img/clear.jpg"; ctx.drawImage(img, col * canvas_magnification, row * canvas_magnification, canvas_magnification, canvas_magnification) ; // ctx.fillStyle = "rgb(150, 0, 0)"; // ctx.fillRect(col * canvas_magnification, row * canvas_magnification, // canvas_magnification, canvas_magnification); // ctx drawLines(); }); window.onload = function() { canvas = document.getElementById('MyCanvas'); canvas.width = canvas_width * canvas_magnification; canvas.height = canvas_height * canvas_magnification; ctx = canvas.getContext('2d'); init(); } function bombCreation(row, col){ var row, col; var tiles; for(row = 0; row < canvas_height; row++) { tiles[row] = []; for(col = 0; col < canvas_width; col++) { tiles[row][col] = row * canvas_width + col; } } } </script> </body> </html>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/03/04 16:52

クリックされたとき、まず canvas 要素なのか?で弾かないとまずそう。 そのクリック処理の最後の drawLines(); はいらないよね。 もしよければ図が表示されるように以下のようにしてみる。 そうすれば、コピペだけで検証しやすくなるよ。 img.src=[ "data:image/gif;base64,", "R0lGODlhHgAeAIEAANwAAAD/AP/78AAAACH5BAEAAAEALAAAAAAeAB4AAAimAAMIHEgwAICDCA8WXMjQ", "4EEBECNCRNiQIYCICRNirDjwoYCMIC9+BFBRZMiTJi1ORHly4sKLLFl+LAgzpkySAk3aROnS4MidPHHW", "BNqS5FCiRY8iBTmyqcSnUKE+nCoyqtWnVJ1e3do0K9etWZcGVSoW4UyyYmf6LJtRrU62PdeyhUnz51K1", "BN8SjZt3JVC+NPW2HMkxJ8aQGwt39ChVoeKXIQsHBAA7" ].join ('\n')
williamsArk

2019/03/04 17:08

アドバイスいただきましてありがとうございました。 初心者なのでいただいた情報が難しいですね。これはどういった処理になるのでしょうか?
guest

回答2

0

ベストアンサー

javascript

1let line = Array (canvas_width * canvas_height);//直線の配列をイメージ 2line.fill (true, 0, bomNumber);//最初のn個を爆弾にする 3line.fill (false, bomNumber);// それ以降は爆弾はなし 4line.sort (()=>Math.random()-.5);//疑似ランダムに並び替える 5 6//横の幅の数だけ切り取って重ねていくイメージ 7//ラインは破壊される 8let tiles = [...Array(canvas_height).keys()].map (_ => line.splice (0, canvas_width)); 9 10console.log (tiles);

canvas 以外を弾く

javascript

1//座標の位置を把握 2document.addEventListener("click", function(e) { 3 if ('CANVAS' !== e.target.tagName) return; 4 ...

文字列で図形を描く

javascript

1 var img = new Image(); 2 img.src = [ 3 "data:image/gif;base64,", 4 "R0lGODlhHgAeAIEAANwAAAD/AP/78AAAACH5BAEAAAEALAAAAAAeAB4AAAimAAMIHEgwAICDCA8WXMjQ", 5 "4EEBECNCRNiQIYCICRNirDjwoYCMIC9+BFBRZMiTJi1ORHly4sKLLFl+LAgzpkySAk3aROnS4MidPHHW", 6 "BNqS5FCiRY8iBTmyqcSnUKE+nCoyqtWnVJ1e3do0K9etWZcGVSoW4UyyYmf6LJtRrU62PdeyhUnz51K1", 7 "BN8SjZt3JVC+NPW2HMkxJ8aQGwt39ChVoeKXIQsHBAA7" 8].join ('\n');

Array( w ).fill( 0 ).map(
できるだけ短くプログラムを書きたいときに使います
for (let i = 0; i < xxx.length) { ...
長ったらしくなるし、変数もつかう。

Array(x).map ((i)=> ...
これだと x 回どころか1度もループしない。

Array(x).fill(0).map ((i)=>
ところがこうすると x 回ループするってこと。
しかもそれ以降では i さえも使われてないでしょ?
変数 i は、儀礼的なもの。

投稿2019/03/04 17:14

編集2019/03/04 19:17
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

williamsArk

2019/03/04 17:23 編集

はあ流石ですね。皆さんは一体プログラミングをどれくらいやっているのでしょうか?4ヵ月程度じゃダメでしょうか ここまで滑らかにコードが浮かぶのは何年も努力が必要なのか、それとも才能でしょうかね。 頭が固いとやっぱりダメなのでしょうか。 ともかく参考になりました。感謝いたします。
退会済みユーザー

退会済みユーザー

2019/03/04 17:29

がんばっ!
williamsArk

2019/03/05 17:06

時間が見つからなかったため、今現在昨日頂いた回答コードを見直しています。BAを決める前にできればもう1つだけ教えてください。 console.log(tiles)で確かにArrayが10個並んでるのがわかりました。 そこで console.log(tiles[2][5])←適当な数を入れてみたら、falseやtrueがランダムに変わっていました。これはfalseは爆弾なしでtrueは爆弾あり、がランダムに決まっているということですか? if(tiles[canvas_height][canvas_width] === true){ alert('爆弾です'); } このように書くことは可能でしょうか?canvas_height/widthが可能かが不明点です。
退会済みユーザー

退会済みユーザー

2019/03/05 23:02 編集

canvas_width と canvas_height の値は、そのタイルの幅と高さの値。 その値未満であれば、OKですよ 余計なことかもしれませんが、なるべくグローバル変数の使用を控える。 変数名は理解しやすい名前を付ける 個々の処理は、なるべく細分化し再構築しておおまかに機能するようにする 入力部分、tilesに関する処理、出力処理を関数にわけて作るイメージです そうすれば、いずれSVGで処理したくなったとき変更部分が出力処理の部分だけで済みます。 そしてなによりも、他者からの改変(いろいろなライブラリを組み合わせると動かなくなるような、脇のあまいプログラム)に強く、仕様の変更が容易いプログラムを書くように心がけてください。 ショートコーディングするのはその後です。w たまにつまずいたら、出来上がっていく過程を見せてくださいね。 いまの状態だと・・・厳しくツッコミできないっす!
退会済みユーザー

退会済みユーザー

2019/03/05 23:05

それと<br><br>やりたいことはわかるのですが、それはダサい。
williamsArk

2019/03/08 11:17

大変お世話になりました。ありがとうございました。
guest

0

「爆弾がある場所」を最初に指定して置くとかどうでしょう。

js

1const w = 3, h = 3, bomb = 3; 2const grid = Array( w ).fill( 0 ).map( e => Array( h ).fill( 0 ) ); 3let i = 0, wx, hx; 4while( i < bomb ) { 5 wx = Math.floor( Math.random () * w ); 6 hx = Math.floor( Math.random () * h ); 7 if ( grid[ wx ][ hx ] === 0 ) { 8 grid[ wx ][ hx ] = 1; 9 i++; 10 } 11} 12console.dir( grid ); 13/* 14例えば if ( grid[ よこ ][ たて ] === 1 ) で爆弾かどうか判別する 15*/ 16```**動くサンプル:**[https://jsfiddle.net/0gymw28t/](https://jsfiddle.net/0gymw28t/) 17 18--- 19 20【Array.prototype.fill() - JavaScript | MDN21[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) 22 23【Array.prototype.map() - JavaScript | MDN24[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) 25 26Math.random() - JavaScript | MDN27[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/random)

投稿2019/03/04 17:02

kei344

総合スコア69364

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

williamsArk

2019/03/04 17:21

詳しい説明と参考ページをご紹介していただきましてありがとうございました。 mapという用法を初めて拝見いたしました。奥が深いですね。 参考ページも見させていただきましたが、もしよろしければ Array( w ).fill( 0 ).map( e => Array( h ).fill( 0 ) ); ここの用法(やってることなど)をもう少し説明いただけませんか?
williamsArk

2019/03/04 22:55

Array( w ).fill( 0 ).map( e => Array( h ).fill( 0 ) ); Array(w或いはh)とは、その数値分だけの配列を作るということですよね? fill(0)の意味・役割と、アロー関数前の(e=>について教えて頂けると幸いです。
kei344

2019/03/05 02:47

Array( n ) は配列のサイズだけ決める物なので、その時点で中身はありません。mapなど配列関数は中身全てに対して操作する物が多いので、.fill( 0 )を使って中身に物をつめてから処理をしています。(今回は使わないので中身は入っていれば良いので、0でも1でも何でも良い) eはfillされた0が入っていますが、使っていないだけです。「() =>」書くより文字数が少ないのでそう書いているだけです。
williamsArk

2019/03/05 17:00

これはJQueryってやつですか。Javascriptだけだと色々と力不足に感じてしまいますね。なんとか少しずつこういう技術を身につけていくほかはないのですね。ありがとうございました。
kei344

2019/03/05 17:06

>JQuery 違います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問