扶桑工廠

I sleep all night and I work all day.

「Puzzle Game RTA Festival」参加レポート

目次

 
はじめに

 パズルゲーム限定のRTAイベント「Puzzle Game RTA Festival」(以下PGRF)に出場しました。Online Marathon Eventersのイベントは今年で2回めの出場(前回は「Kusoge of the RTA」)ですが、今回は前より余裕を持って取り組め、なんとかレポートにまとめられそうな内容が存在するので今回は参加レポートをまとめることにしました。

アーカイブはこちら

https://www.twitch.tv/videos/774269375

イベント前

 パズルゲームのRTAは走ったことがなかったんですが、Steamライブラリの底に沈んでいた「Pikuniku」がパズルゲームかつそこまで不確定要素がなくタイムが安定でき、ほとんどアクションゲームだったのでサクッと走って応募しました。

 当選したときは本当に大丈夫なのか不安でしたが当選したからにはやるしかなかったので覚悟を決めました。

 まあ45分くらいで走れればいいやろとか思ってて、2週間前から本格的に練習を始めたところ、Epic Gamesでの無料配布も伴い走者数が増え、新たな移動方法やタイム短縮手段が見つかってしまいました。
 最後に見つかった短縮はイベント3日前に発見しました。3日前に画面アスペクト比を変更して良いと言ってくださった運営の方々ありがとうございます。

 結果、イベントが始まる前までに20回程度通しを行い、自己ベストを申請時点から7分20秒更新し、ESTがガバガバになりました。ちなみにSRCの順位は一つ落ちました。

イベント当日

 PGRF2日目。午前中から胃が痛い。

 2日目開始後は通話で雑談しつつ序盤区間の練習をして緊張をほぐすことにして、出番を待ってました。運営陣のパズルゲームに対する見識や鮮やかな走者のテクニックに感銘を受けつつ準備へ。

 前回は解説の方がいらっしゃったのでそっちにまかせて大丈夫だったんですが、今回は全部一人でやることになったので、裏で棒読みを立ち上げてコメントを追いつつ状況に合わせて適当に解説をしていくことにしました。台本作るのが面倒くさくなった

 配信準備は問題なく進み、ゲーム内で調整する程度で済んだので序盤練習を回しながら待っていましたが、直前でXboxOneコントローラーの反応がなくなるトラブルが発生

 直前で事故は洒落にならんぞと本気で焦りましたが、無線接続してたコントローラーの電池が切れただけだったので、有線接続して解決しました。結果として緊張が全部飛んだので助かった。

 最初のゲーム解説はWikipediaGame*Sparkの記事を読んで軽く紹介し、あとは全力で走りながら、このゲームがパズルゲームであることをアピールしていきました。

 他のゲームは当然ちゃんと「パズルゲーム」だったので視聴者の反応が何よりも不安でしたが、まずはダンス王との戦いで視聴者を困惑させ、だんだん「そういうゲーム」という認識になっていったので助かりました。

 内容については本当に普通に通しつつあとは妄言垂れ流してただけだった気がします。走りは自己べ+1分程度。序盤のパズルスキップを3回ミスったり、ロープウェーの周期調整技に失敗したり、鉱山区間のアーニーが跳ねなかったりとタイムを失う原因を踏み抜きながらこのタイムはかなり満足できる走りでした。
 しかし、3日前に見つけたロープウェー周期調整に失敗したのはかなり悔しいです。この技のためだけにアスペクト比と解像度を調整したので、この技の失敗は痛い。

 配信で言ってたのに解説していなった解像度調整によるもう一つの短縮ポイントは、火山ステージのレーザーで破壊する最初のロボットの周期です。最速で来るとちょうどレーザー発射口の下側(または右)にロボットが来るため、待たずにレーザーのスイッチを起動してロボットを破壊できます。

 終わってからは通話に戻り少し話しました。「音楽に合わせてボタンを押すタイプのパズルゲームが一番パズルゲームだった」(大意)は面白かったです。裏で何話してたんでしょう。

走者としても、視聴者としても楽しいイベントでした!
運営スタッフやボランティアスタッフ、他のゲームの走者や解説の皆様、本当にありがとうございました。

 

遊戯王構築記録 ~握手で勝負を決めろ!友情爆破!!~

こんばんはー。扶桑です。
KOTR(1ヶ月後)とピカげん大会(1週間後)の練習に疲れてきたので、気分転換に遊戯王のデッキの記事を書くことにしました。
ブログの方向性がわからない?まあそういうことがあってもいいよね…

 

今回は古くから存在し、唯一無二の効果を持つのに全然使われないあるカードについて考えたい。

そのカードとは、

f:id:fusowasedr09:20200606010710p:plain

▲「遊戯王 キャラクターズガイドブック ー真理の福音ー」収録「友情 YU-JYO」

 

《友情 YU-JYO》である。相手プレイヤーに握手を申し込み、握手するというTCG界でも例を見ない効果を持っている。

 

このカードの活用方法といえば、

といった方法が挙げられている。

 

だが、握手をするという面にだけ注目とある問題が浮かび上がってくる。

そもそも、遊戯王には「デュエルを始める前には、お互いに握手をしてあいさつを交わす」(「遊戯王オフィシャルカードゲームパーフェクトルールブック2020」p.193より)というルールがあるのだ。 

