40
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

git commitを楽しくする(その1:hash値ポーカー編)

Last updated at Posted at 2015-01-07

「作業を楽しくすることは生産性の向上につながる」という信念のもとに、
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したくなる仕掛け"を施すのは実際にモチベーション上がりますよ(言い訳)
  • 仕掛けた直後にいきなりフォーカード出てバグかと思いました(自虐風自慢)
  • ちょっと重いのでもう少し高速化したいところですね(丸投げ)
40
39
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
39

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?