「作業を楽しくすることは生産性の向上につながる」という信念のもとに、
commitするたびに ポーカーで遊ぶ スクリプトを作りました。
「作業を楽しく」の方向性が完全に斜め上ですが気にしてはいけません。
作るもの
- commit後に生成される、short hash値7桁の英数文字列を7枚のカードに見立ててポーカーを行う
- commitのたびに役を自動判定、メッセージを表示する
hash値ポーカー ルール
- テキサスホールデムに準じ、7枚中任意の5枚で作られる役のうち最強のものを手役とする
- カードは数字0~9,アルファベット小文字a~fの計16種。強弱もこの順
- トランプと違ってマークが無いので,フラッシュ系の役は無し
- ペア形はできやすい反面、16種もあるのでストレートが最難関(なはず。。。ちゃんと検証してないけど)
- というわけで役の強さは
ストレート > ファイブカード(笑) > フォーカード > フルハウス > スリーカード > ツーペア > ワンペア とする
実装
以下のコードを、プロジェクト内の.git/hooks/post-commit
に保存。
.git/hooks/post-commit
#!/usr/bin/env ruby
# 手札がストレートかどうか判定する関数
def straight?(cards)
# ソートした上で、文字列比較を使って判定
all_cards_sequence = (("0".."9").to_a + ("a".."f").to_a).join
cards_sequence = cards.split(//).sort.join
(0..2).each do |i|
return true if all_cards_sequence.include?(cards_sequence.slice(i,5))
end
false
end
# メッセージハッシュ お好みで編集して下さい
messages = {
straight: "Congratulations!! Straight!!",
five_of_a_kind: "Unbelivable! Five_of_a_kind!",
four_of_a_kind: "Bravo! Four_of_a_kind!",
full_house: "Excellent! Full_house!",
three_of_a_kind: "Three_of_a_kind!",
two_pair: "Two_pair!",
one_pair: "One_pair!"
}
# short hashを取得
cards = `git log -1 --format=format:%h HEAD`.chomp
# cardの枚数の構成を計算
same_card_counts = cards.split(//).group_by{ |r| r }.values.map(&:size).sort.reverse
# 手役の判定
result =
if straight?(cards)
:straight
elsif same_card_counts.max >= 5
:five_of_a_kind
elsif same_card_counts.max == 4
:four_of_a_kind
elsif same_card_counts.max == 3
if same_card_counts == [3,1,1,1,1]
:three_of_a_kind
else
:full_house
end
elsif same_card_counts.max == 2
if same_card_counts == [2,1,1,1,1,1]
:one_pair
else
:two_pair
end
end
puts "\e[31m"+messages[result]+"\e[0m" if result
実装ポイント
- post-commit フックを使えばコミットごとに好きなスクリプトを起動できます
-
git log
のformatオプションを使うと表示項目をある程度好きに弄れます - 最終的な手役の判定ですが、"7枚中任意の5枚を選んだ組合せで作れる手役のうち強さを比較してぐぬぬ"とかやるより、7枚の構成を見て一気に判定した方が楽でした
- ストレートかどうかの判定は"連続である文字列中に現在の手札が出現するか"という発想でやってみました
所感
- 方向性はともかく"たくさんcommitしたくなる仕掛け"を施すのは実際にモチベーション上がりますよ(言い訳)
- 仕掛けた直後にいきなりフォーカード出てバグかと思いました(自虐風自慢)
- ちょっと重いのでもう少し高速化したいところですね(丸投げ)