Ruby
paiza

paiza #paizajack

六村リオ開放

自分の情報しか見えないし、適当にがんばれば開放できるんじゃないかな。

六村リオバニー開放

相手の手札の情報が見えるので、とりあえず相手のスコア以下なら引く処理は必要。
あと、この段階までに、Aを1とも11とも扱う処理の実装は必須。

「以下」です。未満ではありません。注意。

六村リオ赤バニー開放

山札が見られる仕様。要するに現実であれば山札が表向きになっている。ブラックジャックとしてのゲーム性は皆無ですが、別のゲームとしては面白そうですねorz
(Aがない場合)山札から引けるなら必ず引く処理をこの段階で入れることを推奨します。勝率が目に見えて違います。勝率が高ければ連勝しやすいということです。

  • あと、この辺からは、提出を自動化しないときついかもしれない。Seleniumとかのブラウザツールキット、もしくはUserScriptでできます。
    • まったくの余談ですが、この間少し話題になった「Chromeのheadless」は、UIを表示しないという意味であり、SeleniumからChromeを操作するときに画面が不要というのが利点の一つです。

緑川つばめ赤バニー

  • 掛け金は連勝ごとに上げるようにしてください。たとえ少しであっても、指数関数の伸びは意外と大きいものです。固定するのは本当にもったいないです。
  • 週間ランキングのチップ数が2**31以上になるとき、ゲームが止まるのは仕様のようです。それ以上は当該週は勝利できません(提出はできますし、敗北するならゲームは進行しますが、意味がありません)。

六村リオ赤バニー

ディーラー別ランキングでもなく、累計ランキングですから、9999万賭けたいもの。
というわけで、所持チップが最低でも20億ない状態で挑むのは危険です。山札の状況を確認するコードを書かなくても六村リオ赤バニー開放にはこぎつけますが、ない状態で挑むと死にます( 私の所持チップが一回0になりました )。

ジャックポット

大事なことですが、 指定順位は毎回変わります。 ということは、 全部のディーラーに対して1勝だけするのが確率的に最善です。 この方法で私はアマギフを 8枚中3枚 手に入れました。

答案

tyama_paizapoh13.rb
#!/usr/bin/ruby
#paizajack program by @cielavenir.

def score(cards)
    a,b=cards.partition{|e|e==1}
    (a.size+1).times.map{|i|
        10*i+a.size+b.reduce(0,:+)
    }.select{|e|e<=21}.max
end

cards_s=gets
match_s=gets
streak_s=gets
won_s=gets
dealer_s=gets
deck_s=gets

cards=cards_s.split.map &:to_i
if cards[0]==0
    #六村リオ赤に限り、以下をコメントアウトし、99990000に固定して提出します

    #take care of combo?
    if streak_s.to_i==0
        puts 10000 #cards[1]
    else
        puts (0.4 * won_s.to_i).to_i
    end
    exit
end

if score(cards).nil? || score(cards)==21
    #決着
    #todo:dealerも21になったら負けなので、bustさせるためにあえて引く場合
    puts 'STAND'
    exit
end

if !dealer_s
    #緑川つばめまで
    if cards.reduce(:+)>=16 || score(cards)>=18
        puts 'STAND'
    else
        puts 'HIT'
    end
elsif !deck_s
    #緑川つばめバニーまで
    dealer=dealer_s.split.map &:to_i
    if score(dealer).nil? || score(dealer)==21
        #決着
        puts 'STAND'
    elsif score(cards)>score(dealer)
        #todo: 余裕があるのにスタンドしうる
        puts 'STAND'
    else
        puts 'HIT'
    end
else
    #六村リオ赤バニーまで
    dealer=dealer_s.split.map &:to_i
    deck=deck_s.split.map &:to_i
    dealer_freeze=cards.size>dealer.size 

    if score(dealer).nil? || score(dealer)==21
        #決着
        puts 'STAND'
    elsif dealer_freeze
        #勝つまで引ける
        if score(cards)>score(dealer)
            puts 'STAND'
        else
            puts 'HIT'
        end
    elsif score(cards+[deck[0]]).nil? && score(cards+[deck[1]||99]).nil?
        #詰み
        puts 'STAND'
    elsif score(cards+[deck[0]])&&score(cards+[deck[1]||0])
        #引いて差し支えない
        if score(cards)<=[score(cards+[deck[0]]),score(cards+[deck[1]||0])].max
            puts 'HIT'
        else
            #けど、引かないほうがスコアが高くなるなぁ
            puts 'STAND'
        end
    # 1枚目か2枚目のどちらかは手札に加えて安全…さて、どう出るか。
    elsif score(dealer+[deck[0]]).nil?
        # ディーラーがbustするなら1枚目を引くことになりそうだよね
        if score(cards+[deck[0]]) && score(cards)<=score(cards+[deck[0]])
            puts 'HIT'
        else
            puts 'STAND'
        end
    elsif deck.size<2
        puts 'STAND'
    elsif score(cards+[deck[1]]) && score(dealer+[deck[0]]) && score(dealer+[deck[0]])>=score(cards)
        puts 'HIT'
    else
        puts 'STAND'
    end
end

終わりに

緑川つばめ赤バニーに提出するのは今週までです。以降は六村リオ赤バニーにしか提出しません。

謝辞

山札の処理で一部 @yuichi_sakurada 氏のコードを参考にさせていただきました.