Kontes BlackJack KOTH

13

Selikuran

Karena saya senang mengerjakan tantangan KOTH yang asli, saya ingin membuat yang lain. Bagi saya, kesenangan dari tantangan AI ini adalah dalam menyempurnakan bot yang relatif sederhana yang memainkan permainan yang sangat sederhana secara halus. Karena sifat probabilistik dari permainan kartu, saya pikir blackjack bisa menjadi permainan KOTH yang menarik seperti halnya TPD.

Semua aturan berasal dari deskripsi situs web BlackJack ini dengan sepatu

Aturan Mengenai Kartu & Dek

  • Bot bermain di meja empat (4) pesaing dan satu (1) dealer
  • Satu (1) sepatu (dek yang dikocok) dibagikan oleh semua pemain dan dealer sampai habis, pada titik mana dek acak yang baru dikocok akan ditambahkan dan permainan akan dilanjutkan. Bot TIDAK (saat ini) diberitahu tentang penambahan dek baru ini. Pemberitahuan tersebut dapat ditambahkan jika kekurangan fitur ini menyebabkan kesulitan / kesulitan yang cukup.
  • Ada pembelian 10 per putaran, dan kartu gratis
  • Tangan sempurna / ideal memiliki skor 21
  • Semua kartu wajah memiliki nilai 10
  • Semua kartu numerik bernilai angka mereka
  • Ace bernilai 11 atau 1. ini akan ditangani secara otomatis oleh kerangka kerja, bukan bot.
  • Sesuai aturan , semua kartu pemain dibagikan tertutup dan terlihat. Salah satu kartu dealer menghadap ke bawah dan yang lainnya menghadap ke atas.

Mencetak gol

  • Skor lebih dari 21 yang menggunakan kartu as sebagai 11 memaksa kartu as untuk mengurangi nilainya menjadi 1
  • skor lebih dari 21 yang tidak dapat dipaksa di bawah ambang 21 "menerobos" bot

Dealer

  • Dealer menarik sampai ia gagal, atau melebihi skor 17 pada titik mana ia dipaksa berdiri

Taruhan dan Keripik

  • Pada awal setiap putaran, pembelian dalam 10 dibebankan, sehingga ada taruhan minimum 10, dan taruhan minimum 1. CATATAN - taruhan adalah nilai absolut dari argumen taruhan, jadi jangan repot-repot mencoba taruhan negatif.
  • Bot yang tidak mampu membeli-beli dihapus dari kontes
  • Saat membuat taruhan, bot tidak dapat bertaruh lebih dari chip yang mereka miliki
  • Jika taruhan memungkinkan, taruhan chip dikeluarkan dari bot dan ditambahkan ke taruhan
  • Memenangkan taruhan memberikan taruhan keripik bot 2x. Namun karena taruhan dikurangi dari chip bot, bot tersebut impas dan kemudian memenangkan 1x taruhan.
  • Bot memenangkan taruhan hanya jika skor mereka lebih besar dari pada dealer

Kerusakan Gameplay

Satu tangan

  1. Ketika permainan dimulai, setiap pemain secara iteratif dibagikan satu kartu, dan memiliki $ 10 biaya pembelian / taruhan minimum dikurangi dari chip mereka.
  2. Dealer menarik
  3. Kartu pass kedua dibuat, dan kartu lain dibagikan kepada semua pemain.
  4. Dealer menarik
  5. Kemudian (dalam urutan yang sama ketika mereka dibagikan) setiap bot dieksekusi seperti yang dijelaskan di bagian "Antarmuka Programmer" dan harus bergerak atau berdiri. Taruhan dianggap sebagai langkah. CATATAN BETTING YANG TIDAK MEMPENGARUHI KEMAMPUAN BOTS UNTUK MEMBUAT MOVES LEBIH LANJUT. Sangat mungkin untuk bertaruh dan kemudian menggambar kartu, dan dimungkinkan untuk menggambar beberapa kartu dan mereka bertaruh sebelum berdiri.
  6. Ketika semua bot telah rusak atau berdiri, dealer bermain sampai ambang batas 17
  7. Skor dari bot kemudian dibandingkan dengan dealer, taruhan dimenangkan dan dikalahkan

