Akata Works

東京エンジニア。主にRuby,Go,たまにAWSとiOS。ゲーム音楽が好きです。連絡はTwitterかakata.onen@gmail.comまで

タイピングゲームを自動化するスクリプトを組んだった

今更ながら、YAPC::ASIA 2011の竹迫さんの発表を見て興味を持ったので、
Win32::GuiTestモジュールを触ってみました。

まあ、.NET Framework使えよって話ですがね。
せっかくオープンソース化されたので、時間があれば読んでおきたいな。

開発環境はCygwinとStrawberry Perlです。
Image MagickやImage::Magickモジュールのインストールがめんどうだった。
ちゃんと32Bitで統一しよう(;´Д`)=3

竹迫さんが発表で仰っていましたが、
タイピングゲームを自動化すると面白そうだったので自動化しました。

akatakun/auto-typing · GitHub

画像ファイルとスクリーンショットをマッチングする簡単な仕組みですが、
X座標でソートして一気に打ち込むのはうまく出来たと思う。

sub match_words {
  my ( $screenshot, $words ) = @_;

  my %match_words;
  for my $word ( keys %$words ) {
    my @coords = $screenshot->match( $words->{ $word }, multiple => 1 );
    my @xs = @coords[ grep { $_ % 2 == 0 } 0 .. $#coords ];
    $match_words{$_} = $word for @xs;
  }
  return \%match_words;
}

これを某サイトで試したところランキングトップを超えるスコアを出せました(^ρ^)

恐らく画像ファイルさえ用意すれば、ほとんどのサイトで動くと思いますが、
ブラウザの解像度やエリアシングの有無でぱたりと動かなくなりますorz

最後に、、ランキング荒らしちゃ駄目だよ

参考サイト

Perlのプラグマについて調べてみた

ふと、プラグマってたまーに聞くけど一体全体何なんだって思ったので調べてみた

個人的にはPerlプログラミング救命病棟の以下の説明がしっくりきた

Perlコンパイラの動作を変更するモジュールである

φ(゚Д゚ )フムフム…

確かにstringもwarningもutf8プラグマもPerl自体の動作を変えますね!!
あと、小文字なのは慣習らしいです

普通の関数やモジュールと何が違うんだろうってずっと思ってましたが
ようやくスッキリしました+.゚(*´∀`)b゚+

VimをインストールするためのAnsible-Roleを書いた

最近忙しくてちょっとペースが落ちてきているのが気になるakataです。
気が付いたら社会人も二年目になっていました。

今回は前回に引き続き、AnsibleでVimをインストールするためのRoleを書きました!!
と言っても、ほとんどGitの使い回しですが・・(^_^;)
一応、".vimrc"ファイルと".vim/"ディレクトリのシンクまでできます。

akatakun/ansible-role-vim · GitHub

あと、Role内の変数名はRole名を付けるのが良いっぽいので、GitのRoleにも少し修正を加えました。

