Javascript 神経衰弱ゲームを作ろう その3 並べたimgをシャッフル  Fisher–Yatesアルゴリズム

 この記事の続きです

kirikko-scondcube.hatenablog.com

 

 

今回使用したものはFisher–Yatesアルゴリズム

参考:https://qiita.com/komaji504/items/62a0f8ea43053e90555a?fbclid=IwAR2p_kxgQoehQXpfLbMjGXwMYDoWs5ycEjGku52rMAIPHTCcZ6ppLmyjs64

 

内容は以下

for(var i = array.length - 1; i > 0; i--){
var r = Math.floor(Math.random() * (i + 1));
var tmp = array[i];
array[i] = array[r];
array[r] = tmp;
}
 
補足:
上記コードでarray.lengthやarray[i]となっている「array」部分を自分の配列変数に変えると実装できた。
私の場合: let arr =;を使用していたので
arr.lengthやarr[i]を使えばOK!ということ!
 
私の場合配列にしようしていた変数は
let arr =;
としていたので、、

for(let n = arr.length - 1; n > 0; n--){
//今回であればnは27になる
let r = Math.floor(Math.random() * (n + 1));
//Math.randomで0.99...(0以上1未満)の数値を生成
//そこに27+1で28をかける
//そうすると0.00...1〜27.999...(28未満)までの値が生成
//Math.floorで小数点以下を切り捨てる。それにより整数にする
//これにより今rは0~27の整数となる
let tmp = arr[n];
//変数tmpに配列arr[n]を設定。n今のところ27の整数値
arr[n] = arr[r];
//ここで:arr[27] = arr[0~27(ランダムで変わる)];に変数を入れ替えている
arr[r] = tmp;
//ここで:arr[0~27(ランダムで変わる)]= arr[27];に変数を入れ替えている

//つまりこの時点では
//tmp = arr[27];
//arr[n] = arr[0~27(ランダムで変わる)]:
//arr[r] = arr[27];

}
//上記記述で配列のindexの順番を入れ替えることを実装!
このような形に
arr.lengthやarr[n]を使用していることがわかると思います。
 
 
補足2
for文でiではなくnを使用している点について
 
他の部分(カードを27枚配列に格納。そのカードをappendで配置する際、iをfor文で使用)をしたところ、シャッフルのfor文内でiを使うとエラーに
別の変数に格納すれば実装できるかなとnを使用してみたら実装できました!
 
 
全体のjs
// imgを配列に入れたが文字列になっているもの

window.onload = function(){

let arr = [];
let img = document.createElement('img');


img = document.createElement('img');
//img
img.id = ''
//img+id=""
img.className = 'card'
//img id= "" + class
img.setAttribute('src', `images/joker.png`);
//img id ="" + class="card"" + src ここで差別化する!
// palet.appendChild(img);
arr.push(img);

img = document.createElement('img');
//ここでimgを下のforでも使えるようクリア(初期値)に戻す








const palet = document.getElementById('palet');
//imgタグを作る


//スペードの画像を配列に格納  記述------------------------------------------------
for(i=1; i<14; i++){

img = document.createElement('img');
//ここの記述で一度ループの最初でimgについたid、クラス、srcをリセットしているこれをしないとスペてのイメージが最後のイメージになる
//img
img.id = 'spade'
//img+id="spade"
img.className = 'spade card'
//img id= "spade" + class
img.setAttribute('src', `images/spade/${i}.png`);
//img id ="spade" + class="spade" + src ここで差別化する!
// palet.appendChild(img);
arr.push(img);
//1周目は img + id + class + srcとなり img= (img id="spade" class="spade" src ="images/spade/1.png")

}
// ここまでーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

console.log(arr)



//ハートの画像を配列に格納  記述------------------------------------------------
for(i=1; i<14; i++){

img = document.createElement('img');
//ここの記述で一度ループの最初でimgについたid、クラス、srcをリセットしているこれをしないとスペてのイメージが最後のイメージになる
//img
img.id = 'heart'
//img+id="heart"
img.className = 'heart card'
//img id= "heart" + class

img.setAttribute('src', `images/heart/${i}.png`);
//img id ="heart" + class="heart" + src ここで差別化する!
// palet.appendChild(img);
arr.push(img);
//1周目は img + id + class + srcとなり img= (img id="heart" class="heart" src ="images/heart/1.png")
 
}
// ここまでーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー


// 今配列には0-26まで格納されていて
// これを1個ずつ並べるなら
// palet.appendChild(arr[26]);

console.log(arr)



// -------------------ここに配列をシャッフルするコードを記入する-----------------------
//Fisher–Yatesアルゴリズムを使用
//参考:
// for(var i = array.length - 1; i > 0; i--){
// var r = Math.floor(Math.random() * (i + 1));
// var tmp = array[i];
// array[i] = array[r];
// array[r] = tmp;
// }

for(let n = arr.length - 1; n > 0; n--){
//今回であればnは27になる
let r = Math.floor(Math.random() * (n + 1));
//Math.randomで0.99...(0以上1未満)の数値を生成
//そこに27+1で28をかける
//そうすると0.00...1〜27.999...(28未満)までの値が生成
//Math.floorで小数点以下を切り捨てる。それにより整数にする
//これにより今rは0~27の整数となる
let tmp = arr[n];
//変数tmpに配列arr[n]を設定。n今のところ27の整数値
arr[n] = arr[r];
//ここで:arr[27] = arr[0~27(ランダムで変わる)];に変数を入れ替えている
arr[r] = tmp;
//ここで:arr[0~27(ランダムで変わる)]= arr[27];に変数を入れ替えている

//つまりこの時点では
//tmp = arr[27];
//arr[n] = arr[0~27(ランダムで変わる)]:
//arr[r] = arr[27];

}
//上記記述で配列のindexの順番を入れ替えることを実装!
// シャッフルここまでーーーーーーーーーーーーー




// ここで配列から順番に画像を取り出している
for(i=0; i<27; i++){
palet.appendChild(arr[i]);
}
// ここまでーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

}


 
 
html
 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="palet">
 




</div>

<div id="result">ここに経過時間が読み込まれるようにする</div>

<div id="palet2">





</div>
<h1>idテスト</h1>

<script src="js/main.js"></script>
</body>
</html>
 
 
#palet {
width: 310px;
height: 490px;
background-color: antiquewhite;

}

.card {
width: 60px;
height: 80px;
background-size: cover;
float: left;
}


#result{
background-color: lightskyblue;
}
 
 
続く
 
 
2020.4.16更新
 

//シャッフルの記述ここからーーーーーーーーーーーーーーーーーーー


for(i = arr.length - 1; i > 0; i--){
var r = Math.floor(Math.random() * (i + 1));
var tmp = arr[i];
arr[i] = arr[r];
arr[r] = tmp;
}

//-----------------シャッフルここまでーーーーーーーーーーーーーーーーー
 
前回の記述では補足2でiが使えないからnとしていたが、恐らく原因はfor文内で
 
for(let n = arr.length.......)としていたから。
letを使わず
for(i = arr.lengtn... )とするとiが使用できました!