
Youtubeにてあきちょんさんの動画、テトリスを作る17回でテトリスを回転させるコードについて分からないことがあったので質問させて頂きます。必要そうなコードのみ抜粋、変数は自分が分かりやすいように多少変えてます。
<!DOCTYPE html>
<html>
<body>
<script>
let tetro = [
[0,0,0,0],
[1,1,0,0],
[0,1,1,0],
[0,0,0,0],
];
function rotate()
{
let kaiten=[]
for( let y = 0; y<4; y++ )
{
kaiten[y] = []
for( let x = 0; x<4; x++ )
{
kaiten[y][x] = tetro[3-x][y];
}
}
return kaiten;
}
let ntetro = rotate(); //一回目回転させる
tetro = ntetro
ntetro = rotate(); //二回目回転させる
tetro = ntetro
</script>
</body>
</html>
のコードですが、前々回第15回でも二次元配列を初期化、代入を説明されていたので、
let kaiten を関数の外で宣言してreturnを受け取らずにしました。
<!DOCTYPE html>
<html>
<body>
<script>
let tetro = [
[0,0,0,0],
[1,1,0,0],
[0,1,1,0],
[0,0,0,0],
];
let kaiten=[] //関数の外で宣言
function rotate()
{
for( let y = 0; y<4; y++ )
{
kaiten[y] = []
for( let x = 0; x<4; x++ )
{
kaiten[y][x] = tetro[3-x][y];
}
}
} //returnを受け取らない
rotate(); //一回目回転させる
tetro = kaiten
rotate(); //二回目回転させる
tetro = kaiten
</script>
</body>
</html>
このようにしたところ、一回回転させる分には正常なのですが、2回目からバクるんですが、なぜだか分かりません。どうぞご教授ください。プログラミング初めて一か月くらいなので、平たく解説していただけると助かります。
No.3ベストアンサー
- 回答日時:
tetro = kaiten;
kaiten[0] = 'kaitenに代入';
console.log(tetro);
としたとき、
kaitenにだけ代入したつもりなのに、
tetroも一緒に変化します。
一般的な感覚だと、おかしい気もしますが、
プログラムとしては、これが正しい結果です。
その理屈は、No1さんの解説の通りなのですが、
もし難しければ、
「JavaScript 基本型 参照型」
などでググると、いろいろ解説記事が出てきますので、
それらを読んでみて、自分で一番納得しやすいものを参考にしてください。
ご回答ありがとうございます。
なんとなく分かりました。
forループを使って一気に出力すると頭がこんがりますね。
一つ一つ代入しながら検証していきたいと思いました
No.4
- 回答日時:
> Youtubeにてあきちょんさんの動画、テトリスを作る17回でテトリスを回転させるコードについて分からないことがあったので質問させて頂きます。
ハッキリ言うけど。
何故に松下電器の商品に対する質問をSONYにするような真似をするの。
そういう「YouTubeでプログラミング講座」を提供してるトコ自体で質問しなさいよ。
他のサイトにそういう質問を持ち込まない。
逆に言うと、誰?そのあきちょんさんだか何だか知らんけど、もし、貴方のような人からYouTubeで質問を受け付けてない、としたら「プログラミング講座」とかやる資格がないんだよ。
分かる?
> プログラミング初めて一か月くらいなので
うん、だったらそれやめて本の一冊でも買って勉強しなさい。
「動画だったら簡単にプログラムを学べる!」とかウソだから。
安直なヤツが騙されるんだよ。
もう一回言うけど、「質問を受け付けてないような」サイトで「学べる」とかあり得ないから。
だったらフツーに本買って読んで勉強した方がマシ。それには結局「勝てない」んだよな。
No.2
- 回答日時:
No1です
連投失礼。
ちょっと面白い記事をみつけたので・・・
https://qiita.com/kznrluk/items/790f1b154d1b6d4d …
行列の回転を行うワンライナーです。ご参考までに。
// 時計回りに回転
const rotate = a => a[0].map((_, c) => a.map(r => r[c]).reverse());
let tetro = [
[0,0,0,0],
[1,1,0,0],
[0,1,1,0],
[0,0,0,0]
];
tetro = rotate(tetro);
tetro = rotate(tetro);
No.1
- 回答日時:
こんにちは
単変数の場合は、値を代入するとそれぞれが値を保持しますけれど、配列やオブジェクトの場合は参照代入になります。
let a = [1, 2, 3, 4];
let b = a;
b[0] = 5;
console.log(a); // [5, 2, 3, 4]
うまくいかないという方に関しては、最初は配列kaitenとtetroは別々に定義されているので、それぞれ別の値を保持していますが、
>tetro = kaiten
の代入を実行すると、tetroとkaitenは同じ値を参照するようになります。
このため、2度目以降はおかしなことになります。
正しく動作する方のスクリプトは、関数内で毎回新しく配列kaitenを生成しているので、このようなことが起こりません。
後でご提示の方法でも意図通り動作させたければ、
>tetro = kaiten
とせずに、構成する要素を個々に代入するようにすれば、それぞれの変数が個別に値を保持するようになるので、意図通りになると思います。
例えば、
tetro = kaiten.map(i=>i.map(j=>j));
とか。
ご回答ありがとうございます。
参照代入を勉強させて頂きます。
代替案もありがとうございます。
余裕が出来たらそちらも勉強させて頂きます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
自動ジャンプでフォームデータ...
-
getElementsByNameで要素が取得...
-
ひとつのHTMLファイル内にcanva...
-
JavaScriptでiframeの内容を「...
-
クリックすると別の文章を表示する
-
SCRIPT5007: 未定義または NULL...
-
出荷予定日を表示するJavaスク...
-
JavaScript でキーを送る
-
bodyタグのfocus
-
ナンバーズ 4 の数列をランダム...
-
乱数を一定時間毎に表示させた...
-
キーを押している間の時間を計...
-
ajax で読み込みを途中で止めた...
-
JavaScriptでのEnterキーとAlt+...
-
フォーカス移動抑止について
-
Backbone.js イベントが効かない
-
javascript isFinite
-
初心者javascript ウィンドウサ...
-
プログラミング初心者です。ど...
-
ページ全体を検索して特定文字...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
function の return 値を表示し...
-
JavaScriptでiframeの内容を「...
-
SCRIPT5007: 未定義または NULL...
-
getElementsByNameで要素が取得...
-
キーを押している間の時間を計...
-
複雑な再帰(?)に関して
-
乱数を一定時間毎に表示させた...
-
JavaScriptでのEnterキーとAlt+...
-
javascriptでtextareaの文字列...
-
フォーカス移動抑止について
-
iframe内に表示するページを5分...
-
イメージ(画像)の上に重ねたテ...
-
ウィンドウのタイトルを変えたい
-
onmouseoverのクラス指定
-
クリックすると別の文章を表示する
-
JavaScriptについての質問です。
-
出荷予定日を表示するJavaスク...
-
bodyタグのfocus
-
JavaScript でキーを送る
-
マウスクリックした地点のテキ...
おすすめ情報