Euchre botları (kart oyunu)


10

Bu meydan okuma fikri basittir: Euchre kart oyunu oynamak için bir bot oluşturun.

Onları henüz bilmeyenler için, bu meydan okuma ile ilgili oldukları için burada Euchre kurallarını yazdım .

Python veya benzeri bir şey kullanmanızı öneririm, ancak tek gerçek kısıtlama, denetleyici koduyla uyumlu olması gerektiğidir

Giriş:

Euchre botunuz, oyunun veya turun mevcut aşamasına bağlı olarak farklı giriş türleri alacaktır. Genel olarak, ilk aşamada oyun aşamasını, ardından virgül ve takımınızın sahip olduğu puan sayısını ve ardından aşağıdaki satırlardaki ilgili verileri alırsınız.

Kronolojik olarak, botunuz aşağıdaki sırayla girdi alır:

Ordering Trump:
    js,ah,qc,ts,jc  // the cards in your hand
    2               // number of points your team has
    0               // number of tricks your team has taken
    ordering        // the phase of the game
    th              // the turned up card
    p,p             // each previous player’s decision

Naming Trump:
    js,ah,qc,ts,jc  // the cards in your hand
    2               // number of points your team has
    0               // number of tricks your team has taken
    naming          // the phase of the game
    p               // each previous player’s decision

Dealer Discarding:
    js,ah,qc,ts,jc  // the cards in your hand
    2               // number of points your team has
    0               // number of tricks your team has taken
    discard         // the phase of the game
    th              // the card you will pick up

Going alone:
    js,ah,qc,ts,jc  // the cards in your hand
    2               // number of points your team has
    0               // number of tricks your team has taken
    alone           // the phase of the game
    h               // the trump suit
    n,n             // each previous player’s decision

Your turn:
    js,ah,qc,ts,jc  // the cards in your hand
    2               // number of points your team has
    0               // number of tricks your team has taken
    turn            // the phase of the game
    h               // the trump suit
    td,8h,p         // each previous player’s card

Trick data:
                    // the cards in your hand (none, since this happens at the end of a trick)
    2               // number of points your team has
    1               // number of tricks your team has taken
    trick           // the phase of the game
    0               // the index of the following list that is your card
    js,tc,4d,js     // the cards played during the trick in the order they were played

Çıktı:

Euchre botunuz, oyunun veya turun mevcut aşamasına bağlı olarak farklı çıkışlara sahip olacaktır.

Ordering Trump:
    p   //for pass
    OR
    o   //for order up

Naming Trump:
    p           //for pass
    OR ANY OF
    c,s,h,d     //the suit you want to name

Going alone:
    n   // no
    OR
    y   // yes

Your turn:
    js  //the card you want to play

puanlama:

Botunuzun puanı kazandığı toplam oyun sayısıdır.

Botunuz diğer botlara karşı oynayacak ve her zaman kendi kopyasıyla ortak olacaktır.

Notlar:

İşte python2.7'de basit bir şablon:

#!/usr/bin/python2.7
import sys

data = sys.stdin.readlines()

hand = data[0].strip().split(',')   # Hand as a list of strings
points = int(data[1])       # Number of points
tricks = int(data[2])       # Number of tricks

out = ''

if data[3] == 'ordering':
    card = data[4]              # The upturn card
    prev = data[5].strip().split(',')   # The previous player's decisions as a list
    # Ordering logic
    out =       # 'o' or 'p'
elif data[3] == 'naming':
    prev = data[4].strip().split(',')   # The previous player's decisions as a list
    # Naming logic
    out =       # 'p', 'h', 's', 'c', or 'd'
elif data[3] == 'discard':
    card = data[4]              # The card you'll take
    # Discarding logic
    out =       # The card you want to discard
elif data[3] == 'alone':
    trump = data[4]             # The trump suit
    prev = data[5].strip().split(',')   # The previous player's decisions as a list
    # Alone logic
    out =       # 'y' for yes, 'n' for no
elif data[3] == 'turn':
    trump = data[4]             # The trump suit
    prev = data[5].strip().split(',')
    # Turn logic
    out =       # The card you want to play
elif data[3] == 'trick':
    trump = data[5]
    cards = data[6].strip().split(',')
    my_card = cards[int(data[4])]
    # Data logic

