BlackJack KOTHコンテスト


13

ブラックジャック

元のKOTHチャレンジに取り組んでいたので、別のチャレンジを思いつきました。私にとって、これらのAIチャレンジの楽しみは、非常にシンプルなゲームを微妙にプレイする比較的シンプルなボットを改良することです。カードゲームの確率的性質のため、ブラックジャックはTPDと同様に興味深いKOTHゲームになる可能性があると思います。

すべてのルールは、このウェブサイトのBlackJack with shoesの説明に基づいています

カードとデッキに関する規則

  • ボットは4人の競技者と1人のディーラーのテーブルでプレーします
  • 1つの靴(シャッフルデッキ)は、すべてのプレイヤーとディーラーによって共有されます使い果たされるまで、その時点で新しいランダムにシャッフルされたデッキが追加され、プレイが続行されます。ボットは(この時点では)この新しいデッキの追加について通知されません。この機能の欠如が十分な苦痛/トラブルを引き起こす場合、そのような通知は追加されるかもしれません。
  • ラウンドごとに10のバイインがあり、カードは無料です
  • パーフェクト/理想的なハンドのスコアは21です
  • すべてのフェイスカードの値は10です
  • すべての数字カードはその価値があります
  • エースは11または1の価値があります。これは、ボットではなくフレームワークによって自動的に処理されます。
  • あたりとしてのルール、すべてのプレイヤーのカードがフェイスアップを配らと表示されています。ディーラーのカードの1つは裏向きで、もう1つは表向きです。

得点

  • エースを11として使用する21を超えるスコアは、エースの値を1に強制的に下げます。
  • 21を超えるスコアは、ボットを「バスト」する21のしきい値より下に強制することはできません。

ディーラー

  • ディーラーは彼がバストするまで引きます、または17 点を超えた時点で、彼は立つことを強制されます

ベットとチップ

  • 各ラウンドの開始時に、バイイン10のは、そう、最低があり、充電されている株式 10のは、最小賭け 1のNOTE -賭けは賭けの引数の絶対値であるので、気にしないでください負の賭けをしようとしています。
  • バイインを買う余裕のないボットはコンテストから除外されます
  • 賭けをするとき、ボットは持っているチップよりも多く賭けることはできません
  • 賭けが可能であれば、賭けたチップはボットから即座に取り除かれ、賭け金に追加されます
  • ベットに勝つと、ボットに2xチップがベットされます。ただし、ボットのチップからベットが差し引かれるため、ボットは偶数になり、ベットの1倍になります。
  • ボットはディーラーのスコアよりもスコアが大きい場合にのみベットに勝ちます

ゲームプレイ内訳

片手

  1. ゲームが開始されると、各プレーヤーは1枚のカードを繰り返し配られ、チップから10ドルのバイイン料金/最小ベットが差し引かれます。
  2. ディーラーが描く
  3. 2回目のパスが行われ、別のカードがすべてのプレイヤーに配られます。
  4. ディーラーが描く
  5. 次に、(それらが配られたのと同じ順序で)各ボットは、「プログラマインタフェース」セクションで説明したように実行されなければならない行動を起こすか、立っています。ベットは動きと見なされます。ベットがボットのさらなる移動能力に影響しないことに注意してください。ベットしてからカードを引くことは非常に可能であり、複数のカードを引いて、立っている前にそれらをベットすることもできます。
  6. すべてのボットが破壊または立ち上がると、ディーラーは17のしきい値までプレイします
  7. ボットのスコアはディーラーのスコアと比較され、ベットは勝ち負けになります

ワンラウンド

5つのハンドを構成すると見なされます。ハンド間では、競技者のリストがソートされてプレーヤーが削除され、さらに処理されて、すべてのボットが同じ数のハンドをプレイするようにします(エントリ数が4つのボットテーブル間で均等に分割されないという事実の規定) )。

プログラマーのインターフェースと法的動き

CardSharkファイルに記載されているとおり:

