Bot Euchre (trò chơi bài)


10

Ý tưởng của thử thách này rất đơn giản: tạo một bot để chơi trò chơi bài Euchre.

Đối với những người bạn chưa biết về họ, tôi đã viết ra các quy tắc cho Euchre ở đây khi họ liên quan đến thử thách này.

Tôi khuyên bạn nên sử dụng python hoặc một cái gì đó tương tự, nhưng hạn chế thực sự duy nhất là nó phải tương thích với mã điều khiển

Đầu vào:

Bot euchre của bạn sẽ nhận được các loại đầu vào khác nhau tùy thuộc vào giai đoạn hiện tại của trò chơi hoặc vòng. Nói chung, bạn sẽ có được giai đoạn trò chơi trên dòng đầu tiên theo sau là dấu phẩy và số điểm mà nhóm của bạn có, và sau đó là dữ liệu có liên quan trên các dòng sau.

Theo thời gian, bot của bạn sẽ nhận được đầu vào theo thứ tự sau:

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

Đầu ra:

Bot euchre của bạn sẽ có đầu ra khác nhau tùy thuộc vào giai đoạn hiện tại của trò chơi hoặc vòng.

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

Ghi điểm:

Điểm số bot của bạn là tổng số trò chơi mà nó thắng.

Bot của bạn sẽ chơi với mọi bot khác và nó sẽ luôn được hợp tác với một bản sao của chính nó.

Ghi chú:

Đây là một mẫu đơn giản trong python2.7:

#!/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. Sẽ luôn có 4 câu trả lời. Nếu ai đó đi một mình, thì phản ứng của đối tác của họ sẽ là "p" trong lượt của họ.

  2. Tôi đã cố gắng giảm số lượng đầu vào dư thừa, để rõ ràng hơn:

    2a. Cả vị trí của bạn so với đại lý / lãnh đạo và thẻ mà đối tác của bạn đã chơi có thể được xác định bằng số lượng đầu ra trước đó. Có 1 người chơi giữa bạn và đối tác của bạn. Ở đó, ví dụ, nếu bạn nhận được "td, 8h, p" là dòng cuối cùng trong lượt của mình, bạn có thể thấy đối tác của mình đã chơi 8h và đội khác có một người chơi đang đi một mình.

  3. Nếu bạn tò mò, thỏa thuận được thực hiện theo cách truyền thống (trong hai vòng xen kẽ các gói 2 và 3 thẻ) nhưng điều đó không thực sự phù hợp với bot của bạn, vì vậy ...

  4. Nếu người chơi thứ hai quyết định đặt hàng trong giai đoạn át chủ bài, giai đoạn đó sẽ tiếp tục, nhưng kết quả đầu ra của họ sẽ bị bỏ qua khá nhiều. Nói cách khác, bất cứ ai đặt hàng trước đều thuộc nhóm Namers bất kể đầu ra nào khác.

  5. Sau đây là các mặc định cho các giai đoạn trò chơi khác nhau. Nếu bạn không đưa ra phản hồi hợp lệ cho vòng đó, thì phản hồi của bạn sẽ được thay đổi thành những gì bên dưới.

    Đặt hàng Trump: p

    Đặt tên Trump: p

    Loại bỏ: (thẻ đầu tiên trong tay của bạn)

    Đi một mình: n

    Lượt của bạn: (thẻ hợp pháp đầu tiên trong tay bạn)

  6. Đây là mã điều khiển cho mục đích thử nghiệm của bạn.

    6a. Lưu ý rằng bạn có thể chuyển vào 2 hoặc 4 tên bot, nếu bạn cho nó 4 bot thì chúng sẽ được hợp tác ngẫu nhiên và với 2 chúng được hợp tác với các bản sao của chính chúng.

    6b. Bạn cần một thư mục 'bot' trong cùng thư mục với mã điều khiển và mã bot của bạn cần nằm trong thư mục bot.

  7. Đối với những người muốn bot của họ nhớ những thẻ đã được chơi, bạn sẽ có cơ hội trong giai đoạn "lừa", thông báo cho bot của bạn biết những thẻ nào đã được chơi. Bạn có thể ghi vào một tệp trong thư mục bot miễn là tệp đó không vượt quá 1kb.

Bảng điểm:

Old Stager:  2
Marius:      1
Random 8020: 0

2
Tôi khuyên bạn nên bao gồm các bot mẫu để giúp mọi người viết bot dễ dàng hơn.
Nathan Merrill

3
Gửi nó như là một đệ trình. Tuy nhiên, vấn đề với bot ngẫu nhiên đó là nó bỏ qua phần lớn đầu vào mà bạn đang cung cấp cho nó. Mọi người thích sao chép / dán (sau đó sửa đổi) mã, vì vậy các bot ban đầu của bạn càng toàn diện, bạn càng nhận được nhiều bài nộp (và bài nộp tốt hơn).
Nathan Merrill

1
Tôi có đúng không khi cho rằng trừ khi bot là người chơi cuối cùng của lượt chơi, nó không có cách nào để biết những gì đã được chơi trong lượt cuối cùng?
plannapus

1
@Sleafar tốt nếu có một cách để biết những gì đã được chơi trong lượt hiện tại, bot có thể ghi nó vào một tệp, để theo dõi.
plannapus 04/12/2015

1
@NotthatCharles Tôi đã cập nhật các quy tắc để cho phép ghi rõ ràng vào một tệp
Beanstalk

Câu trả lời:


2

Marius

Tôi đã viết bot đó trong R. Tôi đã thực hiện một số thử nghiệm với bộ điều khiển của bạn và chúng dường như giao tiếp chính xác.

#!/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)   
}

Có lẽ tôi sẽ sửa đổi nó sau này vì tôi đã không thực hiện logic "bật" khi bot đang bảo vệ, nhưng tôi sẽ đăng nó ngay bây giờ để mọi người có một bot khác để kiểm tra.

Hiện tại, nó chỉ thực hiện các chiến lược rất cơ bản như dẫn đầu với ace, át chủ bài hoặc bất kỳ thẻ cao cấp nào khác; theo sau với thẻ cao hơn khi có thể hoặc chơi thẻ có giá trị thấp nhất nếu không; đặt hàng khi bàn tay có giá trị cao và đặt tên màu trong đó bàn tay sẽ có giá trị cao nhất; đi một mình khi tay có giá trị rất cao. "Giá trị" của mỗi thẻ được tính toán rất đơn giản: giá trị của các lần bắt đầu từ 7 cho jack đầu tiên và giảm dọc theo bộ đồ chơi bài.


1

Stager cũ

Bot này tuân theo một số quy tắc đơn giản phục vụ tốt cho anh ta trong một thời gian dài:

  • Trực giác chỉ định một số điểm cho mỗi thẻ
  • Chọn át chủ bài nếu điểm số tay đủ tốt
  • Trong trường hợp chơi một tay thực sự tốt một mình
  • Chọn thẻ tốt nhất khi chơi trước
  • Chọn một thẻ tốt hơn so với đối thủ nếu họ đang chiến thắng
  • Chọn thẻ tệ nhất nếu đối tác chiến thắng hoặc nếu không thể chiến thắng

Tôi đã tăng điểm mục tiêu từ 10 lên 100 để thử nghiệm trong bộ điều khiển. Kết quả vẫn rất ngẫu nhiên, nhưng cách ổn định hơn trước.

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

Ngẫu nhiên 8020

Một bot ngẫu nhiên đơn giản, sẽ vượt qua 80% thời gian. Bỏ ghi chú dòng cuối cùng để xem đầu vào và đầu ra (đã xóa).

#!/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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.