การประกวด BlackJack KOTH


13

กระบอง

ในขณะที่ฉันทำงานหนักกับ KOTH ดั้งเดิมฉันจึงอยากลองทำเกมอื่น สำหรับฉันแล้วความสนุกของความท้าทาย AI เหล่านี้คือการปรับแต่งบอทที่ค่อนข้างเรียบง่ายซึ่งเล่นเกมอย่างง่าย ๆ อย่างละเอียด เนื่องจากลักษณะความน่าจะเป็นของเกมไพ่ฉันคิดว่าแบล็คแจ็คอาจเป็นเกม KOTH ที่น่าสนใจเหมือนกับ TPD

กฎทั้งหมดมาจากคำอธิบายของเว็บไซต์ BlackJack พร้อมรองเท้า

กฎระเบียบเกี่ยวกับไพ่และสำรับ

  • บอทเล่นที่โต๊ะของผู้แข่งขันสี่ (4) คนและหนึ่ง (1) เจ้ามือ
  • ผู้เล่นทุกคนและตัวแทนจำหน่ายจนกว่าจะหมดรองเท้า (หนึ่ง) (ไพ่สำรับแบบสับไพ่) จนกว่าผู้เล่นนั้นจะหมดท่าตรงจุดนี้จะมีการเพิ่มสำรับแบบสุ่มแบบสุ่มใหม่และการเล่นจะดำเนินต่อไป บอทจะไม่ได้รับการแจ้งจากการเพิ่มเด็คใหม่นี้ การแจ้งเตือนดังกล่าวอาจถูกเพิ่มหากไม่มีคุณสมบัตินี้ทำให้เกิดความทุกข์ / ปัญหาอย่างเพียงพอ
  • มีการบายอินจำนวน 10 ครั้งต่อรอบและบัตรฟรี
  • มือที่สมบูรณ์แบบ / อุดมคติมีคะแนน 21
  • การ์ดใบหน้าทั้งหมดมีค่า 10
  • การ์ดตัวเลขทั้งหมดมีค่าหมายเลขของพวกเขา
  • เอซมีค่า 11 หรือ 1 ซึ่งจะจัดการโดยอัตโนมัติโดยกรอบไม่ใช่บอท
  • ตามกฎแล้วไพ่ของผู้เล่นทุกคนจะหงายหน้าและมองเห็นได้ ไพ่ใบหนึ่งของเจ้ามือคว่ำหน้าลงและไพ่อีกใบหงายหน้า

เกณฑ์การให้คะแนน

  • คะแนนเกิน 21 ซึ่งใช้เอซเป็น 11 บังคับให้เอซลดค่าเป็น 1
  • คะแนนเกิน 21 ซึ่งไม่สามารถบีบบังคับต่ำกว่าเกณฑ์ 21 "bust" บอท

ตัวแทนจำหน่าย

  • ดีลเลอร์จะจับจนกว่าเขาจะได้คะแนนหรือเกินระดับ 17 คะแนนจากจุดที่เขาถูกบังคับให้ยืน

การเดิมพันและชิป

  • ในช่วงเริ่มต้นของแต่ละรอบจะมีการเรียกเก็บเงินบายอินจาก 10 ดังนั้นจึงมีเงินเดิมพันขั้นต่ำ10 และเดิมพันขั้นต่ำ1 หมายเหตุ - การเดิมพันเป็นค่าสัมบูรณ์ของการโต้แย้งการเดิมพันดังนั้นไม่ต้องกังวล ลองเดิมพันเชิงลบ
  • บอทที่ไม่สามารถซื้อได้จะถูกลบออกจากการแข่งขัน
  • เมื่อทำการเดิมพันบอตจะไม่สามารถเดิมพันได้มากกว่าชิปที่มี
  • หากการเดิมพันเป็นไปได้การเดิมพันชิปจะถูกลบออกจากบอทและเพิ่มลงในเงินเดิมพัน
  • การชนะการเดิมพันจะทำให้การเดิมพันของชิป 2x อย่างไรก็ตามเนื่องจากการเดิมพันนั้นถูกหักออกจากชิปของบอทบอทจึงทำการหักและชนะการเดิมพัน 1x
  • บอทชนะการเดิมพันเฉพาะในกรณีที่คะแนนของพวกเขามากกว่าของดีลเลอร์