相手の手を握りつぶしてジャッジキルを狙うリアリストなら、このタイミングで相手の手を握りつぶせば良い

 また、ジャッジや警察が呼ばれることを回避するために、相手の手を握り潰す際には周りに不審な様子を悟られてはいけない

 こうなると、暗殺拳の使い手でもなければこの方法による勝利は困難だろう。加えて最近はソーシャル・ディスタンスの徹底が求められているので、デュエル開始時の握手を省略でき、たとえ《友情 YU-JYO》を使ったとしても握手に応じる意思を示して効果処理がなされる可能性が高いというのも逆風である。別の道を考える必要がある。

 

ならば、効果に注目しよう。《友情 YU-JYO》は、握手に成功するとお互いのライフポイントが平均化される。

 つまり、相手がLP11000で自分LPが1000のときに《友情 YU-JYO》が通ると、自分LPが6000、相手LPが6000になる。

 このとき、あるカードが頭に浮かんだ。

f:id:fusowasedr09:20200606013835p:plain

▲「ENEMY OF JUSTICE」収録「ライフチェンジャー」

禁止カードに指定されている《ライフチェンジャー》である。
《ライフチェンジャー》がライフポイントを3000に固定するのに対し、《友情 YU-JYO》は自身と相手のライフポイントの合計を2で割った値になるため若干安定しない。

 しかし、《ライフチェンジャー》と違って自分のライフポイントを3000より回復できる可能性があり、さらに通常魔法のために自分のターンで即発動できたりライフポイント差が8000なくても発動できたりというメリットもある。

 

というわけで、《ライフチェンジャー》を使っていたデッキに《友情 YU-JYO》(と《結束 UNITY》)を入れるのは合理的判断である。
(過去に【握手暗黒界】で使われた実績もあるしね)

 「ライフチェンジャー」を活用するデッキといえばやはり【マジック・エクスプロージョン1キル】である。

 このギミックを使えば、《友情 YU-JYO》でデュエルの勝利につながるアドバンテージを得られる。

 

しかし、「マジック・エクスプロージョン」は禁止カードである。これでは【マジック・エクスプロージョン1キル】を組むことはできない。

だが、長い遊戯王の歴史には《マジック・エクスプロージョン》の代わりにできそうなカードがある。

f:id:fusowasedr09:20200606191355p:plain

▲「混沌を制す者」収録「残骸爆破」

そう、《残骸爆破》だ。

《残骸爆破》は発動条件は厄介だが自身のデッキ構築時点でこの問題は解決でき、通れば相手ライフに3000ポイントのダメージを一枚で与えられる優秀な火力になる。

しかし、《ライフチェンジャー》なら《残骸爆破》1枚で決まるが、《友情 YU-JYO》からの《残骸爆破》で決着をつけるには、お互いのライフポイント合計が6000以下である必要がある。

最初のターンでお互いのライフポイントを初期から合計で10000削るのは、自分のライフポイント調整だけでは不可能である。

 

だが、この問題を解決する手段は簡単だ。1枚で足りないなら2枚入れればいい

これなら、お互いのライフポイントを初期から4000減らすだけで十分である。《成金ゴブリン》を3枚使うにしろ、《チキンレース》を3回、《擬似空間》でコピーしてさらに2回、《ドン・サウザンドの契約》を1回発動するだけで足りる。

こうして《友情 YU-JYO》と《残骸爆破》を組み合わせた1キルデッキが現実味を帯びてきた。

 

というわけでこれが完成したデッキ、「友情爆破」だ!

『友情爆破』

f:id:fusowasedr09:20200606193240p:plain

http://www.db.yugioh-card.com/yugiohdb/member_deck.action?cgid=a63c0072ebc44e3ac7b1e0626e271d86&dno=101&request_locale=ja

 

デッキ紹介・採用カード

メインデッキ

モンスター:4枚

《閃刀姫ーレイ》:3枚

このデッキにおいては「闇の誘惑」で除外される以外に基本的に仕事はない。だが、「閃刀起動ーエンゲージ」の発動回数を増やすためにも3枚投入しておく。

 

《トーチ・ゴーレム》:1枚

1枚から4体素材の《鎖龍蛇-スカルデット》をリンク召喚できる有能な制限カード
こいつのために通常召喚が犠牲になった。

 

一応手順を示すと、

  1. 「トーチ・トークン」を自分フィールドに特殊召喚して《トーチ・ゴーレム》をエクストラモンスターゾーンの前に特殊召喚
  2. 「トーチ・トークン」を素材に《リンクリボー》と《リンク・スパイダー》をリンク召喚
  3. 《リンクリボー》と《リンク・スパイダー》を素材に《アカシック・マジシャン》をリンク召喚、効果で《トーチ・ゴーレム》を手札に戻す
  4. 《トーチ・ゴーレム》を特殊召喚、「トーチ・トークン」2体で《アカシック・マジシャン》のリンク先に《セキュリティ・ドラゴン》をリンク召喚
  5. 《セキュリティ・ドラゴン》の効果で《トーチ・ゴーレム》を手札に戻す
  6. 《トーチ・ゴーレム》を特殊召喚
  7. 墓地の《リンクリボー》の効果を発動、「トーチ・トークン」をリリースし、墓地から《リンクリボー》を特殊召喚
  8. アカシック・マジシャン》、《セキュリティ・ドラゴン》、《リンクリボー》、「トーチ・トークン」を素材に《鎖龍蛇-スカルデット》をリンク召喚

