BlackJack KOTH比赛


13

黑杰克

当我为最初的KOTH挑战进行爆炸时,我想提出另一个挑战。对我而言,这些AI挑战的乐趣在于改进了一个相对简单的机器人,该机器人巧妙地玩了非常简单的游戏。由于纸牌游戏的概率性质,我认为二十一点就像TPD一样可能是一个有趣的KOTH游戏。

所有规则均源自该网站对BlackJack鞋子的描述

卡片和套牌规则

  • 机器人在四(4)名竞争对手和一(1)名经销商的牌桌上玩
  • 所有玩家和发牌者都共用一(1)张鞋(洗过的甲板)直到用尽为止,此时将添加新的随机洗过的甲板,并继续比赛。目前,尚未通知机器人已添加新平台。如果缺少此功能会引起足够的困扰/麻烦,则可以添加此类通知。
  • 每回合买入10张,免费提供卡
  • 完美/理想手牌得分为21
  • 所有面部卡的值为10
  • 所有数字卡都值钱
  • ace值11或1。这将由框架自动处理,而不是由自动程序处理。
  • 按照规则,所有玩家的卡面朝上并可见。经销商的一张牌面朝下,另一张牌面朝上。

计分

  • 得分超过21且使用ace作为11迫使ace的价值降低到1
  • 超过21的分数不能强制低于21“破坏”机器人的阈值

经销商

  • 庄家抽牌直到他破产或得分超过17 ,这时他被迫站立

博彩和筹码

  • 在每一轮的开始,一个买入的10充电,所以有最低持股比例的10,最小下注 1 -赌注是下注参数的绝对值,所以也懒得尝试下注。
  • 无法负担买入的机器人被从比赛中删除
  • 下注时,机器人不能下注超过其拥有的筹码
  • 如果有可能下注,则将筹码下注从机器人中删除并添加到赌注中
  • 赢得下注将使机器人获得2倍筹码下注。但是,由于从筹码中减去了赌注,因此该机器人收支平衡,然后赢得了该赌注的1倍。
  • 机器人只有在其分数大于发牌人的分数时才能赢得赌注

游戏性细目

单手

  1. 游戏开始时,每位玩家都会迭代发一张牌,并从其筹码中减去10美元的买入费/最低赌注。
  2. 经销商抽奖
  3. 第二次过关,并且另一张卡发给所有玩家。
  4. 经销商抽奖
  5. 然后(按照处理它们的顺序)按照“程序员界面”部分中的说明执行每个漫游器,并且必须移动或站立。博彩被视为举动。注意,下注不会影响机器人进行进一步移动的能力。很有可能先下注然后下一张牌,也有可能在出局前先下多张牌并下注。
  6. 当所有机器人停止运行或站起来时,发牌人的游戏极限达到17
  7. 然后将机器人的分数与庄家的分数进行比较,赌注获胜和输掉

一轮

被认为构成五(5)手。在两手之间,对参赛者列表进行排序以删除玩家,然后进行进一步处理,以确保所有机器人都玩相同数量的手(这一事实规定,参赛人数不会在四人桌之间平均分配) )。

程序员的界面和法律举措

如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":   '#'

评分系统的源代码为HERE

样本机器人

林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的答案-该引擎的实现方式,没有隐藏的卡片。可见卡片是在本回合中消耗的每只鞋子发出的每张卡片。可见卡片的退货不会在新鞋上清除(因为部分旧鞋可能仍在使用中),而是在回合终止时清除。这是我为简单起见而选择的体系结构选择,如果您发现缺少隐藏卡有问题,可以对其进行修改。
2011年

更新:检查规则链接。引擎现在实现了隐藏卡,但是目前唯一的隐藏卡是经销商的基本卡之一。
2011年

漫游器如何辨别经销商是哪张可见牌?
cthom06 2011年

Answers:


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?中的最后一项),因此某些魔术数字是猜测。

根据评论中两个问题的答案,可能需要适度的轻描淡写。

游戏名称,我的名字和古老的民谣


十张纸牌用T字符表示。将使用列表更新竞赛帖子。
2011年

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))筹码。这样,机器人将在可能的情况下积极下注。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.