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

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

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

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

Q&A

解決済

3回答

2316閲覧

マインスイーパの周囲の爆弾の数を数える関数count()について

Tanakakko

総合スコア11

JavaScript

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

0グッド

1クリップ

投稿2019/06/12 09:40

前提・実現したいこと

現在javascriptでマインスイーパーを作成しております。
しかし、参考にしている本のコード解説だけでは意味がわからない箇所があります。
for分の条件式let j= y-1; j<=y+1; j++
そして、cell[j] && cell[j][i]の部分です。

該当のソースコード

Javascript

1let cell: Cell[][]=[]; 2function count(x: number,y: number){ 3 let b =0; //爆弾の数 4 for(let j= y-1; j<=y+1; j++){ 5 for(let i =x-1; i<=1; i++){ 6 if (cell[j] && cell[j][i]){ 7 if(cell[j][i].bomb) b++; 8 } 9 } 10 } 11 return b; 12}

参考図


このような図とともに「if(cell[j]&&cell[j][i])」は、iとjがマス目の外になった場合、たとえば、jが1のような場合に、爆弾を数えないようにするための処理。という記述がありました。
しかしこの意味がわかりません。どうかご回答願います。

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

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

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

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

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

guest

回答3

0

ベストアンサー

i = x-1; i<=1; i++ について

質問では

for分の条件式let j= y-1; j<=y+1; j++

がわからないとありますが、他の回答に対するコメントを読むとi = x-1; i<=1; i++の方のようなのでこちらについて。
参考にされている本にこれが書かれているのであれば、誤植です。正しくは

js

1for (let i = x - 1; i <= x + 1; i++) {

です。

cell[j] && cell[j][i] について

3x3 のマインスイーパーを考えてみます。

cell[0][0], cell[1][0], cell[2][0] cell[0][1], cell[1][1], cell[2][1] cell[0][2], cell[1][2], cell[2][2]

そして cell[0][0](左上のセル)の周囲の爆弾を数えるためにcount関数を呼び出してみます。

js

1count(0, 0)

x=0, y=0ですから実際に走るコードとしては以下のようになります。

js

1let b = 0; 2for (let j = -1; j <= 1; j++) { 3 for (let i = -1; i <= 1; i++) { 4 if (cell[j] && cell[j][i]) { 5 if (cell[j][i].bomb) b++; 6 } 7 } 8} 9return b;

ここで if (cell[j] && cell[j][i])がない場合を考えます。つまり

js

1let b = 0; 2for (let j = -1; j <= 1; j++) { 3 for (let i = -1; i <= 1; i++) { 4 if (cell[j][i].bomb) b++; 5 } 6} 7return b;

だったとして、これが実行される場合を考えてみます。このとき if (cell[j][i].bomb) 文の中身は実行順に

  1. j = -1, i = -1 => cell[-1][-1].bomb
  2. j = -1, i = 0 => cell[-1][0].bomb
  3. j = -1, i = 1 => cell[-1][1].bomb
  4. j = 0, i = -1 => cell[0][-1].bomb
  5. j = 0, i = 0 => cell[0][0].bomb
  6. j = 0, i = 1 => cell[0][1].bomb
  7. j = 1, i = -1 => cell[1][-1].bomb
  8. j = 1, i = 0 => cell[1][0].bomb
  9. j = 1, i = 1 => cell[1][1].bomb

となります。一番上のcell[-1][-1].bombは、そもそもcell[-1]undefinedであるためにcell[-1][-1]を参照することができず、

Cannot read property '-1' of undefined`

のようなエラーが発生します。上から4番目のcell[0][-1].bomb については、cell[0]自体はアクセス可能ですが、cell[0][-1]undefinedなため、cell[0][-1].bombについて

Cannot read property 'bomb' of undefined

のようなエラーが発生します。

こうしたアクセスできないプロパティへの参照が起こらないようするために、undefinedとなっていないかどうかを先に確かめているのがif (cell[j] && cell[j][i])の条件式です。上記リストのうち、1,2,3についてはif文の中の&&の前の時点でfalseだと判定されてif文の中は実行されません(&&についてはMDN等を参照ください)。つまり上記のエラーが発生する前にループの次の処理にうつります。また4,7についてはif文の中の&&の後ろでfalseと判定され、やはりif文の中は実行されません。最終的には5, 6, 8, 9、つまり↓で●のついているところの爆弾の数がカウントされ、エラーで止まることなく欲しい情報が得られるようになっています。

●cell[0][0], ●cell[1][0], cell[2][0] ●cell[0][1], ●cell[1][1], cell[2][1] cell[0][2], cell[1][2], cell[2][2]

投稿2019/06/12 13:16

YukiYamashina

総合スコア1011

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

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

Tanakakko

2019/06/13 10:39

ご回答ありがとうございます。大変わかりやすく、理解できました!
guest

0

全てのコードみないと分からないので、勘で回答します。
見た目上は3×3のマスしかないけど

codenanoka

1□□□ 2□□□ 3□□□

実際にはその外側にマスを用意してるのでしょう。

codejanaiyona

1■■■■■ 2■□□□■ 3■□□□■ 4■□□□■ 5■■■■■

爆弾のあるところと、外枠(黒いマス)は押せないマスとして判定しているのでしょう。
で、押せないマス=爆弾としてカウントしてしまうと間違った数でカウントされてしまうから、
枠外(黒いマス)は爆弾としてカウントしないようにする
という意味かなと

投稿2019/06/12 09:53

hentaiman

総合スコア6421

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

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

Tanakakko

2019/06/12 11:25

ご回答ありがとうございます。なるほど、外側に押せない仮想のマスを作成するのですね。大変丁寧な説明ありがとうございました。cell[j]&&cell[j][i]部分そして、i =x-1; i<=1; i++のコードがそれをどう実装しているのかの解説もしていただけませんでしょうか
guest

0

端に来るとチェックすべき領域が減るためのの処理でしょうね

この手の処理はダミー領域をつくっておくといつも同じ処理ですみます。
つまり33の領域であれば55の範囲をもち端の1列(1行?)はさわれないように
しておけば済みます

投稿2019/06/12 09:50

yambejp

総合スコア114843

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

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

Tanakakko

2019/06/12 11:25

ご回答ありがとうございます。なるほど、外側に押せない仮想のマスを作成するのですね。大変丁寧な説明ありがとうございました。cell[j]&&cell[j][i]部分そして、i =x-1; i<=1; i++のコードがそれをどう実装しているのかの解説もしていただけませんでしょうか
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問