最後に残った《トーチ・ゴーレム》については、相手に利用されるタイミングがないはずなので放っておこう。

 

 魔法:34枚

 《友情 YU-JYO》、《結束 UNITY》:各1枚

このデッキのキーカード。相手のライフポイントを6000以下にする重大な使命を帯びている。

普通に《友情 YU-JYO》を使っても間違いなく握手拒否されるので、《結束 UNITY》を手札に握ってから最後に発動すること。

 

《閃刀起動-エンゲージ》:2枚、《閃刀機-ホーネットビット》:1枚

「閃刀」魔法カード2種。前者は準制限、後者は制限カード

《閃刀起動ーエンゲージ》はこの手のドローを必要とするデッキにはぜひとも採用したいカードである。墓地に魔法カードが3枚以上あれば、「閃刀」カードをデッキから手札に加えて1枚ドローと、手札を単純に増やすことができる。

《閃刀起動ーエンゲージ》→《閃刀機ーホーネットビット》→《閃刀姫ーカガリ》、効果で《閃刀起動ーエンゲージ》を回収は基本にして強力なコンボである。

2回目以降の《閃刀起動-エンゲージ》は《閃刀姫-レイ》をデッキから手札に加え、《闇の誘惑》のコストを調達する。

 

《テラ・フォーミング》:1枚、《チキンレース》:3枚、《擬似空間》:2枚

ドローソースとなるフィールド魔法とそのサーチカード。

お互いのライフポイントの合計値を減らすためにも積極的に使っていきたい。

 

《妖刀竹光》、《黄金色の竹光》:各3枚

「竹光」ターボギミック。《黄金色の竹光》を連打できればどんどん手札を増やせる。

《妖刀竹光》が手札でだぶついたときは、リンク素材にするモンスターに装備させてからリンク素材にして《妖刀竹光》の効果を発動させて《黄金色の竹光》をデッキから手札に加える。

 

《ワンダー・ワンド》:1枚

《暴走召喚師アレイスター》を2ドローに変換するカード。

《トーチ・ゴーレム》の項目で紹介した方法で《鎖龍蛇-スカルデット》をリンク召喚したあと、《鎖龍蛇-スカルデット》の効果で《閃刀姫-レイ》を特殊召喚、その2体でリンク召喚することで《暴走召喚師アレイスター》を出せる。

 

 アームズ・ホール》:2枚

安定材料にして唯一対策不能な事故を起こすカード。

《妖刀竹光》か《アームズ・ホール》を持ってくるが、ここで《結束 UNITY》が墓地に落ちると詰む。また、《友情 YU-JYO》、《残骸爆破》計3枚のうち2枚が墓地に落ちても詰む。

こればかりはどうしようもないので、運に頼ろう

 

《無の煉獄》、《成金ゴブリン》、《墓穴の道連れ》、《EMポップアップ》、《ドン・サウザンドの契約》、《暗黒界の取引》、《手札断殺》、《闇の誘惑》

各種ドローソース。

《EMポップアップ》と《ドン・サウザンドの契約》はライフポイントの調整を兼ね、《墓穴の道連れ》は相手の手札誘発を潰すチャンスになる。

ただ、《墓穴の道連れ》は手札で抱えなければいけない《結束 UNITY》を落とされる可能性が高く若干使いにくいため、《暗黒界の取引》に入れ替えてもいいだろう。

 

罠:2枚

 《残骸爆破》:2枚

このデッキのキーカードにして切り札。

3枚積むとデッキを掘りきれない恐れがあるので2枚のみ。

 

エクストラデッキ:15枚

 

《リンクリボー》、《リンク・スパイダー》、《アカシック・マジシャン》、《セキュリティ・ドラゴン》、《鎖龍蛇-スカルデット》

4体素材の《鎖龍蛇-スカルデット》で手札の質を上げるためのコンボパーツ一式。

詳細は《トーチ・ゴーレム》の項目を参照。

 

《暴走召喚師アレイスター》

《ワンダー・ワンド》の弾。

 

《トロイメア・ユニコーン》、《トロイメア・フェニックス》、《トロイメア・ケルベロス》、《トロイメア・グリフォン

トロイメアモンスターたち。

実際使うのは《トロイメア・ケルベロス》と《トロイメア・グリフォン》だけだろう。

《トロイメア・ケルベロス》は残った《トーチ・ゴーレム》を破壊して1ドローでき、《トロイメア・グリフォン》は《アームズ・ホール》で落ちてしまった魔法・罠カードをセットしてリカバリーできる。リカバリするときはまず負けているが

 

《閃刀姫-カガリ》、《閃刀姫-ハヤテ》、《閃刀姫-シズク》、《閃刀姫-ジーク》

閃刀姫モンスターたち。

実際使うのは《閃刀姫-カガリ》のみ。

墓地から《閃刀起動-エンゲージ》を回収してドローにつなげられる。

《閃刀姫-ハヤテ》はリンクマーカーが自分のモンスターゾーンを向いているため採用。

リンク2を作る必要性が出てきたときに役に立つ。

また、リンク1「閃刀姫」は他の種類の「閃刀姫」モンスターに《妖刀竹光》を装備させて《妖刀竹光》を能動的に落とす手段になる。

 

デッキを使う際の注意

ドローソースを連打してデッキを引き切り、《友情 YU-JYO》で握手して相手のライフポイントを6000以下にして《残骸爆破》を2枚セット、相手ターンで即《残骸爆破》を2枚発動して相手を倒すだけと、プレイングが容易かつ妨害がなければ悪くない精度で1キルが成立するこのデッキだが、大きな問題点がある。 

