Javascript 神経衰弱ゲームを作ろう その3 並べたimgをシャッフル Fisher–Yatesアルゴリズム
この記事の続きです
kirikko-scondcube.hatenablog.com
今回使用したものは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;
}
補足:
上記コードで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 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 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 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 name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</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が使用できました!