print(out)
  1. Her zaman toplam 4 yanıt olacaktır. Birisi yalnız giderse, eşinin yanıtı "p" olur.

  2. Fazladan net olmak için gereksiz girdi miktarını azaltmaya çalıştım:

    2a. Hem krupiyeye / lidere göre pozisyonunuz hem de partnerinizin oynadığı kart önceki çıktıların sayısına göre belirlenebilir. Eşinizle aranızda 1 oyuncu var. Orada Örneğin, sıranızda son satır olarak "td, 8h, p" alırsanız, eşinizin 8 saat oynadığını ve diğer takımın yalnız giden bir oyuncusu olduğunu görebilirsiniz.

  3. Merak ediyorsanız, anlaşma geleneksel bir şekilde yapılır (2 turda 2 ve 3 kartlık alternatif paketler halinde), ancak bu botunuzla gerçekten ilgili değil, bu yüzden ...

  4. İkinci oyuncu koz aşamasında sipariş vermeye karar verirse, bu aşama devam eder, ancak çıkışları hemen hemen göz ardı edilir. Başka bir deyişle, ilk sipariş veren her kim olursa olsun Namers ekibindedir.

  5. Çeşitli oyun aşamaları için varsayılanlar aşağıdadır. Bu tur için geçerli bir yanıt vermezseniz, yanıtınız aşağıda verilenle değiştirilir.

    Sipariş Trump: p

    Adlandırma Trump: p

    Atma: (elinizdeki ilk kart)

    Yalnız Olmak: n

    Sıranız: (elinizdeki ilk yasal kart)

  6. İşte test amaçlı kontrolör kodu.

    6a. Dikkat edin 2 veya 4 bot isimlerini geçebilirsiniz, eğer 4 bot verirseniz, rastgele bir şekilde ortak olurlar ve 2 ile kendilerinin kopyaları ile ortak olurlar.

    6b. Denetleyici koduyla aynı dizinde bir 'botlar' dizinine ihtiyacınız var ve bot kodunuzun botlar dizininde olması gerekir.

  7. Botlarının hangi kartların oynandığını hatırlamasını isteyenler için, "hile" aşamasında size hangi kartların oynandığını söyleyen fırsat verilir. Bu dosya 1 kb'yi aşmadığı sürece bot dizinindeki bir dosyaya yazabilirsiniz.

scoreboard:

Old Stager:  2
Marius:      1
Random 8020: 0

2
İnsanların botlarını yazmasını kolaylaştırmak için örnek botlar eklemenizi tavsiye ederim.
Nathan Merrill

3
Gönderi olarak gönderin. Ancak, bu rastgele botla ilgili sorun, verdiğiniz girişin çoğunu yok saymasıdır. İnsanlar kodu kopyalamayı / yapıştırmayı (daha sonra değiştirmeyi) severler, bu nedenle ilk botlarınız ne kadar kapsamlı olursa, o kadar çok başvuru (ve daha iyi başvuru) alırsınız.
Nathan Merrill

1
Bot dönüşün son oyuncusu değilse, son sırada ne oynandığını bilmenin bir yolu olmadığını varsayabilir miyim?
plannapus

1
@ Mevcut dönüş sırasında neyin oynandığını bilmenin bir yolu olsaydı, bot takip etmek için bir dosyaya yazabilirdi.
plannapus

1
@NotthatCharles Açıkça bir dosyaya yazılmasına izin vermek için kuralları güncelledim
The Beanstalk

Yanıtlar:


2

Marius

R'de botu yazdım, kontrol cihazınızla bazı testler yaptım ve doğru iletişim kuruyor gibi görünüyorlar.

#!/usr/bin/Rscript
options(warn=-1)
infile = file("stdin")
open(infile)
input = readLines(infile,5)
hand = strsplit(input[1],",")[[1]]
phase = input[4]
if(!phase%in%c("discard","naming")) input = c(input,readLines(infile,1))
other_o = c("a","k","q","j","t","9")
alone = "n"
ord = "p"
trumpify = function(color){
    tr_suit = switch(color,
            "c" = c("c","s",rep("c",5)),
            "s" = c("s","c",rep("s",5)),
            "h" = c("h","d",rep("h",5)),
            "d" = c("d","h",rep("d",5)))
    paste(c("j","j","a","k","q","t","9"),tr_suit,sep="")
    }

if(phase%in%c("ordering","alone")){
    flip = input[5]
    if(phase=="ordering") trump = trumpify(substr(flip,2,2))
    if(phase=="alone") trump = trumpify(flip)
    hand_value = sum((7:1)[trump%in%c(hand,flip)])
    if(hand_value>13) ord = "o"
    if(hand_value>18) alone = "y"
    if(phase=="alone") cat(alone)
    if(phase=="ordering") cat(ord)
    }

