3D脱出ゲーム「Pictures」の攻略手順
unityroom で公開中の脱出ゲーム「Pictures」の攻略手順を残しておきます。
https://unityroom.com/games/escaping-game-pictures
詰まった時のための参考にしましょう。
具体的な内容は反転。
- 白いロッカー(左下)の開け方
まずは写真のオブジェをクッションの下から拾う。
次に、机の上の写真を見ると、ロッカー風のボックスの台座に乗せられている写真が飾られているので、 同じように台座に乗せる。これでロッカーが開くようになる。
- 白いロッカー(右上)の開け方
各スイッチをボックスに入っているカゴの位置に対応するように合わせる。
- 大きい黄色いロッカーの開け方
部屋の中に各アイコンが描かれた絵があるので、それを探す。
絵の中に描かれている数が答えの数字に対応する。
ただし、ちょうちょのアイコンは斜めになっているので、同じ角度のちょうちょを数える必要がある。
- 青いロッカーの開け方
上の画像の左に描かれている記号を用いる。
三角形、四角形、丸に数字を当てはめ、計算した結果が答えの数字になっている。 三角の数字は9 だが、最後の三角は反対向きになっているので、9 -> 6 に読み替える。
93 x 196 = 18228
三角の数字 : ソファーの左側 四角の数字 : 上の画像の右の絵をドライバーで外した壁 丸の数字 : 白いロッカーを開けた中のコイン
- 黄色いロッカー(小さい方)の開け方
青いロッカーから手に入った謎の数独みたいな盤と、
カゴなどが入っているロッカーの裏側に落ちている盤を棒を使って取り出す。
これらの盤は組み合わせると数字の描かれた迷路になる。
迷路のスタートからゴールまで辿った数字が答えの数字に対応している。
- 部屋からの脱出
青いロッカーから手に入れた鍵を使うと、部屋の扉が開けられる。
中にはパラグライダーの装備一式があり、手に入れられる。
これを用いて窓から脱出できる。
今回の製作にあたり知見などをまとめたので、こちらも参照していただければ幸いです。
Twitterで自分が誰にどれくらい 「いいね」 されたのかを調べる方法
成果物
自分のツイートが過去にどのアカウントから何件の「いいね」を貰ったかをグラフにしてみた。
作成したコードはGitHubに公開してます。
環境
- Python 3.6.2
今回の目的
2018年11月、次の衝撃的なニュースが話題に。
なんと、ツイッターの「いいね」機能が無くなるかもしれないそうです。
多くの人がこの機能で承認欲求を満たしていることでしょう。私もそうです。
それなら今のうちに、自分のツイートがどれくらいファボをもらっているのか、
そして、どのアカウントから何件もらっているのかを調べておきたい!
実はこれ、簡単な事ではないです
- 自分のツイート一覧
- フォローしているアカウント一覧
などの様々な情報が取得できますが、肝心の特定のツイートにいいねしたアカウント一覧という情報は取得できないのです。
(API についての詳しい説明は割愛します。取得できる情報はページ下部に載せておきます。)
すなわち、公式API では「いいね の合計数」は調べられますが、「いいね の内訳」は調べられないのです(詳しくはこちら)
また、合計数を調べたいだけならわざわざAPI を使わなくとも、
自分のアカウントのアナリティクス からCSV形式のデータをエクスポートしてなんやかんやすればいけそうです。
解決策1
という事でAPIを用いずに取得する方法で頑張るしかないです。
色々調べた結果、 stackoverflow で同じような質問があったので、そちらを参考にします。
記事内の関数はツイートidを入れるといいね元アカウントidリスト を返します。
各ツイートにツイートid と呼ばれる識別番号が付与されており、それを与えると対象ツイートにいいねしたアカウントのリストが得られるという訳です。
つまり、基本的な方針としては
- Twitter API を用いて自分のツイートid 一覧を取得する
- 各ツイートid ごとに、いいねしたアカウントidのリストを取得する
- アカウントid を集計する
- matplotlib を用いてグラフを描画する
という感じでしょう。
note
アカウントid とは@xxxxx のようなやつとは別物です。各ユーザに振り分けられた数列で、普段目にすることはありません。@xxxxx のようなid はscreen name と呼ばれ、API を叩いてアカウントid からscreen name に変換することができます。
ただし、この方法では誰でも閲覧できるアカウントしか対象になりません。
すなわち、鍵垢(非公開のアカウント)からのいいねは統計に入らないのです。
解決策2
鍵垢からのいいねも含めて調べたい場合。
みたいにする必要があります。
パッと見で気づくかもしれませんが、これはかなり素直(あほ)な実装で、かなり時間がかかります(笑)
回しっぱなしで気長に待てる場合や、
定期的に回してデータベースを更新していく。みたいな運用を想定している人向けでしょうね。
(試しに期間を今年分に絞って回してみたが、それでも2、3時間ぐらいかかった)
コードの詳細な説明は省きます。
note
当然のことですが、鍵垢を含めた検索は自分のアカウントでしか行えません。他のアカウントに来ているいいねの統計は公開アカウントからのもののみです。
役立ちそうな情報メモ
Twitter Developer アカウントの取得について
Twitter API を使うためには開発者用のアカウントを取得する必要があります。
Developer — Twitter Developers
いつの間にか仕様が変わっていて、取得がかなり面倒になっていました。
ただ、面倒と言っても適当に入力したらすぐに取得できました。
アカウントid リストの取得方法
元記事のプログラムは Python 2系 で書かれていたので、Python 3系 に少しだけ書き換えました。
def getUserIDList(self,post_id): """ 指定されたIDのツイートにいいねした人のIDリストを返す post_id : string 調べるツイートID """ # 一秒まつ sleep(1) try: json_data = urllib.request.urlopen(url='https://twitter.com/i/activity/favorited_popup?id=' + str(post_id)).read().decode("utf-8") found_ids = re.findall(r'data-user-id=\\"+\d+', json_data) unique_ids = list(set([re.findall(r'\d+', match)[0] for match in found_ids])) return unique_ids except urllib.request.HTTPError: return False
クラスのメソッドにしたのでself
が付いてます。
matplotlib でいい感じの円グラフ
いい感じの円グラフの作成には以下を参考にしました。
普通にやると色が足りなくなってしまうので、
temp = cm.Pastel1(np.arange(9)) col = [] for i in range(len(data)): col.append(temp[i % 9])
このようにして 9色 をデータの数だけループするような色リストを作成しました。それだけです。
注意点
こちらにも書いてあるが、リクエストの間隔は少なくとも 1秒 空ける必要がある。
そのため、結局全てのツイートを調べるには、少なくとも Tweet数 x 1 [sec]
だけの時間がかかってしまう。
2000件くらいツイートしていれば 最低でも 2000秒はかかる。
また、ユーザーid : screen_name の解決も 1ユーザずつ行なっており、こちらも1秒ずつ間隔を空ける必要がある。よって、「ツイート数はそれほどでもないが、大量のアカウントからいいねされている」みたいな感じのアカウントもかなり時間がかかってしまう。
API で取得できる情報
APIでツイートを取得したとき、以下の情報が付随してくる。
キー | 内容 |
---|---|
created_at | ツイートされた日時 |
id | ツイートに一意に割り当てられるid |
id_str | id の 文字列 |
text | ツイートの本文 |
truncated | ツイート本文が長すぎて途中で切られたかどうか |
entities | ハッシュタグや画像・動画などに関する情報 |
extended_entities | 複数の画像を取得したいとき |
source | どの端末からの送信か |
in_reply_to_status_id | (リプの場合)どのツイートへのリプライか |
in_reply_to_status_id_str | どのツイートへのリプライかの文字列 |
in_reply_to_user_id | リプするアカウントのid |
in_reply_to_user_id_str | リプするアカウントのid の文字列 |
in_reply_to_screen_name | リプするアカウントのscreen_name |
user | ツイート送信者の情報(JSON) |
geo | ツイートを送信したときの位置情報(非推奨らしい) |
coordinates | こちらも送信時の位置情報 |
place | ツイートに関連付けられている場所情報(必ずしもこの場所からの送信とは限らない) |
contributors | アカウントを複数人で運営している時の話 |
is_quote_status | 引用ツイートかどうか |
retweet_count | リツイートされた数 |
favorite_count | いいねされた数 |
favorited | 認証済みユーザーにいいねされたかどうか |
retweeted | 認証済みユーザーにリツイートされたかどうか |
possibly_sensitive | ツイートにリンクがあり、そのコンテンツが危険な可能性がある |
lang | 言語 |
続・将棋ウォーズの棋譜をまとめて保存する方法
以前、将棋ウォーズの棋譜を 将棋ウォーズ棋譜検索β で検索してローカルに保存 という流れをやってみたが、 よく見たら2018年8月以降の棋譜が出てこなくなっていた。(私だけ?)
ということで、最近の棋譜を取得するべく、別の手法で棋譜をダウンロードしてみたいと思う。
さらに今回は、ローカルに保存するだけではなく、ローカルのデータベースに保存して棋譜を再生できるようにしてみた。 その際に必要となったセットアップなどのメモ。
成果物
データベースに棋譜を登録
最近のアップデートで戦型のタグがつくようになった。棋譜を解析しなくてもどういった内容かわかるのでとても嬉しい。
一応再生できる(必要性はない)
使用したコードは GitHub に公開している。
環境
- macOS 10.14
- anaconda3-5.0.0
- MongoDB 4.0.3
棋譜のダウンロード
基本的な方針は前回とほぼ変わらないが、今回は公式のサイトから収集する。
https://shogiwars.heroz.jp/users/history/ユーザーID/web_app?locale=ja
アクセスすると分かるが、対局履歴を一ヶ月分(?)くらい閲覧することができる。
このページから棋譜のURLを取得してく。具体的にはgame_replay
クラスの中にあるa
タグにリンクが貼ってある。
特定のページにアクセスしたい時は以下のようなパラメータを設定する。
params = { "page" : ページ番号(一番最初のページは page = 1) "gtype" : 対局ルール(3切れは"sb"、10秒将棋は"s1") }
とりあえずデータベースに登録したい時は GitHubにコードを公開しているので、
- コードをダウンロード
- 以下の手順でスクリプトを実行する
$ python updateDB.py
これでMongoDBに棋譜データが閲覧できる分だけ保存される。重複して登録しないようにしてあるので、後からもう一度実行することで新しい分だけを取得できる。
対局ルールは以下の規則で命名してある。
10分切れ負け | 10m |
3分切れ負け | 3m |
10秒将棋 | 10s |
もしデータベースじゃなくてローカルにファイルとして保存したいときは、
- コードをダウンロード
- 以下の手順でスクリプトを実行する
$ python downloadKifu.py
とすれば良い。
データベースを利用する準備
MongoDB のインストール
MongoDB というオープンソースのデータベースを使ってみる。
MongoDB はJSON形式でデータを格納できるので使い勝手が良い(個人的に)
- homebrew を使ってインストール
$ brew install mongodb
- mongodb の起動
$ brew services start mongodb
- 起動しているかどうかの確認
$ brew services list
- mongodb の停止
$ brew services stop mongodb
- 特定のコレクションに含まれているデータを全て表示する
$ mongo > show dbs > use [db name] > show collections > db.[collection name].find()
コマンド | 操作 |
---|---|
mongo |
mongoDB のシェルを起動 |
show dbs |
データベース一覧を表示 |
use [name] |
使用するデータベースを変更 |
show collections |
コレクション一覧を表示 |
db.test_collection.find() |
コレクションに登録されている内容を全て表示 |
pymongo のインストール
今回はPython 経由でデータを追加・参照する予定なので、PyMongoというライブラリをインストールする。
- pip を使ってインストール
pip install pymongodb
- mongoDBへのアクセス
>>> from pymongo import MongoClient >>> client = MongoClient("localhost", 27017)
- データベースを使用(なければ作成)
>>> db = client["db_name"]
- コレクションを使用(なければ作成)
>>> collection = db["collection_name"]
- コレクションに追加
>>> type(post) <class 'dict'> >>> collection.insert_one(post)
複数追加したい場合は,辞書のリストを作成し,
>>> type(post) <class 'list'> >>> collection.insert_many(post)
- コレクションを参照
全て取ってくる
>>> collection.find()
Cursor
というイテレータオブジェクトが返ってくる.
for文などで回すことで一つずつ参照できる.
一つ取ってくる
>>> collection.find_one({"key": "000"})
引数として渡した条件に一致するデータが返ってくる。
上での例でいうと、"key" が "000" のデータで一番最初に見つかったやつが返ってくる。
棋譜を再生する
Python の将棋ライブラリとしてpython-shogiがある。
とても使いやすいのでこちらを使って棋譜を再生してみた。
使い方
- pip を使ってインストール
$ pip install python-shogi
- 将棋盤を描画するまで
ポイント
入出力はSFEN形式で行う.
http://ch.nicovideo.jp/kifuwarabe/blomaga/ar795371
- 駒を動かす
>>> board.push(shogi.Move.from_usi(["操作"]))
- 盤面を描画する
>>> print(board.kif_str()))
- SFEN形式の文字列を取得
>>> board.sfen()
Tips
過度なアクセスはサーバーに負荷をかけるので十分に注意しよう。 少なくとも1秒くらい間隔を開けながらアクセスする!