それは、こんなデッキを使うと友情が壊れる可能性があることである。このデッキに友情を感じる余地はかなり少ないので、これには注意が必要だろう。

ある意味《友情 YU-JYO》で友情の大切さを学んでいるとも言える

 

最後に

ここまで無理して【マジカル・エクスプロージョン1キル】もどきを組む必要があるかと言われると微妙だが、《友情 YU-JYO》は輝けたと思う。

やはり、某エンジニアが言っていたように、
「この世に数多あるカードの中に、役に立たないカードなんて一枚もない」

たとえそのデッキが微妙だったとしても、デッキ構築の貴重な財産となるのだ。

 

 

遊戯王の全カード名を公式データベースから抜き出す

概要

今回は前の記事その前の記事のあわせ技として、動的に生成されるサイトからスクレイピングします。個人の備忘録でもあります。
少し用があったので遊戯王OCGカードデータベースから遊戯王OCGに存在するカード名称を全部引っこ抜きます。
後ろにコードを掲載しているので、使う際は注意して使ってください。(多少手を加えないと動きませんが)
使うのはいつものPython 3.6とSeleniumです。ドライバーの更新は忘れずに。

手順

大体前の記事と一緒です。
1.開発者ツールを使って、ウェブサイトの構造を確認する
2.探しているものの場所を確認
3.コード書いて回す(time.sleepを忘れない)

よし、簡単ですね。それでは作っていきましょう。

1.ウェブサイトの構造を確認する

最初にrobot.txtを探します。自動化に関するルールが書いてあるので確認する必要があります。
Scrapyとかだと勝手にやってくれますけどね。
今回は見当たらなかったですが、サーバーに負荷をかけすぎないようにこまめにtime.sleepを入れます。

では本題へ。全カードが検索結果にある状態にします。
これは「カード検索」から何も入れずに検索するだけで済みます。
じゃあこれで出したページをTargetURLとして設定すれば一発で行ける!と考えましたが、結果から言えばこれではだめでした。
理由はよくわかりませんが、トップ画面に飛ばされてしまいます。
となると、トップからボタンを操作して進まないといけません。面倒臭い
仕方がないのでボタンの階層を調べます。
f:id:fusowasedr09:20200502183031p:plain
これは1つだけ。相対パス表記で次の行き先が書いてありますが、普通にボタンを押せば良さそうです。

次は検索ボタン。
f:id:fusowasedr09:20200502183242p:plain
検索ボタンも1つだけですが、Javascriptで書かれているのでスクリプト直打ちでも動きます。まあここは別にボタンを押して処理で良いでしょう。
後ろの方を見ると厄介なのがよく分かるので検索条件指定とかやらなくて本当に良かった。

2.探しているものの場所を確認

f:id:fusowasedr09:20200502184211p:plain カード名の入っている場所を検索結果から探します。
開発者ツールで探すと、読み方はbox_card_name書いてあるカード名はcard_status、レベル等はbox_card_spec、カードテキストはbox_card_textに直接書かれています。
読み方とカード名が別れているので注意が必要です。読み方が欲しかったので、box_card_nameを狙います。
ちなみに画像も取ってこれますが、一段掘らないといけないので他よりひと手間入ります。
値が参照できるなら、全部引っ張ってこれるスクレイピング原則に基づいて引っこ抜きましょう。(著作権やrobot.txtは守りましょう)

引っこ抜くところは見つかりましたが、全部取得するには自動的に次のページに進むようにしてやる必要があります。
問題は普通にクリックさせるだけではダメなところでした。下の画像を見るとその理由がわかります。
f:id:fusowasedr09:20200502190112p:plain 「次へ」ボタンがページ番号指定と一緒!しかも要素の区別もできないからボタンを選んで押せない!
いやー今回は詰みですね。お疲れ様でした…


なんてね!あわてないあわてない!
Javascriptで動作しているなら、こっちが合わせてJavascriptを実行してやるまでです。だいぶ力押しになりましたが。

3.コードを書く

前回記事であるWaifuLabsの自動化コードを改造して作ります。
取得したテキストを保存しないといけないのと、Javascriptを実行する部分をつけてやれば動くでしょう。 というわけで作ったのがこちら(なおこれは失敗します)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import os.path
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

Target =  "https://www.db.yugioh-card.com/yugiohdb/"   # 指定URL
Driver_path = "chromedriver.exe"   # chromedriverの場所。windows,プログラムと同じ場所にある場合
Interval = 5 # 遅延時間設定(あまり短くしないこと)

driver = webdriver.Chrome(executable_path=Driver_path)

def main():
    # 本命の操作
    path_w = "YGOlist.txt"
    items = driver.find_elements_by_class_name("box_card_name")
    for item in items:
        name = item.find_element_by_xpath("./span")
        with open(path_w, mode="a") as f:
            f.write(name.text + "\n")
    time.sleep(Interval)
    driver.execute_script("javascript:ChangePage("+ str(i + 1) + ")")
    
    
if __name__ =="__main__":
    driver.get(Target) # URL先に移動
    driver.find_element_by_class_name("cards").click()
    driver.find_element_by_class_name("black_btn").click()
    for i in range(3):
        main()
    driver.quit()