よーし、残りはZshのRoleを書いたら終わりかなー(;´∀`)=3

参考URL

GitをインストールするためのAnsible-Roleを書いた

まあ、タイトルどおりなんですが、AnsibleでGitをインストールするためのRoleを書きました!! でも、実際はセッティングとリポジトリのクローンまでできますよ。

本当はずいぶん前に書いたものもあるのですが、冪等性(笑)状態で、最適化もしていないオレオレAnsible Roleだったので・・

今回は外部に公開するつもりで思いっきり修正してきました!!

というわけで、GitHubに公開しました。
そのうちAnsible Galaxyにも公開すると思います。

akatakun/ansible-role-git · GitHub

git configやgitメソッドリポジトリをクローンするとき、どうやって冪等性を担保しようかなど、Ansibleの勉強にもなったのでよかったです(まあ、git configは元々冪等性が担保されているのですが・・)

Perlの文字列の扱い方・・其の壱

いい加減に理解しておこうと思って、Perlの文字列の扱い方についてまとめました。長いので2回に分けたいと思います。あと、ちょっと覚書みたいになってます(文章って難しい・・)

簡単に概要と背景ですが、

Perlのバージョン5.8以降は内部文字列をutf8として扱うため、マルチバイト文字列が使用することができるようになりました。 そのとき、下位互換性を保つため、utf8フラグが付いている文字列を内部文字列とし、それ以外を外部文字列としました。

内部文字列:utf8フラグあり
外部文字列:utf8フラグなし

こんな感じだと思います。

ここで、ソースコード内に定義された文字列リテラルが内部文字列か外部文字列かを明示するプラグマについて紹介します。

これには"use utf8"プラグマと"use bytes"プラグマがあります。

"use utf8"プラグマはレキシカルスコープ内の文字列リテラルを内部文字列として扱い、"use bytes"プラグマは外部文字列として扱います。

以下のソースコードの実行結果が分かりやすいと思います。

use strict;
use warnings;

{
  use utf8;

  my $string = 'ほげ';

  print 'is utf-8: ' . ( utf8::is_utf8( $string ) ? 'true' : 'false' ) . $/;
  print 'lengths : ' . length( $string ) . $/;
  print 'string  :' . $string . $/;
}

{
  use bytes;

  my $string = 'ほげ';

  print 'is utf-8: ' . ( utf8::is_utf8( $string ) ? 'true' : 'false' ) . $/;
  print 'lengths : ' . length( $string ) . $/;
  print 'string  :' . $string . $/;
}

これを実行するとこうなります。

is utf-8: true
lengths : 2
Wide character in print at encode.pl line 64.
string  :ほげ
is utf-8: false
lengths : 6
string  :ほげ

前者の"ほげ"は内部文字列として扱われ、6バイトで2文字の文字列の長さが2であると解釈されていて、後者の"ほげ"は外部文字列として扱われ、6バイトで2文字の文字列の長さが6であると解釈されています。

なんで6バイトなのかというと、uft8における日本語が1文字で3バイトだからです。

ちなみにutf8::is_utf8関数はutf8フラグが付いているかを表す関数で、"Wide character in print at"という警告は内部文字列を出力したときに発生します。気になる方は次回で紹介するencode関数を使うといいです。

このようにPerlにはutf8フラグが付いているかで変化する処理があるため注意が必要です。デメリットもあまりないため、よく分からない人はなるべくutf8フラグを付けておくといいと思います。

ちょっと一息( ゚ ρ ゚ )ボーーーー(次回に続く)

AWS S3とBase64エンコードの話

最近、すごいエンジニアの人のブログを最初の記事から読んでいます。 勉強になるのはもちろんのこと、すごいエンジニアの人に比べて自分の成長スピードがいかほどか比較できておもしろいです(やっぱりすごい人はすごい!!)

さて、本題に入ります。

前々回の記事ではNet::Amazon::S3モジュールでAWS S3にアクセスする方法を紹介しました。

しかし、他の人からいただいたAccessKeyIDとSecretAccessKeyではなぜかアクセスすることができなかった/(^o^)\ナンテコッタイ

SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method. at ...

どうやら「SecretAccessKeyがおかしいぞ、ちゃんと確認しろよ!!」(意訳)ということだそうで、さっそく提供者に文句の1つでも入れたいところですが、ここはぐっと堪えて、エンジニアらしい原因の追及を試みることにしました。


ちゃんと調べていないですが、なんかSecretAccessKeyはBase64エンコードされているっぽいです・・

ここで、Base64エンコードについて簡単に紹介しておくと

  • 元データを64種類の印字可能な英数字(A-Z,a-z,0-9,+,/,=)のみを用いて表現する
  • 元データを6ビットごとに分割し、6ビットに満たなければ"0"を追加する
  • 6ビットのデータを変換表で4文字ごとに変換し、4文字に満たなければ"="を追加する

こんな感じの特徴があります。

あれ!?

でも、僕のもらったSecretAccessKey、41文字なんですけど・・4の倍数じゃないんですけど・・ てか、先頭に"="付いてるんですけど・・

案の定、"="を外したらちゃんと動きましたとさ(チャンチャン)

結論

提供者に確認中だけど多分"="いらない

確認って大事

参考URL

[Amazon S3]Bucket一覧取得

http://www.wikiwand.com/ja/Base64

CygwinでZshを使う

最近、Windows側の操作は専らCygwinを使っています。

僕の基本ツールの中でもTmuxとVim,Gitはもう入れていたのですが、Zshはまだ入れていなかったので、ササッと入れるつもりで挑んでみました。

パッケージ管理ツールとしてapt-cygコマンドが入っていれば、以下のコマンドでインストールできます。

$ apt-cyg install zsh

何事もなく導入が終わりました。

早速、ログインシェルに設定しようとchshコマンドを叩いてみると・・

$ chsh -l
bash: chsh: コマンドが見つかりません

な、なんだと・・

まあ、これはあるある問題みたいで"/etc/passwd"ファイルを直接編集したらいいとのこと(そらそうか)

しかし、

$ ls /etc/passwd
ls: /etc/passwd にアクセスできません: No such file or directory

何故か存在しない"/etc/passwd"ファイルorz

なんでだろう、セットアップのときにJust Meにしたからだろうか・・

ファイルがない原因は調べてないので分かりませんが、生成する方法はあるらしく、以下のコマンドで無事に生成されました。

$ mkpasswd > /etc/passwd

よかったよかった。

しかし、ログインしたユーザが辿り着いた先は、何故か"/cygdrive/c/Windows/system32/"ディレクトリであった・・

ホームディレクトリの設定は変えていないのに・・そしてBashに戻すと何事もなかったようにホームディレクトリに辿り着く。

結局、めんどうくさくなっちゃって、下記を"/etc/zprofile"ファイルに記述して暫定対応しちゃったんだけど、ログインのときにホームディレクトリに移動する仕組が分かれば解決はできそうですね(ログインシェルで"/etc/passwd"ファイルに書かれたパスに移動しているのだろうか・・)

# For Cygwin.
if [ "$( uname -o )" = 'Cygwin' ]; then
  # Is not changed home directory for some reason, when login shell is Zsh.
  cd
fi

参考URL

DY - Re: No etc/passwd (was) Re: (everything!) command not found