รายละเอียดการเล่นเกม

มือเดียว

  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.

เป็น (ตอนนี้) ที่บันทึกไว้ในไฟล์การ์ด:

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

ซอร์สโค้ดสำหรับระบบการให้คะแนนอยู่ที่นี่

บอทตัวอย่าง

Lim 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

การคัดเลือกผู้ชนะ

ผู้ชนะจะเป็นผู้เขียน ธ ปท. ซึ่งมีการสะสมชิปมากที่สุดอย่างต่อเนื่องตามจำนวนโต๊ะและรอบที่กำหนด ผู้ชนะจะได้รับการประกาศในวันที่ 3 มิถุนายน แต่การประกาศอาจล่าช้าหากยังมีการส่งผลงานเข้ามา การประกวดขยายไปเรื่อย ๆ


คำถาม: การ์ดที่มองเห็นรวมอยู่ในมือของผู้เล่นเองหรือไม่?
dmckee --- ผู้ดูแลอดีตลูกแมว

คำถามที่สอง: เรารู้จำนวนไพ่ที่เราไม่สามารถเห็นได้หรือไม่
dmckee --- ผู้ดูแลอดีตลูกแมว

ตอบไปที่ # 1 - ใช่; คำตอบของ # 2 - วิธีการใช้เครื่องมือนี้ไม่มีการ์ดซ่อน บัตรที่มองเห็นได้คือไพ่ทุกใบที่แจกจากรองเท้าทุกใบที่ใช้ในรอบปัจจุบัน การคืนการ์ดที่มองเห็นได้จะถูกล้างไม่ได้อยู่ในรองเท้าใหม่ (เพราะส่วนหนึ่งของรองเท้าเก่ายังคงอยู่ในการเล่น) แต่จะถูกล้างแทนเมื่อสิ้นสุดรอบ นี่เป็นตัวเลือกสถาปัตยกรรมที่ฉันสร้างขึ้นมาเพื่อความเรียบง่ายซึ่งสามารถแก้ไขได้หากคุณพบว่าไม่มีการ์ดที่ซ่อนอยู่ซึ่งเป็นปัญหา
arrdem

อัปเดต: ตรวจสอบลิงก์กฎ ตอนนี้เอ็นจิ้นใช้การ์ดที่ซ่อนอยู่ แต่การ์ดที่ซ่อนอยู่ในปัจจุบันเท่านั้นหนึ่งในการ์ดฐานของดีลเลอร์
arrdem

บอทสามารถแยกความแตกต่างการ์ดที่มองเห็นเป็นตัวแทนจำหน่ายได้อย่างไร
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;
}

กลยุทธ์ที่นี่มีการบันทึกไว้ในความคิดเห็น แต่ตรงไปตรงมามาก การเดิมพันเพิ่มเติมนั้นเกิดขึ้นในสองกรณีเท่านั้น (เดิมพันไม่เพียงพอในรอบถัดไปหรือลงสองเท่า) และสิ่งนี้อาจต้องเปลี่ยน

เกมนี้แตกต่างจากไกด์ที่นำเสนอสำหรับผู้เล่นการพนันคาสิโนซึ่งไม่มีข้อมูลเฉพาะเกี่ยวกับบัตรแสดงของดีลเลอร์ (หรือเราสามารถเป็นข้อมูลสุดท้ายได้visibleหรือไม่) ดังนั้นจึงมีการคาดเดาตัวเลขมายากลบางอย่าง

อาจต้องใช้การด้อมเล็กน้อยเพื่อตอบคำถามสองข้อในความคิดเห็น

ชื่อจากเกมชื่อแรกของฉันและเพลงพื้นบ้านเก่า


ไพ่สิบใบถูกแทนด้วยอักขระ 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 * (คะแนน / 21)) ด้วยวิธีนี้บอทจะวางเดิมพันทุกที่ที่ทำได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.