#   DOCUMENTATION
#       INPUT SPECIFICATION
#          $ ./foo.bar <hand-score> <hand> <visible cards> <stake> <chips>
#          <hand-score>     is the present integer value of the player's hand.
#          <hand>           is a space-free string of the characters [1-9],A,J,Q,K
#          <visible cards>  every dealt card on the table. when new shoes are brought
#                           into play, cards drawn therefrom are simply added to this list
#                           NOTE: the first TWO (2) cards in this list belong to the dealer.
#                             one however will be "hidden" by a "#". the other is visible.
#                           !!! THE LIST IS CLEARED AT THE END OF HANDS, NOT SHOES !!!
#          <stake>          the  number of chips which the bot has bet this hand
#          <chips>          the number of chips which the bot has
#       SAMPLE INPUT
#          $ ./foo.bar 21 KJA KQKJA3592A 25 145
#
#       OUTPUT SPECIFICATION
#          "H"|"S"|"D"|"B"  (no quotes in output)
#          "H"              HIT - deal a card
#          "S"              STAND - the dealer's turn
#          "D"              DOUBLEDOWN - double the bet, take one card. FIRST MOVE ONLY
#          "B 15"           BET - raises the bot's stakes by $15.

(現在)カードファイルに記載されているとおり:

#       class CARD
#           card is a container for representing paper playing cards in
#           otherwise fairly functional programming.
#           letter()
#               gets the letter used to identify the card in a string  
#               LETTER MAPPINGS  
#                   Ace     :   'A'
#                   Two     :   '2'
#                   Three   :   '3'
#                   Four    :   '4'
#                   Five    :   '5'
#                   Six     :   '6'
#                   Seven   :   '7'
#                   Eight   :   '8'
#                   Nine    :   '9'
#                   Ten     :   'T'
#                   Jack    :   'J'
#                   Queen   :   'Q'
#                   King    :   'K'
#                   "Hidden":   '#'

スコアリングシステムのソースコードはこちら

サンプルボット

リム17

#!/usr/bin/env python
import sys
s = sys.argv
if int(s[1]) < 17:
    print "H"
else:
    print "S"

エントリー言語

現在、Java、c / c ++、Python、およびLispがサポートされています。他の言語の提出物を含めるための合理的な努力がなされますが、最終コンテストはLinuxボックスで実行されることを忘れないでください。

勝者の選択

勝者は、まだ決定されていないテーブルとラウンドの数で一貫してほとんどのチップを獲得したボットの作者です。 受賞者は6月3日に発表されますが、まだ提出されている提出物がある場合、発表は遅れる可能性があります。 コンテストは無期限に延長されました。


質問:目に見えるカードには、プレイヤー自身の手札のものが含まれていますか?
dmckee ---元モデレーター子猫

2番目の質問:表示されていないカードが何枚配られたか知っていますか?
dmckee ---元モデレーター子猫

#1への回答-はい。#2への回答-このエンジンの実装方法、隠されたカードはありません。可視カードは、現在のラウンドで消費されたすべての靴から配られたすべてのカードです。可視カードの返品は新しい靴ではなくクリアされます(古い靴の一部がおそらくまだ使用されているため)。代わりにラウンド終了でクリアされます。これは単純化のために私が行ったアーキテクチャの選択であり、隠されたカードの欠如に問題がある場合は修正できます。
11

更新:ルールのリンクを確認してください。エンジンは隠しカードを実装するようになりましたが、現時点で唯一の隠しカードはディーラーのベースカードの1つです。
11

ボットはどの可視カードをディーラーと区別することができますか?
-cthom06

回答:


3

BlackJackDavey

退屈で昔ながらのc。ANSIまたはc99でコンパイラする必要があります。

/* BlackJackDavey
 *
 * A entry for
 * http://codegolf.stackexchange.com/questions/2698/a-blackjack-koth-contest
 * copyright 2011 
 *
 * Currently expects a slightly extended version of the spec. Two
 * expected changes:
 * - Tens will be represented as 'T'
 * - The visible card string will include '#' for those cards whose
 *     *backs* we can see (slight improvement in card counting technique)
 * 
 * No disaster if neither feature is present, just sligtly degraded
 * performance.
 */