if(phase=="naming"){
    name = "p"
    colors = unique(substr(hand,2,2))
    col_values = sapply(colors,function(x)sum((7:1)[trumpify(x)%in%hand]))
    if(any(col_values>13)){name = colors[which.max(col_values)]}
    cat(name)
    }

if(phase=="discard"){
    flip = input[5]
    new_hand = c(hand,flip)
    trump = trumpify(substr(flip,2,2))
    discardables = new_hand[!new_hand%in%trump]
    if(length(discardables)){
        val = sapply(substr(discardables,1,1),function(x)(6:1)[other_o==x])
        d = discardables[which.min(val)]
    }else{d = tail(trump[trump%in%new_hand],1)}
    cat(d)
    }

if(phase=="turn"){
    trump = trumpify(input[5])
    fold = strsplit(gsub("[[:punct:]]","",input[6]),",")[[1]]
    if(length(fold)&!any(is.na(fold))){
        fold_c = substr(fold[1],2,2)
        f_suit = if(fold_c!=input[5]){paste(other_o,fold_c,sep="")}else{trump}
        l = length(f_suit)
        current = (l:1)[f_suit%in%fold]
        if(any(hand%in%f_suit)){
            playable = hand[hand%in%f_suit]
            val = sapply(playable,function(x)(l:1)[f_suit==x])
            if(all(max(val)>current)){
                play = playable[which.max(val)]
            }else{play = playable[which.min(val)]}
        }else if(any(hand%in%trump)){
            playable = hand[hand%in%trump]
            val = sapply(playable,function(x)(7:1)[trump==x])
            if(!any(fold%in%trump)){
                play = playable[which.min(val)]
            }else{
                trumped = fold[fold%in%trump]
                val_o = max((7:1)[trump%in%trumped])
                play = ifelse(any(val>val_o), playable[which.min(val[val>val_o])], playable[which.min(val)])
            }
        }else{
            val = sapply(substr(hand,1,1),function(x)(6:1)[other_o==x])
            play = hand[which.min(val)]
            }
    }else{
        col = c("c","s","h","d")
        non_tr = col[col!=input[5]]
        aces = paste("a",non_tr,sep="")
        if(any(hand%in%aces)){
            play = hand[hand%in%aces][1]
        }else if(any(hand%in%trump)){
            playable = hand[hand%in%trump]
            val = sapply(playable,function(x)(7:1)[trump==x])
            play = playable[which.max(val)]
        }else{
            val = sapply(substr(hand,1,1),function(x)(6:1)[other_o==x])
            play = hand[which.max(val)]
        }
    }
    cat(play)   
}

Botun savunması için bir "dönüş" mantığı uygulamadığım için muhtemelen daha sonra değiştireceğim, ancak şimdi test ediyorum ki insanların test etmek için başka bir botu var.

Şimdilik, sadece bir as, koz veya diğer yüksek kartlarla liderlik etmek gibi çok temel stratejileri uyguluyor; mümkünse daha yüksek bir kart ile takip etmek veya değilse en düşük değerli kartı oynamak; elin değeri yüksek olduğunda sipariş verme ve elin en yüksek değere sahip olduğu rengin adlandırılması; el değeri çok yüksek olduğunda yalnız kalmak. Her kartın "değeri" çok basit bir şekilde hesaplanır: koz değeri ilk jak için 7'den başlar ve koz boyunca azalır.


1

Old Stager

Bu bot, ona uzun süre iyi hizmet eden bazı basit kurallara uyar:

  • Her karta sezgisel olarak bir puan atayın
  • El skoru yeterince iyi ise kozu seçin
  • Gerçekten iyi bir el durumunda tek başına oynamak
  • İlk oynarken en iyi kartı seçin
  • Kazanıyorlarsa rakiplerinden daha iyi bir kart seçin
  • Ortak kazanıyorsa veya kazanmak mümkün değilse en kötü kartı seçin

Kontrol cihazında test için hedef puanı 10'dan 100'e çıkardım. Sonuçlar hala çok rastgele, ama öncekinden çok daha kararlı.

#!/usr/bin/python2.7
from __future__ import print_function
import sys, re, math

base = 1.2
playThreshold = 27.0
aloneThreshold = 36.0
sameColor = { 'd' : 'h', 'h' : 'd', 's' : 'c', 'c' : 's' , '' : '', 'n' : 'n' }
cardValue = { 'p' : 0, '9' : 1, 't' : 2, 'j' : 3, 'q' : 4, 'k' : 5, 'a' : 6 }

