블랙 잭 KOTH 콘테스트


13

곤봉

원래의 KOTH 도전에 대한 폭발이 일어 났을 때 나는 또 다른 도전을 원했습니다. 저에게 AI 도전 과제의 재미는 매우 간단한 게임을 미묘하게 수행하는 비교적 간단한 봇을 개선하는 것입니다. 카드 게임의 확률 적 특성으로 인해 블랙 잭은 TPD처럼 재미있는 KOTH 게임이 될 수 있다고 생각합니다.

모든 규칙은이 웹 사이트의 BlackJack 신발 설명에서 파생됩니다.

카드 및 갑판에 관한 규칙

  • 봇은 4 명의 경쟁자와 1 명의 딜러의 테이블에서 플레이합니다.
  • 모든 플레이어 와 딜러 가 고갈 될 때까지 신발 (셔플 데크) 1 개가 공유되며 ,이 때 무작위로 섞인 새 데크가 추가되고 플레이가 계속됩니다. 봇은이 새로운 데크의 추가를 통지받지 않습니다 (현재). 이 기능이 부족하여 충분한 조난 / 문제가 발생할 경우 이러한 알림이 추가 될 수 있습니다.
  • 라운드 당 10의 바이 인이 있으며 카드는 무료입니다
  • 퍼펙트 / 이상 핸드의 점수는 21 점입니다
  • 모든 얼굴 카드의 값은 10입니다
  • 모든 숫자 카드는 그만한 가치가 있습니다
  • 에이스는 11 또는 1의 가치가 있습니다. 이것은 봇이 아닌 프레임 워크에 의해 자동으로 처리됩니다.
  • 에 따라 규칙 , 모든 플레이어 '카드는 페이스 업을 처리하고 볼 수 있습니다 있습니다. 딜러 카드 중 하나는 아래를 향하고 다른 카드는 위를 향합니다.

채점

  • 에이스를 11로 사용하는 21을 초과하는 점수는 에이스의 가치를 1로 줄입니다.
  • 봇의 "버스트"임계 값 아래로 강요 할 수없는 21을 초과하는 점수

딜러

  • 딜러는 파열 될 때까지 끌거나 17 점을 초과 하여 서 있어야합니다.

베팅 및 칩

  • 각 라운드의 시작에서, 바이 인 (10)이 때문에 최소가, 충전 지분 10 및 최소 베팅 (1)의 - 내기가 너무 귀찮게하지 않습니다, 내기 인수의 절대 값 부정적인 베팅을 시도합니다.
  • 바이 인을 감당할 수없는 봇은 컨테스트에서 제거됩니다
  • 베팅 할 때 봇은 보유한 칩보다 더 많이 베팅 할 수 없습니다
  • 베팅이 가능하면 칩 베팅은 봇에서 제거되고 스테이크에 추가됩니다.
  • 베팅에서 이기면 봇 2x 칩이 베팅됩니다. 그러나 봇의 칩에서 베팅이 차감되기 때문에 봇은 짝수를 끊고 내기의 1 배를 얻습니다.
  • 봇은 점수가 딜러의 점수보다 큰 경우에만 베팅에서 승리합니다.

게임 플레이 내역

한 손

  1. 게임이 시작되면 각 플레이어는 한 장의 카드를 반복적으로 처리하며 칩에서 10 달러의 바이 인 / 최소 베팅을 뺍니다.
  2. 딜러는
  3. 두 번째 패스가 이루어지고 다른 플레이어는 모든 플레이어에게 처리됩니다.
  4. 딜러는
  5. 그런 다음 (처리 된 순서와 동일한 순서로) 각 봇은 "프로그래머 인터페이스"섹션에 설명 된대로 실행되며 이동 또는 스탠드 해야합니다 . 베팅은 이동으로 간주됩니다. 베팅이 더 나아가 움직일 수있는 봇의 능력에는 영향을 미치지 않습니다. 카드를 베팅 한 다음 뽑는 것이 매우 가능하며, 여러 카드를 뽑아서 내기 전에 베팅 할 수 있습니다.
  6. 모든 봇이 파열되거나 서있을 때, 딜러는 17의 임계 값까지 플레이합니다
  7. 봇의 점수는 딜러의 점수와 비교되고 베팅에서 이기고집니다.

한 라운드

다섯 손을 구성하는 것으로 간주됩니다. 손 사이에서 참가자 목록은 플레이어를 제거하기 위해 정렬 된 다음 모든 봇이 같은 수의 손을 플레이 할 수 있도록 추가 처리됩니다 (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.

Cards 파일에 문서화되어 있습니다 :

#       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 --- 전 운영자 고양이

두 번째 질문 : 볼 수없는 카드가 몇 개나 처리되었는지 알고 있습니까?
dmckee --- 전 운영자 고양이

# 1에 대답-예; # 2에 대한 답변-이 엔진이 구현되는 방식에는 숨겨진 카드가 없습니다. 보이는 카드는 현재 라운드 동안 소비 된 모든 신발에서 처리 된 모든 카드입니다. 보이는 카드 반품은 새 신발이 아닌 청산됩니다 (오래된 신발의 일부가 아직 재생 중이므로). 대신 라운드 종료시 청산됩니다. 이것은 내가 단순성을 위해 선택한 아키텍처 선택이며 숨겨진 카드가 부족한 경우 문제를 해결할 수 있습니다.
arrdem

업데이트 : 규칙 링크를 확인하십시오. 엔진은 이제 숨겨진 카드를 구현하지만 현재 유일한 숨겨진 카드는 딜러의 기본 카드 중 하나입니다.
arrdem

봇은 딜러가 보이는 카드를 어떻게 구별 할 수 있습니까?
cthom06

답변:


3

블랙 잭

지루하고 구식 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;
}

이 전략은 의견에 문서화되어 있지만 매우 직설적입니다. 추가 베팅은 두 가지 경우에만 이루어지며 (다음 라운드 또는 더블 다운에 대한 지분이 충분하지 않음) 변경해야 할 수도 있습니다.

이 게임은 딜러의 표시 카드에 대한 특정 정보가 없다는 점에서 카지노 도박꾼에게 제공되는 가이드와 일부 다릅니다 (또는 마지막 항목이 될 수 visible있습니까?). 마법의 숫자 중 일부는 추측입니다.

의견의 두 가지 질문에 대한 답변에 따라 약간의 여유가 필요합니다.

게임의 이름, 내 이름 및 오래된 민속 발라드 .


10 개의 카드는 T 문자로 표시됩니다. 컨테스트 게시물을 목록으로 업데이트합니다.
arrdem

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.