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

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

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

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

Q&A

解決済

3回答

4064閲覧

なぜforとwhileを同時に使うか

maleon

総合スコア12

JavaScript

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

0グッド

0クリップ

投稿2020/04/14 12:17

編集2020/04/14 13:03

前提・実現したいこと

・javaScriptでマインスイーパーを作る
・ネットで拾ったソースコードを見ながら、自分でコードを組み直した

発生している問題・エラーメッセージ

ソースコード'addBom'関数の箇所 なぜfor文とwhile文を併用するのか分かりません。 forもwhileも書き方が違うだけ、「条件式がtrueの間、定められた処理を行う」ということは同じ、 と理解しているのですが... while文だけでは記述できないでしょうか?

該当のソースコード

javascript

1<!DOCTYPE HTML> 2<html> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 6 <title>デモ マインスイーパー</title> 7 <link href="https://fonts.googleapis.com/css?family=M+PLUS+1p:400,500" rel="stylesheet"> 8 <link href="demo-minestyle.css" rel="stylesheet"> 9 <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous"> 10 11</head> 12 13<body> 14 <div id="stage"></div> 15 16<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script> 17<script> 18'use strict'; 19 20var bom = [9, 9, 10]; //[ブロックの行数,ブロックの列数,爆弾の数] 21var bomPosi = []; //爆弾の位置を格納する配列 22var gameFlg = true; //ゲームの進行状態 true/通常 false/ゲームオーバーorクリアー 23 24//ブロックの追加 25function addBlock(){ 26 for(let i = 0; i < bom[0]*bom[1]; i++) { 27 $('<div></div>').appendTo('#stage'); 28 } 29} 30 31//爆弾の配置 32**function addBom(){ 33 for(let i = 0; i < bom[2]; i++){ 34 while(true){ 35 var randomNum = Math.floor( Math.random() * (bom[0]*bom[1]+1) ); /* 0~81の中から乱数を取得 */ 36 if(!bomPosi.includes(randomNum)){ //配列bomPosiにrandomNumが含まれていなければ 37 bomPosi.push(randomNum); //配列bomPosiにrandomNumを追加 38 $('#stage div').eq(randomNum).addClass('bomb'); 39 break; 40 } 41 } 42 } 43}** 44 45//周囲の爆弾チェック 46function checkBom(n){ 47 var countBom = 0; 48 49 //一番左端でなければ 50 if(( n % bom[1] ) != 0){ 51 //左チェック 52 if($('#stage div').eq(n-1).hasClass('bomb')){ 53 countBom ++; 54 } 55 //一番上端でなければ 56 if( n >= bom[1]){ 57 //左上チェック 58 if($('#stage div').eq(n-bom[1]-1).hasClass('bomb')){ 59 countBom ++; 60 } 61 } 62 //左下チェック 63 if($('#stage div').eq(n+bom[1]-1).hasClass('bomb')){ 64 countBom ++; 65 } 66 } 67 //一番右端でなければ 68 if(( n % bom[1] ) != bom[1]-1){ 69 //右チェック 70 if($('#stage div').eq(n+1).hasClass('bomb')){ 71 countBom ++; 72 } 73 //一番上端でなければ 74 if( n >= bom[1]){ 75 //右上チェック 76 if($('#stage div').eq(n-bom[1]+1).hasClass('bomb')){ 77 countBom ++; 78 } 79 } 80 //右下チェック 81 if($('#stage div').eq(n+bom[1]+1).hasClass('bomb')){ 82 countBom ++; 83 } 84 } 85 //一番上端でなければ 86 if( n >= bom[1]){ 87 //上チェック 88 if($('#stage div').eq(n-bom[1]).hasClass('bomb')){ 89 countBom ++; 90 } 91 } 92 //下チェック 93 if($('#stage div').eq(n+bom[1]).hasClass('bomb')){ 94 countBom ++; 95 } 96 return countBom; 97} 98 99//ゲームオーバー時の処理 100function gameover(){ 101 $('.bomb').html('<i class="fas fa-bomb"></i>'); //.bombのタイルに爆弾を表示させる 102 $('.bomb').css('background-color','#ffff00'); //.bombの背景色を変更 103 alert("ゲームオーバー!"); 104 gameFlg = false; //ゲーム進行の変数をfalseに 105} 106 107//ゲームクリアーのチェック 108function clearCheck(){ 109 var cnt = $(".open").length; //現在開かれているタイル数を調べる 110 if(cnt >= (bom[0]*bom[1]-bom[2])) { //開かれているタイルが爆弾を除いたタイルの総数以上になったら 111 alert('クリアー!') 112 gameFlg = false; //ゲーム進行の変数をfalseに 113 } 114} 115 116$(function(){ 117 118 $('#stage').width(bom[1] * 20); //ステージサイズの設定 119 addBlock(); //ブロック生成 120 addBom(); //爆弾のclass付与 121 122 //タイルをクリックしたら 123 $('#stage div').on("click", function(){ 124 if(gameFlg == true){ //ゲームが進行状態ならば(ゲームオーバーorクリアー以外) 125 var index = $('#stage div').index(this); //クリックしたタイルの順番を取得 126 var countBom = checkBom(index); //周囲の爆弾数を調べcountBomに代入 127 $(this).addClass('open'); //クリックしたタイルに.openを付与 128 $(this).text(countBom); //タイルに周囲の爆弾数を表示 129 clearCheck(); //ゲームクリアーの判定 130 } 131 }); 132 133 //爆弾のタイルをクリックしたら 134 $('.bomb').on("click", function(){ 135 if(gameFlg == true){ //ゲームが進行状態ならば(ゲームオーバーorクリアー以外) 136 gameover(); //ゲームオーバーを実行 137 } 138 }); 139}); 140 141</script> 142 143</body> 144</html> 145``` 146 147 148### 試したこと 149 150太字の箇所を下のコードのように記述しました。 151```javaScript 152function addBom(){ 153 let i = 0; 154 while(i <= bom[2]){ 155 var randomNum = Math.floor(Math.random()*bom[0]*bom[1] +1); 156 if(!bomPosi.includes(randomNum)){ 157 bomPosi.push(randomNum); 158 $('#stage div').eq().addClass('bomb'); 159 i++; 160 } 161 } 162}; 163``` 164 165 166こうすると、爆弾が各マスに配置されません。 167元のソースコード通りだと、ランダムに10個のマスに、爆弾が配置されるのですが。 168 169### 補足情報(FW/ツールのバージョンなど) 170 171ここにより詳細な情報を記載してください。

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

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

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

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

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