class Card(object):
    def __init__(self, name, trump):
        self.name = name
        self.value = cardValue[name[0:1]]
        self.suit = name[1:2]
        self.trump = False
        self.updateScore(trump)
    def updateScore(self, trump):
        self.score = self.value
        if self.suit == trump:
            self.trump = True
            self.score += 6
        if self.value == 3:
            if self.suit == trump:
                self.score = 14
            if self.suit == sameColor[trump]:
                self.trump = True
                self.score = 13

class Cards(object):
    def __init__(self, cards, trump):
        self.list = []
        self.score = 0.0
        if cards:
            for c in cards.split(','):
                self.append(Card(c, trump))
    def append(self, card):
        self.list.append(card)
        self.score += math.pow(base, card.score)
    def updateScore(self, trump):
        self.score = 0.0
        for card in self.list:
            card.updateScore(trump)
            self.score += math.pow(base, card.score)
    def best(self):
        card = self.list[0]
        for i in self.list[1:]:
            if i.score > card.score:
                card = i
        return card
    def worst(self):
        card = self.list[0]
        for i in self.list[1:]:
            if i.score < card.score:
                card = i
        return card
    def better(self, ref):
        card = None
        for i in self.list:
            if i.score > ref.score and (card is None or i.score < card.score):
                card = i
        return card

def ordering(hand, card, decisions):
    if len(decisions) == 3:
        hand.append(card)
    return 'o' if hand.score > playThreshold else 'p'

def naming(hand):
    result = 'p'
    score = playThreshold
    for trump in ['d', 'h', 's', 'c']:
        hand.updateScore(trump)
        if hand.score > score:
            result = trump
            score = hand.score
    return result

def turn(hand, decisions):
    bestIndex = -1
    for i, d in enumerate(decisions.list):
        if d.suit:
            bestIndex = i
            break
    if bestIndex == -1:
        return hand.best()
    else:
        suit = decisions.list[bestIndex].suit
        for i in range(2, len(decisions.list)):
            if (decisions.list[i].suit == suit or decisions.list[i].trump) and decisions.list[i].score > decisions.list[bestIndex].score:
                bestIndex = i
        matching = Cards('', '')
        for card in hand.list:
            if card.suit == suit:
                matching.append(card)
        if not matching.list:
            if bestIndex == len(decisions.list) - 2:
                return hand.worst()
            for card in hand.list:
                if card.trump:
                    matching.append(card)
            if not matching.list:
                return hand.worst()
        if bestIndex == len(decisions.list) - 2:
            return matching.worst()
        card = matching.better(decisions.list[bestIndex])
        if card:
            return card
        return matching.worst()

output = ''
input = re.split('\n', re.sub(r'[^a-z0-9,\n]+', '', sys.stdin.read()))

if input[3] == 'ordering':
    output = ordering(Cards(input[0], input[4][1:2]), Card(input[4], input[4][1:2]), input[5].split(','))
elif input[3] == 'naming':
    output = naming(Cards(input[0], 'n'))
elif input[3] == 'discard':
    output = Cards(input[0], input[4][1:2]).worst().name
elif input[3] == 'alone':
    output = 'y' if Cards(input[0], input[4]).score > aloneThreshold else 'n'
elif input[3] == 'turn':
    output = turn(Cards(input[0], input[4]), Cards(input[5], input[4])).name

print(output)

0

Rasgele 8020

Zamanın% 80'ini geçecek basit bir rastgele bot. (Silindi) giriş ve çıkışını görmek için son satırın açıklamasını kaldırın.

#!/usr/bin/python2.7
from __future__ import print_function
import sys, re, random

output = ''
input = re.split('\n', re.sub(r'[^a-z0-9,\n]+', '', sys.stdin.read()))
hand = input[0].split(',')

if input[3] == 'ordering':
    output = random.choice(['p', 'p', 'p', 'p', 'o'])
elif input[3] == 'naming':
    output = random.choice(['p', 'p', 'p', 'p', random.choice(hand)[1:2]])
elif input[3] == 'discard':
    output = random.choice(hand)
elif input[3] == 'alone':
    output = random.choice(['n', 'n', 'n', 'n', 'y'])
elif input[3] == 'turn':
    output =  random.choice(hand)
    if input[5]:
        suited = filter(lambda x: input[5][1:2] in x, hand)
        if suited:
            output = random.choice(suited)

print(output)
#print(input, " --> ", output, file=sys.stderr)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.