Un contest di BlackJack KOTH


13

BlackJack

Dato che mi sono divertito tantissimo a lavorare sulla sfida originale di KOTH, volevo inventarne un'altra. Per me, il divertimento di queste sfide AI è nel perfezionare un bot relativamente semplice che gioca sottilmente un gioco molto semplice. A causa della natura probabilistica dei giochi di carte, penso che il blackjack potrebbe essere un gioco KOTH interessante proprio come TPD.

Tutte le regole derivano dalla descrizione di questo sito Web di BlackJack con le scarpe

Regole riguardanti le carte e il mazzo

  • I robot giocano ai tavoli di quattro (4) concorrenti e un (1) mazziere
  • Una (1) scarpa (un mazzo mescolato) è condivisa da tutti i giocatori e dal banco fino a quando non si esaurisce, a quel punto verrà aggiunto un nuovo mazzo mescolato casualmente e il gioco continuerà. I robot NON SONO (attualmente) NOTIFICATI dell'aggiunta di questo nuovo mazzo. Tale notifica può essere aggiunta se la mancanza di questa funzione causa sufficiente angoscia / difficoltà.
  • C'è un buy-in di 10 per round e le carte sono gratuite
  • La mano perfetta / ideale ha un punteggio di 21
  • Tutte le figure hanno un valore di 10
  • Tutte le carte numeriche valgono il loro numero
  • Gli assi valgono 11 o 1. questo sarà gestito automaticamente dal framework, non dai robot.
  • Secondo le regole , tutte le carte dei giocatori vengono distribuite scoperte e sono visibili. Una delle carte del banco è coperta e l'altra è scoperta.

punteggio

  • I punteggi superiori a 21 che usano un asso come 11 costringono l'asso a ridursi in valore a 1
  • punteggi superiori a 21 che non possono essere forzati al di sotto della soglia di 21 "rompono" il bot

Il commerciante

  • Il mazziere pareggia fino a quando non busta, o esclude un punteggio di 17 a quel punto è costretto a stare in piedi

Scommesse e patatine

  • All'inizio di ogni round, viene addebitato un buy-in di 10, quindi c'è una puntata minima di 10 e una puntata minima di 1. NOTA : la scommessa è il valore assoluto dell'argomento della scommessa, quindi non preoccuparti provare scommesse negative.
  • I robot che non possono permettersi il buy-in vengono rimossi dal concorso
  • Quando effettuano scommesse, i robot non possono scommettere più delle chip che hanno
  • Se la scommessa è possibile, la scommessa con chip viene rimossa dal bot e aggiunta alla puntata
  • La vincita di una scommessa dà al bot una scommessa con 2 chips. Tuttavia, poiché la scommessa viene sottratta dalle fiche del bot, il bot si rompe e quindi vince 1 volta la puntata.
  • I robot vincono le scommesse solo se il loro punteggio è superiore a quello del banco

Ripartizione del gioco

Una mano

  1. All'inizio del gioco, a ogni giocatore viene distribuita in modo iterativo una carta e viene sottratta la commissione di buy-in di $ 10 / puntata minima.
  2. Il mazziere disegna
  3. Viene effettuato un secondo passaggio e un'altra carta viene distribuita a tutti i giocatori.
  4. Il mazziere disegna
  5. Quindi (nello stesso ordine in cui sono stati gestiti) ogni bot viene eseguito come descritto nella sezione "Interfaccia del programmatore" e deve fare una mossa o rimanere in piedi. Le scommesse sono considerate una mossa. Si noti che le scommesse non influiscono sull'abilità dei robot di compiere ulteriori mosse. È molto possibile scommettere e quindi pescare una carta, ed è possibile pescare più carte e puntare prima di rimanere in piedi.
  6. Quando tutti i robot sono stati eliminati o in piedi, il banco gioca alla sua soglia di 17
  7. I punteggi dei robot vengono quindi confrontati con quelli del banco, le scommesse vengono vinte e perse

Un round

È considerato costituire cinque (5) mani. Tra le mani, l'elenco dei concorrenti viene ordinato per rimuovere i giocatori e quindi ulteriormente elaborato per garantire che tutti i robot giochino lo stesso numero di mani (una disposizione per il fatto che il numero di voci non si dividerà uniformemente tra i tavoli a quattro bot ).

Interfaccia del programmatore e mosse legali

Come documentato nel file 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.

Come (ora) documentato nel file 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":   '#'

Il codice sorgente per il sistema di punteggio è QUI

Bot di esempio

Lim 17

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

Lingue di ingresso

Attualmente sono supportati Java, c / c ++, Python e Lisp. Verrà compiuto uno sforzo ragionevole per includere gli invii in altre lingue, ma ricorda che il concorso finale verrà eseguito su un box Linux.

Selezione del vincitore

Il vincitore sarebbe l'autore del bot che ha costantemente accumulato il maggior numero di fiches su un numero di tavoli e round ancora da determinare. Il vincitore sarà annunciato il 3 giugno, ma l'annuncio potrebbe essere ritardato se ci sono ancora invii in arrivo. Concorso esteso a tempo indeterminato.


Domanda: le carte visibili includono quelle nella mano dei giocatori?
dmckee --- ex gattino moderatore

Seconda domanda: sappiamo quante carte sono state distribuite che non possiamo vedere?
dmckee --- ex gattino moderatore

Risposta a n. 1 - sì; Rispondi a # 2 - il modo in cui questo motore è implementato, non ci sono carte nascoste. carte visibile è ogni carta che è stata distribuita da ogni scarpa consumata durante il round corrente. i ritorni delle carte visibili non vengono cancellati con le nuove scarpe (perché parte della vecchia scarpa è probabilmente ancora in gioco) ma vengono invece cancellati al termine del round. Questa è una scelta di architettura che ho fatto per semplicità, che può essere rivista se trovi problematica la mancanza di carte nascoste.
arrdem,

Aggiornamento: controlla il link delle regole. Il motore ora implementa le carte nascoste, ma al momento l'unica carta nascosta è una delle carte base del banco.
Arrdem,

Come possono i robot distinguere quale carta visibile sono i mazzieri?
cthom06,

Risposte:


3

BlackJackDavey

Noioso, vecchio stile c. Dovrebbe compilatore sotto ANSI o 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;
}

La strategia qui è documentata nei commenti, ma è molto diretta. Le scommesse aggiuntive vengono fatte solo in due casi (puntata insufficiente per il turno successivo o raddoppio), e potrebbe essere necessario cambiare.

Il gioco differisce in parte dalle guide offerte ai giocatori d'azzardo per il fatto che non ci sono informazioni specifiche sulla carta che mostra il mazziere (o possiamo considerarla come l'ultima entrata in visible?), Quindi alcuni dei numeri magici sono ipotesi.

Potrebbe essere necessaria una modesta manipolazione a seconda della risposta a due domande nei commenti.

Nome dal gioco, il mio nome e la vecchia ballata popolare .


Le dieci carte sono rappresentate dal carattere T. Aggiornerà il post del concorso con l'elenco.
arrdem,

3

Scommessa lineare

#!/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"

Questo bot è una modifica della strategia 17. Questo bot pesca fino a quando non supera un punteggio di 15 (f) e poi scommette int (c * (score / 21)) chips. In questo modo il bot scommetterà in modo aggressivo ove possibile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.