y_waiwai

2020/04/14 12:19

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
maleon

2020/04/14 13:05

失礼しました。 はじめての質問で、使い方を理解できていませんでした。 <code>ボタンを使って質問を編集しました。
guest

回答3

0

ベストアンサー

ソースが読みづらい(マークダウンになってない)のでその部分は読まずに回答しますが

なぜfor文とwhile文を併用するのか分かりません。
forもwhileも書き方が違うだけ、「条件式がtrueの間、定められた処理を行う」ということは同じ、

と理解しているのですが...

機能的にforとwhileが違う点は仰る通り多くありません。
forが基本的に決められた長さ分カウンタを回す処理なのに対し、whileは決められた終了条件を満たすまでループする処理である、というだけです。

当然whileでも自前でカウンタ回せば同じことはできますが、forがあるならforを使った方が、わざわざ自前でインクリメント等する必要がないので楽です。逆にその「特定の長さ」が終了条件にならない場合や、意図して無限ループを使いたい場合はwhileを使うことになると思います。

forを使うメリットとしては、配列の長さなど基本的には終了条件が存在しており、ちょっとした終了条件の書き間違いで無限ループに陥るというバグを減らせる点だと思います。

while文だけでは記述できないでしょうか?

できると思いますが、それが書きやすいか、読みやすいかは人によると思います。

投稿2020/04/14 12:28

gentaro

総合スコア8949

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

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

maleon

2020/04/14 13:38

ありがとうございます! forが存在する意味がイマイチ理解できなかったのですが、そんなメリットがあるわけですね。
maleon

2020/04/14 13:58

やっと、なんとなく分かりました。 今回は10回決まった処理を行うことにしており、「10回繰り返す」ことを規定するためにfor文を使う。 で、1回の処理で行う内容は、while文を使って規定しているわけですね。
guest

0

書き直した後のコードでは、ifのブロックの中にi++が入ってしまっているので、もとのforとは別なコードになっています。

投稿2020/04/14 12:20

maisumakun

総合スコア145183

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

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

maleon

2020/04/14 13:53

ありがとうございます! 確かにそうですね。 気付きませんでした
guest

0

for文とwhile文の違いに関して回答します。

for文;(セミコロン)で初期処理、継続条件、ループ区切り時の処理の3点セットを区切りながら定義したものです。
for (初期処理; 継続条件; ループ区切り時の処理) {ループ毎の処理}

for文は;で区切らなければなりませんが、
for (; true;)という風に不要な箇所は空欄に出来ます。

while文は継続条件のみを記した構文です。
while (継続条件) {ループ毎の処理}

つまり、while文はやっている事が少ないだけなので、
「初期処理」と「ループ区切り時の処理」を記述すれば等価になります。

js

1for (var i = 0; i < 10; i++) { 2 console.log(i); 3} 4 5// 上記のforと同じ事をwhileでやるとこうなる 6var i = 0; 7while (i < 10) { 8 console.log(i); 9 i++; 10}

それではforとwhileのどちらを使うべきかを考えていきます。

for文は「初期処理」「継続条件」「区切りの処理」の3点セットです。
そしてこの3点セットは多くのケースで必要です。

それが1行にぎゅっと凝縮されているので
for文の行をちらっと見ただけで何をしたいループなのか判別出来ます。
つまり読みやすいわけですね。

プログラムは後からコードを読んで修正するという作業が発生しやすいものですので、
読みやすいという観点は非常に重要になってきます。


逆にwhile文を使った方が良い場合は、
for文の「初期処理」や「ループ区切り時の処理」を省きたいケースです。

先程for (; true;)でも実行出来るんだよと説明しましたが、
3点セットの2つを省略してまでfor文にこだわるくらいなら、
継続条件のみが定義されているwhile (true)と記述した方が用途に合致していて美しいです。

whileを使うべき場面は中々ありませんが、
記憶の片隅にちらっと覚えておくと良いかもしれませんね。

投稿2020/04/14 14:04

miyabi-sun

総合スコア21158

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

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

maisumakun

2020/04/14 14:25

無限ループはfor(;;)とも書けますが、「省略すると無限ループ」というのも、知らないとわからないことですね。
maleon

2020/04/15 09:45

ありがとうございます! 何となくwhileを使うことが多かったのですが、確かに全体的に見ると、for文の方がスッキリしていて見やすいですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問