…これでヨシ!ってやって10回ほどトライ&エラーを繰り返しました。
これだとbox_card_nameを取得した際に空のリストが帰ってきてしまいます。
あと、うまく行ってもrange指定が間違ってるので1ページ目が2回取得されます。(これはただのアホ)

ここでググりつつ色々動かしてみると、どうやらページが生成される前に要素を取得しているから空のリストが帰ってきていることがわかりました。
そういや、プログラムは瞬時にアクセスしますがそんなにwebページの実行は早くないですもんね…
これなら、time.sleepを適当な時間とってやれば要素が帰ってくるはずです。
というわけで、完成品がこちら。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import os.path
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

Target =  "https://www.db.yugioh-card.com/yugiohdb/"   # 指定URL
Driver_path = "chromedriver.exe"   # chromedriverの場所。windows,プログラムと同じ場所にある場合
Interval = 5 # 遅延時間設定(あまり短くしないこと)

driver = webdriver.Chrome(executable_path=Driver_path)

def main():
    # 本命の操作
    path_w = "YGOlist.txt"
    time.sleep(Interval)
    items = driver.find_elements_by_class_name("box_card_name")
    for item in items:
        name = item.find_element_by_xpath("./span")
        with open(path_w, mode="a") as f:
            f.write(name.text + "\n")
    time.sleep(Interval)
    driver.execute_script("javascript:ChangePage("+ str(i + 1) + ")")
    
    
if __name__ =="__main__":
    driver.get(Target) # URL先に移動
    driver.find_element_by_class_name("cards").click()
    driver.find_element_by_class_name("black_btn").click()
    for i in range(1,1040):
        main()
    driver.quit()    

これですべて取得できました。
少し苦戦しましたが、概ね今までの応用で突破できました。
動的な生成ページはこの方法でスクレイピングできるので、困っている方は参考にしてください(大したの書けませんが)
連絡はTwitter(@fuso_wasedr09)にお願いします。
それではまた!

WaifuLabsを自動化する


一年ぐらい更新してませんでした。