Satu putaran

Dianggap merupakan lima (5) tangan. Di antara kedua tangan, daftar kontestan diurutkan untuk menghapus pemain dan kemudian diproses lebih lanjut untuk memastikan bahwa semua bot memainkan jumlah tangan yang sama (ketentuan untuk fakta bahwa jumlah entri tidak akan dibagi secara merata di antara tabel empat bot) ).

Antarmuka Programmer dan Gerakan Hukum

Seperti yang didokumentasikan dalam 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.

Seperti (sekarang) didokumentasikan dalam file Kartu:

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

Kode sumber untuk sistem penilaian ada di SINI

Contoh Bot

Lim 17

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

Bahasa Entri

Saat ini, Java, c / c ++, Python dan Lisp didukung. Upaya yang masuk akal akan dilakukan untuk memasukkan pengiriman dalam bahasa lain, tetapi ingat bahwa kontes terakhir akan dijalankan pada kotak Linux.

Pilihan Pemenang

Pemenangnya adalah penulis bot yang secara konsisten menghasilkan paling banyak chip pada jumlah tabel dan putaran yang belum ditentukan. Pemenang akan diumumkan pada tanggal 3 Juni, tetapi pengumuman tersebut dapat ditunda jika masih ada pengiriman yang masuk. Kontes diperpanjang tanpa batas.

arrdem
sumber
Pertanyaan: apakah kartu yang terlihat termasuk kartu yang ada di tangan pemain?
dmckee --- mantan moderator kucing
Pertanyaan kedua: apakah kita tahu sudah berapa banyak kartu yang tidak bisa kita lihat?
dmckee --- mantan moderator kucing
Jawaban untuk # 1 - ya; Jawaban ke # 2 - cara mesin ini diterapkan, tidak ada kartu tersembunyi. kartu terlihat adalah setiap kartu yang telah dibagikan dari setiap sepatu yang dikonsumsi selama putaran saat ini. pengembalian kartu yang terlihat dihapus bukan pada sepatu baru (karena bagian dari sepatu lama mungkin masih dalam permainan) tetapi malah dihapus pada pemutusan putaran. Ini adalah pilihan arsitektur yang saya buat untuk kesederhanaan, yang dapat direvisi jika Anda menemukan kurangnya kartu tersembunyi bermasalah.
arrdem
Perbarui: periksa tautan aturan. Mesin sekarang mengimplementasikan kartu tersembunyi, tetapi satu-satunya kartu tersembunyi saat ini adalah salah satu kartu dasar dealer.
arrdem
Bagaimana bot dapat membedakan kartu yang terlihat adalah dealer?
cthom06

Jawaban:

3

BlackJackDavey

Membosankan, kuno c. Haruskah kompiler di bawah ANSI atau 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;
}

Strategi di sini didokumentasikan dalam komentar, tetapi sangat lurus ke depan. Taruhan tambahan dibuat hanya dalam dua kasus (taruhan tidak cukup untuk putaran berikutnya, atau dobel turun), dan ini mungkin perlu diubah.

Permainan ini berbeda dari panduan yang ditawarkan untuk penjudi kasino karena tidak ada informasi spesifik tentang kartu yang menunjukkan dealer (atau bisakah kita bisa mengenai itu menjadi entri terakhir di visible ?), Sehingga beberapa angka ajaib adalah tebakan.

Mungkin perlu diddling sederhana tergantung pada jawaban untuk dua pertanyaan di komentar.

Nama dari permainan, nama depan saya, dan balada rakyat lama .

dmckee --- mantan kucing moderator
sumber
Sepuluh kartu diwakili oleh karakter T. Akan memperbarui pos kontes dengan daftar.
arrdem
3

Taruhan Linier

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

Bot ini merupakan modifikasi dari 17 strategi. Bot ini menarik hingga melebihi skor 15 (f) dan kemudian taruhan chip int (c * (skor / 21)). Dengan cara ini bot akan bertaruh secara agresif sedapat mungkin.

arrdem
sumber