ไพ่ยูเครอ (เกมไพ่)


10

แนวคิดของความท้าทายนี้ง่ายมาก: สร้างบอทเพื่อเล่นการ์ดเกมไพ่ยูเครอ

สำหรับบรรดาของคุณที่ยังไม่รู้จักพวกเขาฉันได้เขียนกฎให้กับ Euchre ที่นี่เนื่องจากพวกเขาเกี่ยวข้องกับความท้าทายนี้

ฉันแนะนำให้ใช้ python หรือบางอย่างที่คล้ายกัน แต่ข้อ จำกัด จริง ๆ เท่านั้นคือมันต้องเข้ากันได้กับโค้ดคอนโทรลเลอร์

การป้อนข้อมูล:

บอทยูแคร์ของคุณจะได้รับการป้อนข้อมูลที่แตกต่างกันขึ้นอยู่กับเฟสปัจจุบันของเกมหรือรอบ โดยทั่วไปแล้วคุณจะได้รับช่วงของเกมในบรรทัดแรกตามด้วยเครื่องหมายจุลภาคและจำนวนคะแนนที่ทีมของคุณมีแล้วข้อมูลที่เกี่ยวข้องในบรรทัดต่อไปนี้

ตามลำดับบอทของคุณจะได้รับการป้อนข้อมูลตามลำดับต่อไปนี้:

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

เอาท์พุท:

บอทไพ่ยูเครอของคุณจะมีเอาท์พุตต่างกันขึ้นอยู่กับเฟสปัจจุบันของเกมหรือรอบ

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

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

คะแนนบอทของคุณคือจำนวนเกมทั้งหมดที่ชนะ

บอทของคุณจะเล่นกับบอทอื่น ๆ และมันจะถูกจับคู่กับสำเนาของตัวเองเสมอ

หมายเหตุ:

นี่คือเทมเพลตง่ายๆใน 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. จะมีคำตอบทั้งหมด 4 คำตอบเสมอ หากมีคนไปคนเดียวการตอบสนองของพันธมิตรจะเป็น "p" เมื่อถึงคราว

  2. ฉันพยายามลดปริมาณการป้อนข้อมูลซ้ำซ้อนเพื่อให้ชัดเจนยิ่งขึ้น:

    2a ทั้งตำแหน่งของคุณที่สัมพันธ์กับดีลเลอร์ / ผู้นำและการ์ดที่คู่ของคุณเล่นสามารถกำหนดได้จากจำนวนเอาท์พุทก่อนหน้า มีผู้เล่น 1 คนระหว่างคุณกับคู่ของคุณ ตัวอย่างเช่นหากคุณได้รับ "td, 8h, p" เป็นบรรทัดสุดท้ายในตาคุณคุณจะเห็นว่าคู่ของคุณเล่นเป็นเวลา 8 ชั่วโมงและทีมอื่นมีผู้เล่นคนเดียว

  3. หากคุณอยากรู้อยากเห็นการจัดการจะทำในลักษณะดั้งเดิม (ในสองรอบสลับแพ็คเก็ตของ 2 และ 3 ใบ) แต่นั่นไม่เกี่ยวข้องกับบอทของคุณดังนั้น ...

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

  5. ต่อไปนี้เป็นค่าเริ่มต้นสำหรับเฟสเกมต่างๆ หากคุณไม่ส่งออกการตอบสนองที่ถูกต้องสำหรับรอบนั้นการตอบสนองของคุณจะถูกเปลี่ยนเป็นสิ่งที่ด้านล่าง

    การสั่งซื้อทรัมป์: p

    การตั้งชื่อทรัมป์: p

    การทิ้ง: (ไพ่ใบแรกในมือของคุณ)

    ไปคนเดียว: n

    Your Turn: (การ์ดใบแรกในมือของคุณ)

  6. นี่คือรหัสคอนโทรลเลอร์สำหรับจุดประสงค์ในการทดสอบของคุณ

    6a โปรดสังเกตว่าคุณสามารถส่งชื่อบอท 2 หรือ 4 ชื่อหากคุณให้บอท 4 บอทพวกเขาจะได้รับการสุ่มและ 2 คนจะได้รับสำเนาของตัวเอง

    6b คุณต้องการไดเรกทอรี 'bots' ในไดเรกทอรีเดียวกันกับรหัสควบคุมและรหัส bot ของคุณต้องอยู่ในไดเรกทอรี bots

  7. สำหรับผู้ที่ต้องการบอทของพวกเขาที่จะจำสิ่งที่เล่นไพ่คุณจะได้รับโอกาสในช่วง "เคล็ดลับ" ซึ่งบอกบอทของคุณที่เล่นไพ่ คุณสามารถเขียนไปยังไฟล์ในไดเรกทอรีบอทตราบเท่าที่ไฟล์นั้นไม่เกิน 1kb

