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を探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SCRIPT5007: 未定義または NULL...
-
フォーカス移動抑止について
-
JavaScriptでiframeの内容を「...
-
リンク移動先のURLを取得
-
初心者javascript ウィンドウサ...
-
ナンバーズ 4 の数列をランダム...
-
JavaScriptでのEnterキーとAlt+...
-
数日前等の日付を表示したいの...
-
ホームページに日付によりかわ...
-
インラインフレーム内から親フ...
-
【jquery】EasyUIのSubGridにMy...
-
function の return 値を表示し...
-
インラインフレームの、リンク...
-
JavaScript でキーを送る
-
iframeの中から親ページをスム...
-
<a href="#" …>の意味を教えて...
-
HTMLソースからURLだけを抜き出...
-
リンクのクリック数を把握したい
-
bodyにidをつける理由は何ですか?
-
submitボタンで他のフレームを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
function の return 値を表示し...
-
SCRIPT5007: 未定義または NULL...
-
JavaScriptでiframeの内容を「...
-
getElementsByNameで要素が取得...
-
キーを押している間の時間を計...
-
フォーカス移動抑止について
-
JavaScriptでの西暦下2桁での表...
-
自動ジャンプでフォームデータ...
-
出荷予定日を表示するJavaスク...
-
クリックすると別の文章を表示する
-
リンク移動先のURLを取得
-
乱数を一定時間毎に表示させた...
-
JavaScript でキーを送る
-
idHOGEで取得したinnerText(数...
-
ボタンのID名を取得するには?
-
htaでVBSのソースを書いたらエ...
-
Javascriptの出力結果をhtmlボ...
-
bodyタグのfocus
-
AjaxでDBから取得したデータを...
-
JavaScriptでのEnterキーとAlt+...
おすすめ情報