前回、前々回のブログ記事では、pythonでガチャを実装し、それをウェブアプリにしました。今回はそれの補足ですが、10連ガチャと一万連ガチャのpython flask側の処理とhtml側の処理を書きます。
https://blueqat.com/yuichiro_minato/3eaae4a2-8b62-4660-8bb6-8cd8351c6745
https://blueqat.com/yuichiro_minato/c6c04924-2548-4250-bb88-92849e160353
内部でもちろん処理を枝分けしても良いですが、今回はわかりやすいように全部別々に書きました。flask側は、
@app.route('/gacha')
def gacha():
return render_template("gacha.html")
@app.route('/gacha10')
def gacha10():
return render_template("gacha10.html")
@app.route('/gacha10k')
def gacha10k():
return render_template("gacha10k.html")
テンプレートを分けて出力しています。templatesフォルダの中にそれぞれhtmlを入れておきましょう。
10連サーバーサイド
10回サンプリングを行い、配列を書き出します。戻ってくる結果は結果ごとの出現回数がまとまってしまっているので、バラしてあげる必要があります。
response = EmbeddingComposite(DWaveSampler(endpoint='https://cloud.dwavesys.com/sapi', token=token, solver='Advantage_system1.1')).sample(bqm, num_reads=10)
arr = []
for item in response.record:
for _ in range(item[2]):
a = list(item[0])
if a == [1,0,0]:
b = 4
elif a == [1,1,0]:
b = 1
elif a == [0,0,0]:
b = 3
else:
b = 2
arr.append(b)
random.shuffle(arr)
return str(arr)
そして、最後にシャッフルして、stringにしてreturnします。
一万連サーバーサイド
一万連も同じです。D-Waveでは一度に最大一万サンプルが取れますので、num_reads=10000 と指定するだけです。あとは同じで、戻ってきたresponseオブジェクトから配列を取り出します。今回は10000配列をフロントに返すのはちょっと気が引けるので、答えごとの出現回数をそのまま返、フロント側で処理します。
response = EmbeddingComposite(DWaveSampler(endpoint='https://cloud.dwavesys.com/sapi', token=token, solver='Advantage_system1.1')).sample(bqm, num_reads=10000)
arr = []
ss = 0
for item in response.record:
a = list(item[0])
if a == [1,0,0]:
b = 4
elif a == [1,1,0]:
b = 1
elif a == [0,0,0]:
b = 3
elif a == [1,1,1]:
b = 5
else:
b = 2
if b !=2:
arr.append([b,item[2]])
ss = ss+item[2]
aa = 10000 - ss
arr.append([2,aa])
return str(arr)
10連フロントエンド
続いて、フロントエンドです。
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
body{font-family:courier;}
.table-bordered{border:3px solid black;}
.table-bordered tr:nth-child(3n){border-bottom:2px solid black;}
.table-bordered td:nth-child(3n){border-right:2px solid black;}
.table td{padding:0;}
input{-webkit-appearance:none;border:0;background:none;text-align:center;font-weight:bold;line-height:35px;}
.answer{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:37px;font-weight:bold;color:skyblue;opacity:0.6}
.result{color:red;}
</style>
</head>
<body>
<div class="container" style="margin-top:20px">
<div class="row">
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_0">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_1">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_2">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_3">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_4">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_5">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_6">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_7">
</div>
<div class="col-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_8">
</div>
<div class="col-4 offset-4">
<img src="http://blog.blueqat.com/wp-content/uploads/2020/11/0.jpg" style="width:100%;height:auto;" id="main_9">
</div>
<div class="col-12">
<div style="text-align:center;margin-top:5px;">
<button id="gacha" type="button" class="btn btn-outline-dark" style="font-size:24px;font-weight:bold;padding:1px 15px;border:3px solid black;">gacha</button>
</div>
</div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script>
$(function(){
var url = "画像フォルダ";
$('#gacha').click(function(){
var anneal = setInterval(function(){
//数字の表示系
$('#main_0').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_1').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_2').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_3').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_4').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_5').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_6').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_7').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_8').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
$('#main_9').attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
},50)
$.ajax({
type : 'GET',
url : 'APIエンドポイント',
timeout : 15000
}).done(function(data, textStatus, jqXHR) {
var cc = JSON.parse(data);
for(var i=0;i<10;i++){
$('#main_'+i).attr('src',url + cc[i] +'.jpg');
};
clearInterval(anneal);
}).fail(function(jqXHR, textStatus, errorThrown) {
clearInterval(anneal);
$('#main').attr('src',url + '0.jpg');
});
});
})
</script>
</body>
</html>
こんな感じでしょうか。画像がシャッフルされる感じを出して、その間にajaxでgetリクエストをサーバーに投げます。戻ったきたのは配列で戻りますので、そのまま対応するイメージを書き換えます。サーバー側に特に送るパラメータもないので簡単です。
一万連フロントエンド
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
body{font-family:courier;}
.table-bordered{border:3px solid black;}
.table-bordered tr:nth-child(3n){border-bottom:2px solid black;}
.table-bordered td:nth-child(3n){border-right:2px solid black;}
.table td{padding:0;}
input{-webkit-appearance:none;border:0;background:none;text-align:center;font-weight:bold;line-height:35px;}
.answer{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:37px;font-weight:bold;color:skyblue;opacity:0.6}
.result{color:red;}
</style>
</head>
<body>
<div class="container" style="margin-top:20px">
<div class="row" style="margin-bottom:10px;">
<div class="col-12">
<div style="text-align:center;margin-top:5px;">
<button id="gacha" type="button" class="btn btn-outline-dark" style="font-size:24px;font-weight:bold;padding:1px 15px;border:3px solid black;">gacha</button>
</div>
</div>
</div>
<div class="row" id="row1">
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script>
$(function(){
var url = "画像フォルダ";
for(var i=0;i<10000;i++){
$('#row1').append('<div class="col-2"><img src="画像フォルダ/0.jpg" style="width:100%;height:auto;" id="main_'+i+'"></div>');
};
const shuffle = ([...array]) => {
for (let i = array.length - 1; i >= 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
$('#gacha').click(function(){
var anneal = setInterval(function(){
//数字の表示系
for(var i =0;i<300;i++){
$('#main_'+i).attr('src',url + (Math.floor(Math.random()*4)+1) + '.jpg');
};
},50)
$.ajax({
type : 'GET',
url : 'APIエンドポイント',
timeout : 15000
}).done(function(data, textStatus, jqXHR) {
clearInterval(anneal);
var cc = [[1, 5570], [4, 81], [3, 98], [5, 1], [2, 4250]]
var arr3 = [];
for(var i=0;i<cc.length;i++){
for(var j=0;j<cc[i][1];j++){
arr3.push(cc[i][0]);
}
}
arr3 = shuffle(arr3);
for(var i=0;i<10000;i++){
$('#main_'+i).attr('src',url + arr3[i] +'.jpg');
};
}).fail(function(jqXHR, textStatus, errorThrown) {
clearInterval(anneal);
$('#main').attr('src',url + '0.jpg');
});
});
})
</script>
</body>
</html>
ここまでくると手書きもきついのでjqueryで書きました。リクエストを投げて戻ってきた後に自分で配列に展開してシャッフルするのをjs側でやってるのが以前と違います。表示系は100から300程度に動きをつければ十分でした。性能の低いスマホではあまりインターフェイスにこだわりすぎると動きが重たくなるので、適宜調整です。
jsでのシャッフル部分の参考文献は、
https://www.nxworld.net/tips/js-array-shuffle.html
できました!
これでできました!D-Waveの無料枠を利用すれば十分ガチャを楽しめると思います!では、量子と共に!