#include <stdio.h>
#include <string.h>

/* A full deck has a total value of 4*( (11*5) + (3*10) + ace ) where
 * ace is 11 or according to our need.
 **/
int fullWeight(const int current){
  int ace = (current>10) ? 1 : 11;
  return 4 * ( 11*5 + 3*10 + ace);
}
/* Return the value of a particular card in the context of our
 * current score
 */
int cardWeight(const char c, const int current){
 switch (c) {
 case '1': case '2': case '3': case '4': case '5':
 case '6': case '7': case '8': case '9':
   return (c - '0');
 case 'T': case 'J': case 'Q': case 'K':
   return 10;
 case 'A':
   return current>10 ? 1 : 11;
 }
 return 0;
}
/* returns the mean card *value* to be expected from the deck 
 *
 * Works by computing the currently unknown value and diviing by the
 * number of remaining cards 
 */
float weight(const char*known, const int current){
  int weight = fullWeight(current);
  int count=52;
  int uCount=0;
  const char*p=known;
  while (*p != '\0') {
    if (*p == '#') { /* Here '#' is a stand in for the back of a card */
      uCount++;
    } else {
      weight -= cardWeight(*p,current);
    }
    count--;
    p++;
    if ( count==0 && *p != '\0') {
      count += 52;
      weight += fullWeight(current);
    }
  }
  return (1.0 * weight)/(count+uCount);
}


int main(int argc, char*argv[]){
  int score=atoi(argv[1]);
  const char*hand=argv[2];
  const char*visible=argv[3];
  int stake=atoi(argv[4]);
  int chips=atoi(argv[5]);

  /* If current stake is less than 10, bet all the rest because a loss
     does not leave us enough to continue */
  if (chips < 10 && chips > 0) {
    printf("B %d\n",chips);
    return 0;
  }
  /* First round stategy differs from the rest of the game */
  if (strlen(hand)==2 && stake==10) {
    switch(score){
    case 10:
    case 11: /* Double down on particularly strong hands */
      if (chips >= 10) {
    printf("D\n");
    return 0;
      }
      break;
    default:
      break;
    };
  }
  /* In future rounds or when first round spcialls don't apply it is
     all about maximizing chance of getting a high score */
  if ((score + weight(visible,score)) <= 21) {
    /* if the oods are good for getting away with it, hit */
    printf("H\n");
    return 0;
  }
  /* Here odd are we bust if we hit, but if we are too low, the dealer
     probably makes it.*/
  printf("%c\n", score>14 ? 'S' : 'H');
  return 0;
}

ここでの戦略はコメントに記載されていますが、非常に簡単です。追加の賭けは2つの場合にのみ行われ(次のラウンドの賭け金が十分ではない、またはダブルダウン)、これは変更が必要な場合があります。

ゲームは、カジノのギャンブラーに提供されるガイドとは異なり、ディーラーの表示カードに関する特定の情報がありません(または、それが最後のエントリである可能性があります) visibleますか?)、マジックナンバーの一部は推測になります。

コメント内の2つの質問への回答によっては、控えめなディドリングが必要になる場合があります。

ゲームの名前、私の名前、そして 古いフォークバラード


10枚のカードはTキャラクターで表されます。リストでコンテストの投稿を更新します。
11

3

リニアベット

#!/usr/bin/env python
from __future__ import division
import sys
s = sys.argv

c=150    # chip modifier
f=15     # stand score

if int(s[1]) < f:
    print "H"
else:
    if int(s[4]) == 10:
        print "B", (int(s[1])/21)*c
    else:
        print "S"

このボットは17戦略の修正版です。このボットは、スコアが15(f)を超えるまでドローし、int(c *(score / 21))チップをベットします。このようにして、ボットは可能な限り積極的にベットします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.