この間に前の記事botが凍結されました。悲しい。
今回もPythonでWebサイトと遊びます。

 
さて、Waifulabs(https://waifulabs.com)をご存知でしょうか。
AIがアニメ絵の女の子を描いてくれるWebサービスです。
4×4のタイル表示の中から選択して(もしくは再抽選)いくことを4回繰り返し、好みのWaifuを作っていきます。

しかし、そこそこ遊んでいると当然自分の好みに大幅に偏り、新鮮さがなくなってきます。でもたまには別のも欲しくなりません?(わがまま)
というわけで、自動的にWaifuLabsで作ってもらうプログラムを組みます。公式のDiscordbotを使えばいいとか言わない
今回もPythonを使います。

 
最初にサイト構造を調べる作業から。前の記事とやることはほとんど一緒ですが、今回は操作しないと進まないので、ブラウザを自動化することを考えながら調べます。
まずはスタート画面。"MEET YOUR DREAM WAIFU"を押さないと先に進まないので、要素を調べます。

 f:id:fusowasedr09:20200502140459p:plain

割とすぐに見つかりました。ですが、上の画像をよく見ると同じclassが2つあるのがわかります。
ここで押したいのは(HTML抜粋)

<div class="button-content">
    <span class="label">Meet your dream waifu</span>

なので、覚えておきます。

次はアプリケーションの操作。

f:id:fusowasedr09:20200502141619p:plain

class="container"以下に16個のclass="girl"がありますが、今回はランダム生成なので最初の1個めを取れば良さそうです。
相手のランダム性にかけて、手を抜きます。(手を抜かないなら、リストに格納したあとで0から15までの乱数で選択すれば動くと思います)
あと残り3回のステップでも、格納場所は一緒だったので同じ動作を回すだけです。

最後の保存画面でWaifuをダウンロードすれば完了です。

f:id:fusowasedr09:20200502142321p:plain

画像のダウンロードを、ソースから直抜きするかダウンロードボタンを押してDLするかは選べますが、ソースから引っこ抜く方が簡単です(動いてないなら)。
が、作ったときは何も考えてなかったのでボタンを押してダウンロードする方法を取りました。
最後に、初期画面に戻してループさせれば、自動装置が完成します。

見通しが持てたのでコードを書きます。
それで出来上がったものがこちらです。githubに上げてあるのとほぼ一緒。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import os.path
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

Target =  "https://waifulabs.com/" # 指定URL
Driver_path = "chromedriver.exe"   # chromedriverの場所
Interval = 3 # 遅延時間設定(あまり短くしないこと)

kaisu = input("何回繰り返す?(半角数字)")
kaisu = int(kaisu)
driver = webdriver.Chrome(executable_path=Driver_path)

def main():
    driver.get(Target) # URL先に移動
    # ボタン操作
    driver.find_element_by_xpath("//*[contains(text(), 'Meet your dream waifu')]").click()
    time.sleep(Interval)
    # escキー入力(ポップアップ回避)
    webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform()
    # 本命の操作
    for j in range(4):
        driver.find_element_by_class_name("girl").click()
        time.sleep(Interval)
    # 保存ボタン入力
    driver.find_element_by_class_name("download-button").click()
    time.sleep(Interval)

if __name__ =="__main__":
    for i in range(kaisu):
        main()
    driver.quit()

今回は動的な作業が必要なのでBeautifulSoup4ではなく、Seleniumを使用しています。
Seleniumをpip経由でインストールし、chromedriverをダウンロードし(面倒なので)プログラムと一緒の階層に置きました。
階層指定はwindows版の指定で書いているので、別OSを使用する場合は指定場所を変更する必要があります。ググれば出ます。

やっていることはURL先に飛んで、自動的にアプリケーションを回すだけです。
最初のボタン指定はxpathで書くことで適切なボタンを押すようにしています。
(ここではワイルドカードで指定してテキストに指定文字列を含むものを探していますが、もし指定文字列が2つ以上ある可能性があるなら、一回直上の階層をリストで取得してから下層に降りて本命を取る形にします)

また、最初だけはチュートリアルが表示されてしまい、そのまま進行すると要素がなくてエラーを出すので、それを回避します。
だいぶ時間がかかった後、ESCキーで飛ぶことに気がついたため、キー入力を送るようにしました。
最初さえ終わればあとは順番通りに書いていくだけ…

と思いきや、"Restart from the beginning”をクリックする動作を入れるとなぜか失敗することがあったので(おそらく早すぎ)、再接続でごまかすことにします。

これで回数指定すればぐるぐる自動的にまわしてくれます。調整しないので出来は回数で補おう。

無料エロ漫画サイトの煽り文を機械学習で再現する方法(全年齢版)

<注意書き>

こちらは18歳未満でも安心して読める記事です。
よって結果は出力してません。結果を見たい18歳以上の方はnoteの記事

(https://note.mu/notes/n02752880ceaa)を読むか

TwitterBot(@R18_manga_LSTM)をフォローしてください。

こっちは手順解説です。

(5/5/2019更新)コードを少しマシにしました。 

今回、「エロ漫画タイム」(リンク先R18)

http://eromanga-time.com/)という無料エロ漫画サイトを題材として、文章の機械学習と文章の自動生成に取り組みました。

「エロ漫画タイム」には、独特な煽り文(作品紹介)があります。

これが非常に特徴的で面白いのですが、18歳未満にふさわしくないので例は差し控えさせてください。(note参照)

さて、この煽り文(に近いもの)を機械学習で作り出します。

 

◯環境

OS:Windows 10 home(64-bit)

GPU: Geforce GTX 1070Ti

Python 3.6.6(64bit)

Anaconda Navigator 1.9.6

MeCab-0.996

mecab-python-0.996

Jupyter Notebook 5.7.0

Google Chrome  72.0.3626.121(Official Build)(64 ビット)

 

◯データセットを用意する

まずは学習するためのデータセットを準備します。

APIが提供されてるならそちらからアプローチをかけたほうが良いですが、当然そんなものが提供されているはずもないので普通にやります。

サイトに行き、F12キーを押して(Google Chromeの場合)開発者モードを開きます。

f:id:fusowasedr09:20190324184930p:plain

↑開発者モードの例(このサイト)

そして、取得したい値がどこに書き込まれているかを探します。

今回の場合、<h2 class="article-title entry-title">の下にありました。

次に、ページ構造を確認しておきます。

普通に次のページに行き、URLの変化をチェックします。

「エロ漫画タイム」はURLが

http://eromanga-time.com/?paged=(ページ番号)

の形で管理されていたので、全ページを取得したいときはページ番号部分を動かせばいいとわかりますね。

これで必要な情報は手に入れたのでエディタに移りましょう。

 煽り文をスクレイピングするコードを書きます。

Beautiful SoupとRequestsをインストールしておく必要があります。

import bs4
import re
import requests
import os, sys, time

def scrape(mint):
    res = requests.get(mint)
    res.raise_for_status()
    soup = bs4.BeautifulSoup(res.text)
    titles = soup.find_all("h2", class_="article-title entry-title")
    for title in titles:
        print(title)
        time.sleep(5)
        
def main():
page_id_list = range(1,20)
for page_id in page_id_list:
scrape(f'http://eromanga-time.com/?paged={page_id}')
if __name__ == "__main__": main()

 前にげっちゅをスクレイピングした際に使ったコードを改造したので、前に何を参考にしていたか忘れちゃった。

注意するのは"class"は予約語なのでそのままでは使えず、”class_”で使うこと、ループ回さないと全取得できないことの2点。

このプログラムは取得した情報を保存してないですが、そのへんは大目に見てください。
やろうと思えばできますが(リストをstr型に変換してから書き込み)、jupyter使ったほうが簡単なので…
実際にはJupyter Notebookで動かして結果をコピペで保存しました。
2時間ほどかかると思います。

また、これだとhtmlタグがそのまま残るので、エディタで正規表現を使って処理します。

http://hodade.com/seiki/page.php?r_tag_sakujo

http://hodade.com/seiki/page.php?r_karagyou_sakujo

上のサイト2つを参考にして削除して、行を詰めます。

 

◯学習して出力する

今回はささっとやるために以下のレポジトリを使いました。

github.com

自動文章生成AI(LSTM)に架空の歴史を作成させた方法とアルゴリズム | SPJ

掲載元のサイトによると、事前処理が必要なのでこれも以下を参考にエディタで処理します。

http://hodade.com/seiki/page.php?r_gyoutou_tsuika

http://hodade.com/seiki/page.php?r_gyoumatsu_tsuika

 

データの事前処理が終わったら、プログラムをReadmeに従って実行します。

「--gpu=0」を使うと早くなると書いてありますが、generator.pyでGPUを使用するとエラーが出たので使わないほうがいいかも。

 

出力結果は…

18歳未満が見ると悪いのでやめておきます。botとnoteで確認してね!

SceneAttacher for CryptoKanojo

CryptoKanojo非公式支援ツール「SceneAttacher for CryptoKanojo」(Win,Linux対応)の配布と使い方の解説です。

◇ 概要 ◇

 トークンの女の子と戯れることができるDapps、CryptoKanojoの支援用ツールです。
CryptoKanojoの共有機能を使用すると、女の子の画像を共有できますが背景がありません。(透過処理されていて、imgur上では黒背景に見える)
本プログラムは、簡単に共有機能で出力した画像と背景画像を合成し、女の子に背景をつけるためのツールです。
共有の際や、自身の部屋に召喚したい、デートしたいという時にお使いください。

t.co

◇ 環境 ◇

このプログラムはWindowsLinuxで動作します。(Macは未確認です)
しかし、それぞれで必要な準備が異なるため注意してください。

Windows:準備の必要なし(exeファイルを使用する場合)

Linux:Python 3.4以降で、Pillowがインストール済みであること。
(導入方法はMGM-Fusion-Systemhttps://fuso-wasedr09.hatenablog.com/entry/2019/01/17/234632

のエントリをご確認ください)

Windowsでも、.pyファイルで動かす場合はLinuxと同様の準備が必要です。

 

◇ 使い方 ◇

①CryptoKanojoの共有機能を使ってimgurのURL(例:https://t.co/vFJyu1LCdI?amp=1)を取得
②imgurの画像を保存
(ここで、画像のサイズが400×500か念の為確認してください。)
③背景にしたい画像と彼女の画像のファイルの場所を確認してプログラムを起動
④画面の指示に従い、彼女の画像ファイルの場所と背景画像のファイル場所を指定する
⑤少し待つと、プログラムと同一のディレクトリに背景が合成された彼女の画像が出力されます。

◇ 注意事項 ◇
・ファイル名に日本語が入っていると文字化けします。
・彼女の画像サイズ400×500に対応するので背景画像はそれ以上のサイズにしてください。細かい調整はかかりません。
背景画像のサイズが400×500だときれいに出来上がります。

 

◇ 複製 ◇
無断でのソフトウェア、コードの再配布や一部改変したコードやソフトウェアの配布は禁止です。
再配布や改変しての配布を行いたい場合、ご連絡ください。
連絡いただければ大抵許可は出します。


◇ 免責 ◇
これらのプログラムの使用は自己責任でお願いします。
製作者は利用の結果生じた損害について一切責任を負いません。
(クリティカルな問題が発生するとも考えにくいですが、ファイルを間違って上書きしちゃったなどはありえるので自己責任で。)
また、CryptoKanojo公式にこのプログラムについての質問等を送らないでください。
非公式のプログラムです。

よくある質問
Q.ライブラリを全部インストールしたのに、ライブラリがないと言われて動かせない。
A.まず、コマンドプロンプトやターミナルで"python --version"を実行してPython2系が入っていないか確認してください。
 入っている場合、pipでインストールするとPython2に導入されるので、Python3に導入できていません。
 pip3をインストールし、”pip”部分を”pip3”で置き換えてインストールするとうまくいくと思われます。

<追記(1/18/2019)>

公式に紹介されました。正直ちょっと焦りました…

 

 

MGM-Fusion-System

MakeGirlsMoe(https://make.girls.moe/#/)で融合を行うための非公式プログラム「MGM-Fusion-System」の配布と使い方のページです。

(2019/02/18更新)Ver1.3に更新。ノイズの日本語ファイル名に対応。

◇ 概要 ◇
 MGM-Fusion-System(以下MGMFS)は、MakeGirlsMoe(https://make.girls.moe/#/)のノイズを利用し、
MakeGirlsMoeで疑似的に融合を行うための支援プログラム(当然ながら非公式)です。2つのノイズを融合し、融合元の女の子の特徴を引き継いだ女の子を作るノイズを作成します。
ノイズから生成するにはMakeGirlMoeを利用する必要があります。
Noise_attachはMakeGirlsmoeで生成したノイズを生成された女の子の画像とセットにできるプログラムです。
Noise_separateを利用することでノイズのみを分離できます。

 

◇ 動作条件 ◇
(共通)
MakeGirlsMoe(https://make.girls.moe/#/)が利用できること。
(.exe版)
Windows用のexeファイルを使って起動する場合、事前準備は不要です。
(.py版)
Python 3.4以上がインストールされており、かつ以下の外部ライブラリがインストールされていること。
OpenCV
・numpy
・Pillow

# Python上で、OpenCVは"pip install opencv-python"で、Pillowは"pip install Pillow"でインストールできます。
また、numpyはOpenCVのインストール時に一緒に入ります。
詳細はGoogleで導入方法を調べるか、もしくはAWSドキュメント(https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb-cli3-install-linux.html)を読むと良いでしょう。それでも正常にインストールしたはずなのにライブラリがないとエラーが出る場合、下のFAQを参照すると解決するかもしれません。

(推奨)
MakeGirlsMoeの「ノイズをセーブ」機能を利用して、2つ以上のノイズを保存しておく。
(なくても「テスト用ノイズ」フォルダに入っているノイズを利用できますが、MakeGirlsMoeの支援アプリなので準備を推奨。)

 

配布先(Ver1.3)

1drv.ms

Ver1.3

更新内容:

・ノイズに日本語が入っていた場合、エラーが出る不具合の修正。

・処理ごとにプログラムが落ちなくなった。終了時は2を押して抜けてください。

 

アーカイブは記事一番最後へ)

 

◇ インストール ◇
配布先からダウンロードして、MGMFS_Ver1.3のフォルダを解凍。

◇ アンインストール ◇
レジストリは使用しないので、フォルダごと削除してください。

 

◇ 使い方 ◇

<MGMFS>
(旧バージョン用ですが、こちらも参考に→https://note.mu/fuso_wasedr09/n/nb1f953371f71
1. MakeGirlsMoe(https://make.girls.moe/#/)で女の子を生成します。
良さそうな女の子ができたら、「ノイズをロード/セーブ」から「セーブ」を選択し、png形式で保存します。
この際、生成した女の子とノイズのセーブ名が対応するようにしておくと便利です。

2.プログラムの実行
(.exe版)
「MGMFS.exe」をダブルクリックして実行します。
実行するとコマンドプロンプトが開きます。(少し時間がかかります。)

(.py版)
「MGMFS.py」を実行します。
# OSによって異なりますが、"python3 MGMFS.py"で実行できます。また、パスが通っていれば"MGMFS.py"で実行できます。
# また、JupyterNotebookで実行する場合は、同梱の「Lancher_for_jupyter.ipynb」を利用すると簡単です。

(実行後の共通部分)
その後、画面の指示に従ってノイズのファイルの場所を入力します。(便利な入力方法は下のTipsへ)
問題なく実行された場合、「作業が完了しました!」のメッセージが出力されます。
「MGMFS.exe」と同一のディレクトリに作成される「fusednoise」フォルダ内に融合後のノイズが出力されています。
融合後のノイズは「fusion base_(1番目に選択したノイズのファイル名)_and_(2番目に選択したノイズのファイル名).png
というファイル名になります。

続けて処理を行う際は1を、終了する場合は2を押してください。(Ver1.3)

Tips:便利な入力方法
(パスの書き方に慣れている人は飛ばして構いません。)
 基本的にファイルの場所を全部入力する必要がありますが、一部省略できるケースがあります。
・実行する「MGMFS.py」(「MGMFS.exe」)と同一のディレクトリにノイズのファイルがある場合:ファイル名(拡張子も)のみ。
・実行する「MGMFS.py」(「MGMFS.exe」)より下層のディレクトリにある場合:「./(フォルダ名)/(ファイル名、拡張子付き)」

3.融合後のノイズの読み込み
MakeGirlsMoeのサイトにアクセスします。「ノイズをロード/セーブ」から「ロード」を選択し、MGMFSで生成されたノイズを
ロードします。うまくいっていれば、ここで正常にロードされます。
その後は通常のMakeGirlsMoeの使用方法に従って生成してください。どこかしら融合元に似た女の子が生成されるはずです。

<Noise_attach,Noise_separate>
1.実行
MGMFSの2の手順を参考に実行してください。
2.操作(Noise_attach)
画面の指示に従ってノイズファイルの場所とそのノイズをくっつける女の子の画像ファイルの場所を選択してください。
処理後の画像はNoise_attachと同一のディレクトリに生成されます。

2.操作(Noise_separate)
画面の指示に従い、Noise_attachでノイズのくっつけられた画像ファイルの場所を選択してください。
処理後の画像はNoise_separateと同一のディレクトリに生成されます。

◇ 免責 ◇
これらのプログラムの使用は自己責任でお願いします。
製作者は利用の結果生じた損害について一切責任を負いません。
(クリティカルな問題が発生するとも考えにくいですが、ファイルを間違って上書きしちゃったなどはありえるので自己責任で。)
また、MakeGirlsMoe運営にこのプログラムの操作等についての質問は避けてください。迷惑です。

◇ 複製 ◇
無断でのソフトウェア、コードの再配布や一部改変したコードやソフトウェアの配布は禁止です。
再配布や改変しての配布を行いたい場合、ご連絡ください。
連絡いただければ大抵許可は出します。

◇ FAQ ◇
既知の不具合
・ノイズのファイル名に日本語を利用していた場合、融合後にノイズ名が文字化けする。

よくある質問
Q.ライブラリを全部インストールしたのに、ライブラリがないと言われて動かせない。
A.まず、コマンドプロンプトやターミナルで"python --version"を実行してPython2系が入っていないか確認してください。
 入っている場合、pipでインストールするとPython2に導入されるので、Python3に導入できていません。
 pip3をインストールし、”pip”部分を”pip3”で置き換えてインストールするとうまくいくと思われます。

Q.仕組みについて
A.こちらを参照。

note.mu

◇ 履歴 ◇
2019/01/10:Ver1.2公開。
それぞれ.exeと.pyを同梱。
Lancher_for_jupyter,Noise_attach,Noise_separateの同梱。
融合時、遺伝に偏りが発生しやすいのを少し修正。
作業フォルダが存在していなくても自動的に作成されるようになった。
融合後のノイズの保存場所を変更。
ノイズの場所をファイル場所指定に変更した。
Noise,frag,Mothernoise,Fathernoiseフォルダの削除。
Readmeの追加。
ファイルが見つからなかった場合、強制的に終了するようになった。

2018/12/15:Ver1.0.1公開。
Linux系で動かない不具合の改善。

2018/12/12:Ver1.1公開。
Windows用にexeファイル追加。

2018/12/11:Ver1.0公開。

 

アーカイブ

(Ver1.2)

1drv.ms

(Ver1.2以前)

note.mu