สกอร์:

Old Stager:  2
Marius:      1
Random 8020: 0

2
ฉันขอแนะนำให้รวมบอตตัวอย่างเพื่อให้คนเขียนบอตง่ายขึ้น
Nathan Merrill

3
โพสต์มันเป็นความคิดเห็น อย่างไรก็ตามปัญหาของบอทแบบสุ่มนั้นคือมันไม่สนใจอินพุตส่วนใหญ่ที่คุณให้ ผู้คนชอบที่จะคัดลอก / วาง (จากนั้นแก้ไข) โค้ดดังนั้นยิ่งบอตเริ่มต้นของคุณครอบคลุมมากขึ้นเท่าใดคุณก็จะได้รับการส่งมากขึ้น (และการส่งที่ดีขึ้น)
Nathan Merrill

1
ฉันถูกต้องหรือไม่ที่จะสมมติว่าถ้าบอทเป็นผู้เล่นคนสุดท้ายของเทิร์นมันไม่มีทางรู้ได้เลยว่าเล่นในเทิร์นสุดท้ายหรือไม่?
plannapus

1
@Sleafar ดีหากมีวิธีการรู้ว่าสิ่งที่เล่นในช่วงเทิร์นปัจจุบันบอทสามารถเขียนลงในไฟล์เพื่อติดตาม
plannapus

1
@NotthatCharles ฉันได้อัปเดตกฎเพื่ออนุญาตการเขียนไฟล์อย่างชัดเจน
The Beanstalk

คำตอบ:


2

Marius

ฉันเขียนบอทในอาร์ฉันทำการทดสอบบางอย่างกับคอนโทรลเลอร์ของคุณและพวกมันดูเหมือนสื่อสารอย่างถูกต้อง

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

ฉันอาจจะแก้ไขในภายหลังเนื่องจากฉันไม่ได้ใช้ตรรกะ "เทิร์น" เมื่อบอตกำลังปกป้อง แต่ฉันโพสต์ไว้ในตอนนี้เพื่อให้ผู้คนมีบอตอื่นเพื่อทดสอบ

สำหรับตอนนี้มันใช้เพียงแค่กลยุทธ์ขั้นพื้นฐานมาก ๆ เช่นการเป็นผู้นำกับเอซทรัมป์หรือไพ่สูงอื่น ๆ ตามด้วยไพ่ใบที่สูงกว่าถ้าเป็นไปได้หรือเล่นไพ่ที่มีค่าต่ำสุดถ้าไม่ใช่ การเรียงลำดับเมื่อมือมีค่าสูงและตั้งชื่อสีที่มือจะมีมูลค่าสูงสุด ไปคนเดียวเมื่อมือมีมูลค่าสูงมาก "มูลค่า" ของการ์ดแต่ละใบมีการคำนวณอย่างง่าย ๆ : มูลค่าของการปั้นเริ่มจาก 7 สำหรับแจ็คแรกและลดลงตามชุดคนที่กล้าหาญ


1

Stager เก่า

บอทนี้ปฏิบัติตามกฎง่าย ๆ บางอย่างที่ให้บริการเขามาเป็นเวลานาน

  • ให้คะแนนกับการ์ดแต่ละใบโดยสังหรณ์ใจ
  • เลือกคนที่กล้าหาญถ้าคะแนนมือดีพอ
  • ในกรณีที่มือดีเล่นคนเดียว
  • เลือกไพ่ที่ดีที่สุดเมื่อเล่นครั้งแรก
  • เลือกไพ่ที่ดีกว่าของฝ่ายตรงข้ามหากพวกเขาชนะ
  • เลือกไพ่ที่แย่ที่สุดหากพันธมิตรชนะหรือไม่สามารถชนะได้

ฉันเพิ่มคะแนนเป้าหมายจาก 10 เป็น 100 สำหรับการทดสอบในคอนโทรลเลอร์ ผลลัพธ์ยังคงสุ่มมาก แต่วิธีนี้เสถียรกว่าเมื่อก่อน

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

สุ่ม 8020

บอทสุ่มง่าย ๆ ซึ่งจะผ่าน 80% ของเวลา ยกเลิกหมายเหตุบรรทัดสุดท้ายเพื่อดูอินพุต (และล้างข้อมูล)

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