कोथ - लोडेड आरपीएस


12

प्रतियोगिता स्थायी रूप से खोली गई - अद्यतन 10 अगस्त 2017

भले ही 5 जून 2017 को मैंने एक विजेता घोषित किया (जिसे सबसे अच्छे उत्तर के रूप में रखा जाएगा) मैं नए बॉट्स को फिर से जारी करूंगा और परिणामों को अपडेट करूंगा।

5 जून परिणाम

बधाई हो user1502040

चूंकि कोई संबंध नहीं है, मैं केवल जीते गए मैचों का% दिखाता हूं।

Statistician2- 95.7%
Fitter- 89.1%
Nash- 83.9%
Weigher- 79.9%
ExpectedBayes- 76.4%
AntiRepeater- 72.1%
Yggdrasil- 65.0%
AntiGreedy- 64.1%
Reactor- 59.9%
NotHungry- 57.3%
NashBot- 55.1%
Blodsocer- 48.6%
BestOfBothWorlds- 48.4%
GoodWinning- 43.9%
Rockstar- 40.5%
ArtsyChild- 38.4%
Assassin- 38.1 % %
WeightedRandom- 37.7%
Ensemble- 37.4%
UseOpponents- 36.4%
GreedyPsychologist- 36.3%
TheMessenger- 33.9%
Copycat- 31.4%
Greedy- 28.3%
SomewhatHungry- 27.6%
AntiAntiGreedy- 21.0%
Cycler- 20.3%
Swap- 19.8%
RandomBot- 16.2%

मैंने प्रत्येक युग्मन के परिणामों की ग्रिड के साथ एक Google शीट बनाई: https://docs.google.com/spreadsheets/d/1KrMvcvWMkK-h1Ee50w0gWLh_L6rCFOgOhhTN_QlEXHyk/edit?usp=sharing


पेट्री दुविधा के लिए धन्यवाद, मैंने खुद को इस पहाड़ी के राजा को संभालने में सक्षम पाया।

खेल

खेल एक मोड़ के साथ एक सरल "रॉक-पेपर-कैंची" है: मैच के दौरान प्रत्येक जीत वृद्धि के साथ प्राप्त अंक (आपके आर, पी या एस लोड हो जाते हैं)।

  • पेपर रॉक जीतता है
  • कैंची कागज जीतती है
  • रॉक ने कैंची जीती

विजेता को अपने खेल पर लोड के रूप में कई बिंदु मिलते हैं।

हारने वाले के खेलने पर भार में 1 की वृद्धि होती है।

एक टाई के मामले में, प्रत्येक खिलाड़ी अपने खेल पर भार को 0.5 से बढ़ाता है।

100 नाटकों के बाद, अधिक अंक के साथ विजेता है।

उदाहरण: P1 में भार है [10,11,12] (रॉक, पेपर, कैंची) और P2 [7,8,9]। पी 1 प्ले आर, पी 2 प्ले पी। पी 2 जीतता है और 8 अंक मिलते हैं। पी 1 लोड [11,11,12] हो जाता है, पी 2 लोड समान रहते हैं।

चुनौती विनिर्देशों

आपके कार्यक्रम को पायथन में लिखा जाना चाहिए (क्षमा करें, मुझे नहीं पता कि इसे अन्यथा कैसे संभालना है)। आपको एक ऐसा फंक्शन बनाना है जो प्रत्येक चर को प्रत्येक निष्पादन पर एक तर्क के रूप में ले:

my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history

points - वर्तमान बिंदु (आपका और आपका उत्पीड़न)

loaded- भार के साथ सरणी (क्रम में आरपीएस) (आपका और आपका उत्पीड़न)

history- सभी नाटकों के साथ स्ट्रिंग, अंतिम चरित्र अंतिम नाटक है (आपका और आपका जुल्म)

आप अवश्य लौटें "R", "P"या "S"। यदि आप कुछ अलग करते हैं, तो यह मैच का स्वत: हार होगा।

नियम

आप अंतर्निहित कार्यों को बदल नहीं सकते हैं।

परिक्षण

मैं एक Git को कोड और सभी बॉट्स के साथ अपडेट करता रहूंगा: https://github.com/Masclins/LoadedRPS

आंकना

1000 पूर्ण राउंड-रॉबिन के बाद सबसे अधिक जीत वाले व्यक्ति को चुनकर विजेता का फैसला किया जाएगा। बंधे हुए मैचों से टाई टूट जाएगा। एक के बजाय 1000 मैच खेले जा रहे हैं क्योंकि मुझे बहुत अधिक यादृच्छिकता की उम्मीद है, और इस तरह यादृच्छिकता कम प्रासंगिक होगी।

आप 5 बॉट तक जमा कर सकते हैं।

पर प्रतियोगिता समाप्त होता है जुलाई जून 4 (कि अंतिम दिन मैं किसी भी सवाल का जवाब स्वीकार करेंगे हो जाएगा), और पर जुलाई जून 5 वीं मैं अंतिम stadings पोस्ट करेंगे (पहले एक advancemnt पोस्ट करने के लिए कोशिश कर सकते हैं)।


चूंकि यह मेरा पहला KOTH है, मैं सुधार के लिए कुछ भी बदलने के लिए 100% खोला गया हूं, जैसे कि प्रत्येक बॉट के खिलाफ खेले जाने वाले मैचों की संख्या।

1000 मैचों का संपादन, क्योंकि मैं देख रहा हूं कि वास्तव में इसमें काफी यादृच्छिकता शामिल है।


कुछ यादृच्छिक बॉट्स के साथ, आप वास्तव में कई राउंड के कई गेम बनाना चाहते हैं
विनाशकारी नींबू

@DestructibleLemon मैंने एक बार के बजाय प्रत्येक बॉट को एक-दूसरे बॉट के खिलाफ तीन बार खेलने के बारे में सोचा। आपको भी ऐसा ही लगता है, देखकर मैं ऐसा करूंगा।
मासक्लिंस

1
(वास्तव में आपको एक उचित बड़ी संख्या की आवश्यकता है, क्योंकि कुछ संभावनाएं वास्तव में कई मैचों से अधिक होती हैं। मेरे बॉट को देखें, जहां इसे ट्रू किया जा सकता है, लेकिन संभवतः मैचों की उचित मात्रा के साथ नहीं होगा)
विनाशकारी नींबू

1
मुझे खुशी है कि मेरे सवाल से आपको यह चलाने में सक्षम होने में मदद मिली, @AlbertMasclans!
ग्रीफॉन

2
@AlbertMasclans क्या आप पूर्ण परीक्षण (सहित runcodeऔर bots) पोस्ट कर सकते हैं ?
कैलक्यूलेटरफिलीन

जवाबों:


8

सांख्यिकीविद (अब नहीं खेल रहे हैं)

import random
import collections

R, P, S = moves = range(3)
move_idx = {"R": R, "P": P, "S": S}
name = "RPS"
beat = (P, S, R)
beaten = (S, R, P)

def react(_0, _1, _2, _3, _4, opp_history):
    if not opp_history:
        return random.randrange(0, 3)
    return beat[opp_history[-1]]

def anti_react(_0, _1, _2, _3, _4, opp_history):
    if not opp_history:
        return random.randrange(0, 3)
    return beaten[opp_history[-1]]

def random_max(scores):
    scores = [s + random.normalvariate(0, 1) for s in scores]
    return scores.index(max(scores))

def greedy_margin(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    scores = [my_loaded[move] - opp_loaded[beat[move]] for move in moves]
    return random_max(scores)

def anti_greedy(my_points, opp_pints, my_loaded, opp_loaded, my_history, opp_history):
    scores = [-my_loaded[move] for move in moves]
    return random_max(scores)

def recent_stats(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    opp_history = opp_history[-10:-1]
    counts = collections.Counter(opp_history)
    scores = [(counts[beaten[move]] + 1) * my_loaded[move] - 
              (counts[beat[move]] + 1) * opp_loaded[move] for move in moves]
    return random_max(scores)

def statistician(_0, _1, _2, _3, my_history, opp_history):
    m1 = []
    o1 = []
    my_loaded = [0] * 3
    opp_loaded = [0] * 3
    my_points = 0
    opp_points = 0
    strategies = [react, anti_react, greedy_margin, anti_greedy, recent_stats]
    strategy_scores = [0 for _ in strategies]
    for i, (mx, ox) in enumerate(zip(my_history, opp_history)):
        mx = move_idx[mx]
        ox = move_idx[ox]
        for j, strategy in enumerate(strategies):
            strategy_scores[j] *= 0.98
            move = strategy(my_points, opp_points, my_loaded, opp_loaded, m1, o1)
            if move == beat[ox]:
                strategy_scores[j] += my_loaded[move]
            elif move == beaten[ox]:
                strategy_scores[j] -= opp_loaded[ox]
        m1.append(mx)
        o1.append(ox)
        if mx == beat[ox]:
            opp_loaded[ox] += 1
            my_points += my_loaded[mx]
        elif mx == beaten[ox]:
            my_loaded[mx] += 1
            opp_points += opp_loaded[ox]
        else:
            my_loaded[mx] += 0.5
            opp_loaded[ox] += 0.5
    strategy = strategies[random_max(strategy_scores)]
    return name[strategy(my_points, opp_points, my_loaded, opp_loaded, m1, o1)]

पिछले प्रदर्शन के आधार पर कुछ सरल रणनीतियों के बीच स्विच करता है

सांख्यिकीविद २

import random
import collections
import numpy as np

R, P, S = moves = range(3)
move_idx = {"R": R, "P": P, "S": S}
names = "RPS"
beat = (P, S, R)
beaten = (S, R, P)

def react(my_loaded, opp_loaded, my_history, opp_history):
    if not opp_history:
        return random.randrange(0, 3)
    counts = [0, 0, 0]
    counts[beat[opp_history[-1]]] += 1
    return counts

def random_max(scores):
    scores = [s + random.normalvariate(0, 1) for s in scores]
    return scores.index(max(scores))

def argmax(scores):
    m = max(scores)
    return [s == m for s in scores]

def greedy_margin(my_loaded, opp_loaded, my_history, opp_history):
    scores = [my_loaded[move] - opp_loaded[beat[move]] for move in moves]
    return argmax(scores)

recent_counts = None

def best_move(counts, my_loaded, opp_loaded):
    scores = [(counts[beaten[move]] + 0.5) * my_loaded[move] - 
              (counts[beat[move]] + 0.5) * opp_loaded[move] for move in moves]
    return argmax(scores)

def recent_stats(my_loaded, opp_loaded, my_history, opp_history):
    if len(opp_history) >= 10:
        recent_counts[opp_history[-10]] -= 1
    recent_counts[opp_history[-1]] += 1
    return best_move(recent_counts, my_loaded, opp_loaded)

order2_counts = None

def order2(my_loaded, opp_loaded, my_history, opp_history):
    if len(my_history) >= 2:
        base0 = 9 * my_history[-2] + 3 * opp_history[-2]
        order2_counts[base0 + opp_history[-1]] += 1
    base1 = 9 * my_history[-1] + 3 * opp_history[-1]
    counts = [order2_counts[base1 + move] for move in moves]
    return best_move(counts, my_loaded, opp_loaded)

def nash(my_loaded, opp_loaded, my_history, opp_history):
    third = 1.0 / 3
    p = np.full(3, third)
    q = np.full(3, third)
    u = np.array(my_loaded)
    v = np.array(opp_loaded)
    m0 = np.zeros(3)
    m1 = np.zeros(3)
    lr = 0.2
    for _ in range(10):
        de0 = u * np.roll(q, 1) - np.roll(v * q, 2)
        de1 = v * np.roll(p, 1) - np.roll(u * p, 2)
        m0 = 0.9 * m0 + 0.1 * de0
        m1 = 0.9 * m1 + 0.1 * de1
        p += lr * m0
        q += lr * m1
        p[p < 0] = 0
        q[q < 0] = 0
        tp, tq = np.sum(p), np.sum(q)
        if tp == 0 or tq == 0:
            return np.full(3, third)
        p /= tp
        q /= tq
        lr *= 0.9
    return p

strategies = [react, greedy_margin, recent_stats, order2, nash]

predictions = strategy_scores = mh = oh = None

def statistician2func(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    global strategy_scores, history, recent_counts, mh, oh, predictions, order2_counts
    if not opp_history:
        strategy_scores = [0 for _ in strategies]
        recent_counts = collections.Counter()
        order2_counts = collections.Counter()
        mh, oh = [], []
        predictions = None
        return random.choice(names)
    my_move = move_idx[my_history[-1]]
    opp_move = move_idx[opp_history[-1]]
    if predictions is not None:
        for j, p in enumerate(predictions):
            good = beat[opp_move]
            bad = beaten[opp_move]
            strategy_scores[j] += (my_loaded[good] * p[good] - opp_loaded[opp_move] * p[bad]) / sum(p)
    mh.append(my_move)
    oh.append(opp_move)
    predictions = [strategy(my_loaded, opp_loaded, mh, oh) for strategy in strategies]
    strategy = random_max(strategy_scores)
    p = predictions[strategy]
    r = random.random()
    for i, pi in enumerate(p):
        r -= pi
        if r <= 0:
            break
    return names[i]

नैश

import numpy as np
import random

def nashfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    third = 1.0 / 3
    p = np.full(3, third)
    q = np.full(3, third)
    u = np.array(my_loaded)
    v = np.array(opp_loaded)
    m0 = np.zeros(3)
    m1 = np.zeros(3)
    lr = 0.2
    for _ in range(10):
        de0 = u * np.roll(q, 1) - np.roll(v * q, 2)
        de1 = v * np.roll(p, 1) - np.roll(u * p, 2)
        m0 = 0.9 * m0 + 0.1 * de0
        m1 = 0.9 * m1 + 0.1 * de1
        p += lr * m0
        q += lr * m1
        p[p < 0] = 0
        q[q < 0] = 0
        tp, tq = np.sum(p), np.sum(q)
        if tp == 0 or tq == 0:
            return random.choice("RPS")
        p /= tp
        q /= tq
        lr *= 0.9
    r = random.random()
    for i, pi in enumerate(p):
        r -= pi
        if r <= 0:
            break
    return "RPS"[i]

क्रमिक वंश द्वारा एक अनुमानित एनएएस संतुलन की गणना करता है।


1
मैं वास्तव में इस दृष्टिकोण को पसंद करता हूं, और समझ सकता हूं कि आप राउंड के बीच स्थिति को क्यों बनाए रखना चाहते हैं। भले ही मैं इसे बदलने के लिए एक बड़ी समस्या देखता हूं, इसे प्रस्तुतियाँ की संख्या दी गई है। मैं आगे की चुनौतियों के लिए इसे ध्यान में रखूंगा (जो कि यह पूरा होने पर मुझे उम्मीद है)।
मैस्किन्स

5

तुला

मैंने कोड के साथ प्रयोग करते समय तर्क का ट्रैक खो दिया है, लेकिन मूल विचार प्रतिद्वंद्वी के चाल की संभावना का अनुमान लगाने के लिए कुछ वजन का उपयोग करके पिछले 3 चालों द्वारा किया जाता है और उन्हें एक और वजन से गुणा करता है जो भार पर निर्भर करता है। मैंने सोचा था कि मैं किसी तरह से भी उपयोग my_loadedकर सकता हूं, लेकिन मैं यह तय नहीं कर सकता कि कैसे, इसलिए इसे छोड़ दिया।

def weigher(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    idx = {"R": 0, "P": 1, "S": 2}
    sc = [0, 0, 0]
    for i, m in enumerate(reversed(opp_history[-3:])):
        sc[idx[m]] += (1 / (1 + i))

    for i in range(3):
        sc[i] *= (opp_loaded[i] ** 2)

    return "PSR"[sc.index(max(sc))]

शैतान

शायद अयोग्य हो जाएगा, क्योंकि यह धोखा देने की तरह है और यह परीक्षण फ़ंक्शन के बारे में कुछ धारणाएं बनाता है (इसके स्टैक फ्रेम पर एक चर में प्रतिद्वंद्वी का कार्य करना पड़ता है), लेकिन यह तकनीकी रूप से किसी भी मौजूदा नियम को नहीं तोड़ता है - यह नहीं करता है किसी चीज़ को फिर से लिखना या फिर से लिखना। यह बस विरोधी फ़ंक्शन को निष्पादित करने के लिए काले जादू का उपयोग करता है यह देखने के लिए कि उन्होंने क्या किया / वे क्या करेंगे। यह यादृच्छिकता से नहीं निपट सकता है, लेकिन निर्धारक बॉट्स के पास शैतान को हराने का कोई मौका नहीं है।

def satan(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    import inspect, types
    f = inspect.currentframe()
    s = f.f_code.co_name
    try:
        for v in f.f_back.f_locals.values():
            if isinstance(v, types.FunctionType) and v.__name__ != s:
                try:
                    return "PSR"[{"R": 0, "P": 1, "S": 2}[
                        v(opp_points, my_points, opp_loaded, my_loaded, opp_history, my_history)]]
                except:
                    continue
    finally:
        del f

बिना किसी संदेह के सादगी-परिणाम के संदर्भ में सबसे अच्छा
Masclins

वैसे, उपयोग करने के लिए my_loadedआप एक ऐसा वज़न जोड़ सकते हैं जो उस मूव को महत्व देता है जो आपके अंतिम मूव (एस) के खिलाफ खो जाएगा। यह मानने जैसा है कि आपका विरोधी आपके साथ जैसा करेगा वैसा ही कुछ करेगा, और इसलिए उसे यह मानने के लिए दंडित करना कि आप वही खेलते रहेंगे। कुछ इस तरह:for i, m in enumerate(reversed(my_history[-3:])): sc[(idx[m]+1)%3] += (K / (1 + i))
मैस्किन्स

@AlbertMasclans ने एक और समाधान जोड़ा
प्रदर्शन नाम

1
मैं वास्तव में शैतान को पसंद करता हूं। लेकिन जैसा कि आपने कहा, मेरा मानना ​​है कि इसे योग्य नहीं होना चाहिए: भले ही यह किसी भी स्पष्ट नियम को नहीं तोड़ता है, यह स्पष्ट रूप से खेल की भावना के खिलाफ है। फिर भी, आपके विचार पर बधाई!
मैस्किन्स

4

फिटर

यह बॉट पैटर्न में सुधार करता है और अर्थशास्त्री के साथ इसे फ्यूज करता है (पैटर्न और अर्थशास्त्री अब भाग नहीं लेंगे)

पैटर्न में सुधार यह है कि बॉट अब दो दो प्रकार के पैटर्न की तलाश करता है: विरोधी अपने अंतिम नाटक पर प्रतिक्रिया दे रहा है और प्रतिद्वंद्वी मेरे पहले नाटक पर प्रतिक्रिया दे रहा है। फिर दोनों भविष्यवाणियों का मूल्यांकन करता है कि जो सबसे अच्छा फिट बैठता है उसका उपयोग करें।

उस पैटर्न से बॉट के पास अब आर, पी और एस के लिए संभावना है कि खाते में और प्रत्येक नाटक के अपेक्षित मूल्य (जैसा कि अर्थशास्त्री ने किया था), बॉट वह निभाता है जो सबसे अधिक मूल्य देता है।

import random
import numpy as np
def fitterfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
        t = len(opp_history)
        RPS = ["R","P","S"]
        if t <= 2:
                return RPS[t]
        elif t == 3:
                return random.choice(RPS)

        def n(c): return RPS.index(c)

        total_me = np.zeros(shape=(3,3))
        total_opp= np.zeros(shape=(3,3))
        p_me = np.array([[1/3]*3]*3)
        p_opp = np.array([[1/3]*3]*3)

        for i in range(1, t):
                total_me[n(my_history[i-1]), n(opp_history[i])] += 1
                total_opp[n(opp_history[i-1]), n(opp_history[i])] += 1
        for i in range(3):
                if np.sum(total_me[i,:]) != 0:
                        p_me[i,:] = total_me[i,:] / np.sum(total_me[i,:])
                if np.sum(total_opp[i,:]) != 0:
                        p_opp[i,:] = total_opp[i,:] / np.sum(total_opp[i,:])

        error_me = 0
        error_opp = 0

        for i in range(1, t):
                diff = 1 - p_me[n(my_history[i-1]), n(opp_history[i])]
                error_me += diff * diff
                diff = 1 - p_opp[n(opp_history[i-1]), n(opp_history[i])]
                error_opp += diff * diff

        if error_me < error_opp:
                p = p_me[n(my_history[-1]),:]
        else:
                p = p_opp[n(opp_history[-1]),:]


# From here, right now I weight values, though not 100% is the best idea, I leave the alternative in case I'd feel like changing it
        value = [(p[2]*my_loaded[0] - p[1]*opp_loaded[1], "R"), (p[0]*my_loaded[1] - p[2]*opp_loaded[2], "P"), (p[1]*my_loaded[2] - p[0]*opp_loaded[0], "S")]
        value.sort()

        if value[-1][0] > value[-2][0]:
                return value[-1][1]
        elif value[-1][0] > value[-3][0]:
                return random.choice([value[-1][1], value[-2][1]])
        else:
                return random.choice(RPS)

#       idx = p.tolist().index(max(p))
#       return ["P", "S", "R"][idx]

यहाँ दो पुराने कोड हैं

पैटर्न (अब नहीं खेल रहा है)

पैटर्न अपने प्रतिद्वंद्वी पर पैटर्न खोजने की कोशिश करता है। यह दिखता है कि प्रतिद्वंद्वी ने आखिरी नाटक के बाद क्या खेला था (बाद के नाटकों को अधिक वजन देना)। इसके माध्यम से, यह अनुमान लगाता है कि प्रतिद्वंद्वी क्या खेलेगा, और उस पर जवाबी कार्रवाई करेगा।

import random
import numpy as np
def patternfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
        if len(opp_history) == 0:
                return random.choice(["R","P","S"])
        elif len(opp_history) == 1:
                if opp_history == "R":
                        return "P"
                elif opp_history == "P":
                        return "S"
                elif opp_history == "S":
                        return "R"

        p = np.array([1/3]*3)
        c = opp_history[-1]
        for i in range(1, len(opp_history)):
                c0 = opp_history[i-1]
                c1 = opp_history[i]
                if c0 == c:
                        p *= .9
                        if c1 == "R":
                                p[0] += .1
                        elif c1 == "P":
                                p[1] += .1
                        elif c1 == "S":
                                p[2] += .1

        idx = p.tolist().index(max(p))
        return ["P", "S", "R"][idx]

अर्थशास्त्री (अब नहीं खेल रहे हैं)

द इकोनॉमिस्ट निम्न कार्य करता है: प्रतिद्वंद्वी द्वारा प्रत्येक खेल की संभावना को देखकर यह अनुमान लगाता है कि उसने अंतिम 9 बार क्या खेला था। उस से, प्रत्येक नाटक के अपेक्षित लाभ की गणना करता है और उस के साथ जाता है जिसका सबसे अच्छा मूल्य होता है।

import random
def economistfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
        if len(opp_history) == 0:
                return random.choice(["R","P","S"])
        if len(opp_history) > 9:
                opp_history = opp_history[-10:-1]
        p = [opp_history.count("R"), opp_history.count("P"), opp_history.count("S")]

        value = [(p[2]*my_loaded[0] - p[1]*opp_loaded[1], "R"), (p[0]*my_loaded[1] - p[2]*opp_loaded[2], "P"), (p[1]*my_loaded[2] - p[0]*opp_loaded[0], "S")]
        value.sort()

        if value[-1][0] > value[-2][0]:
                return value[-1][1]
        elif value[-1][0] > value[-3][0]:
                return random.choice([value[-1][1], value[-2][1]])
        else:
                return random.choice(["R","P","S"])

4

Yggdrasil

इसे "Yggdrasil" नाम दिया गया है क्योंकि यह गेम ट्री में आगे दिखता है। यह बॉट प्रतिद्वंद्वी की कोई भी भविष्यवाणी नहीं करता है, यह केवल एक सांख्यिकीय लाभ बनाए रखने का प्रयास करता है अगर इसे एक दिया जाता है (वर्तमान और भविष्य के मुनाफे को संतुलित करके)। यह एक लगभग आदर्श मिश्रित रणनीति की गणना करता है, और उन भारों के साथ यादृच्छिक रूप से चयनित एक चाल देता है। यदि यह बॉट परिपूर्ण था (जो कि ऐसा नहीं है, क्योंकि राज्य का मूल्यांकन कार्य बहुत बुरा है और यह बहुत आगे नहीं दिखता है), तो इस बॉट को 50% से अधिक बार हरा पाना असंभव होगा। मुझे नहीं पता कि यह बॉट व्यवहार में कितना अच्छा करेगा।

def yggdrasil(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    cache = {}
    def get(turn, ml, ol):
        key = str(turn) + str(ml) + str(ol)
        if not key in cache:
            cache[key] = State(turn, ml, ol)
        return cache[key]

    def wrand(opts):
        total = sum(abs(w) for c,w in opts.items())
        while True:
            r = random.uniform(0, total)
            for c, w in opts.items():
                r -= abs(w)
                if r < 0:
                    return c
            print("error",total,r)

    class State():
        turn = 0
        ml = [1,1,1]
        ol = [1,1,1]
        val = 0
        strat = [1/3, 1/3, 1/3]
        depth = -1
        R = 0
        P = 1
        S = 2
        eps = 0.0001
        maxturn = 1000

        def __init__(self, turn, ml, ol):
            self.turn = turn
            self.ml = ml
            self.ol = ol
        def calcval(self, depth):
            if depth <= self.depth:
                return self.val
            if turn >= 1000:
                return 0
            a = 0
            b = -self.ol[P]
            c = self.ml[R]
            d = self.ml[P]
            e = 0
            f = -self.ol[S]
            g = -self.ol[R]
            h = self.ml[S]
            i = 0
            if depth > 0:
                a += get(self.turn+1,[self.ml[R]+1,self.ml[P],self.ml[S]],[self.ol[R]+1,self.ol[P],self.ol[S]]).calcval(depth-1)
                b += get(self.turn+1,[self.ml[R]+2,self.ml[P],self.ml[S]],[self.ol[R],self.ol[P],self.ol[S]]).calcval(depth-1)
                c += get(self.turn+1,[self.ml[R],self.ml[P],self.ml[S]],[self.ol[R],self.ol[P],self.ol[S]+2]).calcval(depth-1)
                d += get(self.turn+1,[self.ml[R],self.ml[P],self.ml[S]],[self.ol[R]+2,self.ol[P],self.ol[S]]).calcval(depth-1)
                e += get(self.turn+1,[self.ml[R],self.ml[P]+1,self.ml[S]],[self.ol[R],self.ol[P]+1,self.ol[S]]).calcval(depth-1)
                f += get(self.turn+1,[self.ml[R],self.ml[P]+2,self.ml[S]],[self.ol[R],self.ol[P],self.ol[S]]).calcval(depth-1)
                g += get(self.turn+1,[self.ml[R],self.ml[P],self.ml[S]+2],[self.ol[R],self.ol[P],self.ol[S]]).calcval(depth-1)
                h += get(self.turn+1,[self.ml[R],self.ml[P],self.ml[S]],[self.ol[R],self.ol[P]+2,self.ol[S]]).calcval(depth-1)
                i += get(self.turn+1,[self.ml[R],self.ml[P],self.ml[S]+1],[self.ol[R],self.ol[P],self.ol[S]+1]).calcval(depth-1)
            self.val = -9223372036854775808
            for pr in range(0,7):
                for pp in range(0,7-pr):
                    ps = 6-pr-pp
                    thisval = min([pr*a+pp*d+ps*g,pr*b+pp*e+ps*h,pr*c+pp*f+ps*i])
                    if thisval > self.val:
                        self.strat = [pr,pp,ps]
                        self.val = thisval
            self.val /= 6


            if depth == 0:
                self.val *= min(self.val, self.maxturn - self.turn)
            return self.val

    turn = len(my_history)
    teststate = get(turn, [x * 2 for x in my_loaded], [x * 2 for x in opp_loaded])
    teststate.calcval(1)
    return wrand({"R":teststate.strat[R],"P":teststate.strat[P],"S":teststate.strat[S]})

कृपया उन टिप्पणियों को हटा दें जो कोड को अधिक समझने योग्य नहीं हैं
प्रदर्शन नाम

@ सर्जबॉर्श किया
फियोटपाइ

1
@PhiNotPi मुझे पता है कि मैंने बिना समय सीमा के पोस्ट किया, लेकिन Yggdrasil प्रत्येक प्रतिद्वंद्वी के खिलाफ एक मिनट से अधिक समय ले रहा है। क्या इसे थोड़ा अनुकूलित करना संभव होगा?
मैक्लिन्स

हाँ, यह असहनीय रूप से धीमा है
प्रदर्शन नाम

प्रति मिनट प्रति मिनट @AlbertMasclans क्या आप एक विरोधी के खिलाफ सभी खेल के लिए कुल 1 मिनट का मतलब है? इसके अलावा, मैं इसे गति देने की कोशिश कर सकता हूं, लेकिन मुझे वास्तव में यह नहीं पता है कि यह कैसे करना है, यह केवल 1 कदम आगे दिखता है।
फीनोटपी

4

विरोधी पुनरावर्तक

from random import choice
def Antirepeaterfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    s = opp_history.count("S")
    r = opp_history.count("R")
    p = opp_history.count("P")

    if s>p and s>r:
        return "R"
    elif p>s and p>r:
        return "S"
    else:
        return "P"

पहले मोड़ पर पेपर लीक हो जाता है, इसके बाद जो कुछ भी धड़कता है वह प्रतिद्वंद्वी के मुकाबले सबसे ज्यादा किया जाता है।

नकल

import random
def copycatfunc(I,dont,care,about,these,enmoves):
    if not enmoves:
        return random.choice(["R","P","S"])
    else:
        return enmoves[len(enmoves)-1]

बस विरोधियों की आखिरी चाल की नकल करता है।

विरोधी विरोधी लालची

from random import choice
def antiantigreedy(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    if opp_loaded[0] > opp_loaded[1] and opp_loaded[0] > opp_loaded[2]:
        return "S"
    if opp_loaded[1] > opp_loaded[0] and opp_loaded[1] > opp_loaded[2]:
        return "R"
    if opp_loaded[2] > opp_loaded[0] and opp_loaded[2] > opp_loaded[1]:
        return "P"
    else:
        return choice(["R","P","S"])

प्रतिद्वंद्वी की सबसे भारी भारित पसंद को खो देता है।

थोड़ी भूख लगी है

from random import choice
def somewhathungryfunc(blah, blah2, load, blah3, blah4, blah5):
    if load[0] > load[1] and load[0] < load[2] or load[0] < load[1] and load[0] > load[2]:
        return "R"
    if load[1] > load[0] and load[1] < load[2] or load[1] < load[0] and load[1] > load[2]:
        return "P"
    if load[2] > load[1] and load[2] < load[0] or load[2] < load[1] and load[2] > load[0]:
        return "S"
    else:
        return choice(["R","P","S"])

3

संदेशवाहक

डीएम्ज़मेन्फरफुन्क (I, do, not, need, these, आर्ग्युमेंट्स): "P" लौटाएं

रॉकस्टार

रॉकस्टारफुन्क (I, do, not, need, these, आर्ग्युमेंट्स): "R" लौटाएं

हत्यारा

def assfunc (I, do, not, need, these, आर्ग्युमेंट्स): रिटर्न "S"

व्याख्या

अब, आप सोच सकते हैं कि ये बॉट पूरी तरह से बेवकूफ हैं।

पूरी तरह से सच नहीं है, ये वास्तव में विचार पर आधारित हैं, एक विशाल बोनस amassing के, और दुश्मन एक गलत बनाने और इसके साथ walloped हो रही है।

अब, ये बोट्स लालची के समान खेलते हैं, हालांकि, वे सरल होते हैं, और बेतरतीब ढंग से नहीं उठाते हैं जब तक कि उन्हें एक हथियार पर भार नहीं मिलता है, वे अपनी पसंद के हथियार के साथ चिपके रहते हैं।

ध्यान देने वाली एक और बात: ये प्रत्येक आधे समय के आसपास लालची को हरा देंगे, एक तिहाई को आकर्षित करेंगे, और समय के एक छठे को खो देंगे। जब वे जीतते हैं, तो वे बहुत कुछ करके जीतेंगे। यह क्यों है?

लालची, जब तक वह एक राउंड नहीं हारता, बेतरतीब ढंग से एक हथियार उठाएगा। इसका मतलब यह है कि जब वह एक राउंड नहीं जीतता है, तो वह फिर से बेतरतीब ढंग से एक हथियार उठाएगा, जो फिर से एक जीत हो सकती है। यदि लालची आकर्षित या हार जाता है, तो वह उस हथियार से चिपक जाता है। यदि लालची कम से कम एक राउंड जीतता है, तो वही हथियार उठाता है जैसे कि बॉट, लालची जीतता है। यदि लालची किसी बिंदु पर हारने वाले हथियार को उठाता है, तो हमारा बॉट जीत जाता है, क्योंकि हमारे हथियार पर भार स्कोर लालची की तुलना में अधिक होता है।

यह मानते हुए कि लालची हमेशा जीतने का हथियार भव्य अवसर के माध्यम से नहीं उठाता है, इसका मतलब यह होगा कि संभावनाएं हैं:

1/3: {1/2 जीत (1/6 कुल)। 1/2 हार (1/6 कुल)। }

1/3 ड्रा

1/3 जीत

इसलिए: ड्रा करने के लिए 1/3 मौका, हार का 1/6 मौका, जीतने का 1/2 मौका।

यह संभवतः दिखाता है कि आपको कई राउंड के कई गेम करने की आवश्यकता है

ये मुख्य रूप से चुनौती देने के लिए हैं


3

रिएक्टर

वह नाटक बनाता है जो पिछले दौर में जीता होगा।

import random
def reactfunc(I, dont, need, all, these, opp_history):
    if not opp_history:
        return random.choice(["R","P","S"])
    else:
        prev=opp_history[len(opp_history)-1]
        if prev == "R":
            return "P"
        if prev == "P":
            return "S"
        else:
            return "R"

1
आप बदल सकते हैं opp_history[len(opp_history)-1]के साथ opp_history[-1]
कैलक्यूलेटरफिलीन

3

आर्टी चाइल्ड

यह बॉट एक बच्चे की कला और शिल्प की तरह काम करता है, कागज के साथ शुरू होगा और कागज या कैंची का उपयोग बेतरतीब ढंग से करेगा, लेकिन रॉक या कैंची के बाद कैंची का उपयोग नहीं करेगा क्योंकि उसे कागज पर कैंची का उपयोग करने की आवश्यकता है। जो कोई भी उस पर एक चट्टान फेंकता है, वह एक चट्टान को वापस फेंक देगा।

import random
def artsychildfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    if len(opp_history) == 0:
            return "P"
    elif opp_history[-1] == "R":
            return "R"
    elif my_history[-1] != "P":
            return "P"
    else:
            return random.choice(["P", "S"])

2

यहाँ मेरे परीक्षण के लिए बनाए गए तीन बॉट हैं:


RandomBot

import random
def randombotfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
        return random.choice(["R","P","S"])

लालची

बस अपना सबसे भरा हुआ विकल्प चुनता है।

import random
def greedyfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
        if my_loaded[0] > my_loaded[1]:
                if my_loaded[0] > my_loaded[2]:
                        return "R"
                elif my_loaded[0] < my_loaded[2]:
                        return "S"
                else:
                        return random.choice(["R","S"])
        elif my_loaded[0] < my_loaded[1]:
                if my_loaded[1] > my_loaded[2]:
                        return "P"
                elif my_loaded[1] < my_loaded[2]:
                        return "S"
                else:
                        return random.choice(["P","S"])
        else:
                if my_loaded[0] > my_loaded[2]:
                        return random.choice(["R","P"])
                elif my_loaded[0] < my_loaded[2]:
                        return "S"
                else:
                        return random.choice(["R","P","S"])

Antigreedy

विरोधी मानता है कि लालची खेलेंगे और जीतने वाला विकल्प खेलेंगे।

import random
def antigreedyfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
        if opp_loaded[0] > opp_loaded[1]:
                if opp_loaded[0] > opp_loaded[2]:
                        return "P"
                elif opp_loaded[0] < opp_loaded[2]:
                        return "R"
                else:
                        return "R"
        elif opp_loaded[0] < opp_loaded[1]:
                if opp_loaded[1] > opp_loaded[2]:
                        return "S"
                elif opp_loaded[1] < opp_loaded[2]:
                        return "R"
                else:
                        return "S"
        else:
                if opp_loaded[0] > opp_loaded[2]:
                        return "P"
                elif opp_loaded[0] < opp_loaded[2]:
                        return "R"
                else:
                        return random.choice(["R","P","S"])

1

भूख नहीं

def nothungryfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    if my_loaded[0] < my_loaded[1]:
            if my_loaded[0] < my_loaded[2]:
                    return "R"
            elif my_loaded[0] > my_loaded[2]:
                    return "S"
            else:
                    return random.choice(["R","S"])
    elif my_loaded[0] > my_loaded[1]:
            if my_loaded[1] < my_loaded[2]:
                    return "P"
            elif my_loaded[1] > my_loaded[2]:
                    return "S"
            else:
                    return random.choice(["P","S"])
    else:
            if my_loaded[0] < my_loaded[2]:
                    return random.choice(["R","P"])
            elif my_loaded[0] > my_loaded[2]:
                    return "S"
            else:
                    return random.choice(["R","P","S"])

यह वस्तुतः लालची का विलोम है, यह उपलब्ध सबसे कम अंकों के विकल्प को चुनता है।


1

विरोधी के पसंदीदा का उपयोग करें

from collections import Counter
import random
def useopponents(hi, my, name, is, stephen, opp_history):
  if opp_history:
    data = Counter(opp_history)
    return data.most_common(1)[0][0]
  else:
    return random.choice(["R","P","S"])

पहली बारी के लिए, एक यादृच्छिक आइटम चुनता है। हर दूसरे मोड़ के लिए, प्रतिद्वंद्वी की सबसे आम पसंद का उपयोग करता है। यदि कोई टाई है, तो यह सबसे आम पसंद के लिए चूक है।

// मैंने यहाँ से कोड चुराया है


जीतना अच्छा है

import random
def goodwinning(no, yes, maybe, so, my_history, opp_history):
  if opp_history:
    me = my_history[len(my_history)-1]
    you = opp_history[len(opp_history)-1]
    if you == me:
      return goodwinning(no, yes, maybe, so, my_history[:-1], opp_history[:-1])
    else:
      if me == "R":
        if you == "P":
          return "P"
        else:
          return "R"
      elif me == "P":
        if you == "S":
          return "S"
        else:
          return "R"
      else:
        if you == "R":
          return "R"
        else:
          return "P"
  else:
    return random.choice(["R","P","S"])

पिछले दौर के विजेता की पसंद लौटाता है। यदि पिछला राउंड एक टाई था, तो उससे पहले के राउंड को फिर से जाँचता है। यदि यह केवल संबंध था, या यह पहला दौर है, एक यादृच्छिक विकल्प देता है।


1

दोनों ओर से लाभदायक

यह बॉट मूल रूप से एंटी-लालची और लालची (इसलिए नाम) को जोड़ती है।

def bobwfunc(a, b, my_loaded, opp_loaded, c, d):
    opp_max = max(opp_loaded)
    opp_play = "PSR"[opp_loaded.index(opp_max)]

    my_max = max(my_loaded)
    my_play = "RPS"[my_loaded.index(my_max)]

    if opp_play == my_play:
        return opp_play
    else:
        return my_play if opp_max < my_max else opp_play

यह एंटीग्रेडी है, पहले से ही एक उदाहरण के रूप में पोस्ट किया गया है।
मस्किन्स

@AlbertMasclans ने इसे दूसरे बॉट में बदल दिया।
मौलवी

findतार के लिए है। my_loadedऔर opp_loadedदोनों सूची हैं। indexआप जो चाहते हैं उसके लिए अच्छा होना चाहिए।
मस्किन्स

@AlbertMasclans वूप्स, अब तय किया गया। पकड़ने के लिए धन्यवाद! मुझे उम्मीद है कि यह कोई और डुप्लिकेट नहीं है ... मैं इस पोस्ट को फिर से हटाना नहीं चाहता।
मौलवी

यह ठीक है, खेलने के लिए धन्यवाद
मैस्किन्स

1

NashBot

import random
def nashbotfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    r = opp_loaded[0] * opp_loaded[2]
    p = opp_loaded[0] * opp_loaded[1]
    s = opp_loaded[1] * opp_loaded[2]
    q = random.uniform(0, r + p + s) - r
    return "R" if q < 0 else "P" if q < p else "S"

बेतरतीब ढंग से तीन विकल्पों के बीच चयन करता है कि प्रतिद्वंद्वी सांख्यिकीय रूप से कितना स्कोर करता है, इस संबंध में चालों के बीच कोई वरीयता नहीं है; दूसरे शब्दों में, Greedy और Not Hungry दोनों के पास इसके खिलाफ औसत औसत स्कोर होना चाहिए।


1

Expectedbayes

संपादित करें: अद्यतन रैंकिंग

यह अपेक्षित शीर्षकों को शामिल करने के बाद नई शीर्ष रैंकिंग है:

  • सांख्यिकीविद् 2func 91.89%
  • फिटरफुनक 85.65%
  • नशफून 80.40%
  • वेटेरफंक 76.39%
  • अपेक्षित 73% 3%
  • एंटीरेप्टरफ़नक 68.52%
  • ...

स्पष्टीकरण

(एनबी: पोस्ट 05/06/2017 सबमिशन)

यह बॉट इसके अगले कदम के अपेक्षित मूल्य को अधिकतम करने की कोशिश करता है:

  • प्रतिद्वंद्वी के अगले संभावित कदम के लिए संभावना की गणना करना
  • उस आकृति और भार का उपयोग करके R, P और S में से प्रत्येक के लिए अपेक्षित मान की गणना करना
  • उस चाल का चयन करना जिसमें सबसे अधिक अपेक्षित मूल्य है
  • यदि अनुमान लगाना विफल रहा तो बेतरतीब ढंग से मूल्य का चयन

हर दस चालों में संभावनाओं को अपडेट किया जाता है। प्रत्येक बॉट के लिए संभावनाओं की गणना करने के लिए उपयोग किए जाने वाले पिछले चालों की संख्या 10 पर सेट की गई है (इसलिए कुल मिलाकर 20 विशेषताएं)। यह संभवतः डेटा को ओवरफिट कर रहा है, लेकिन मैंने आगे जांचने की कोशिश नहीं की।

यह प्रतिद्वंद्वी की संभावित संभावनाओं की गणना करने के लिए scitit लाइब्रेरी पर निर्भर करता है (मैं इसे नियमों के गलत होने की स्थिति में कह रहा हूं और यह वास्तव में अनुमति नहीं थी)।

यह आसानी से बॉट्स के खिलाफ जीतता है जो हमेशा एक ही विकल्प बनाते हैं। आश्चर्यजनक रूप से, यह 93% जीत दर के साथ यादृच्छिक बॉट के खिलाफ काफी प्रभावी है (मेरा मानना ​​है कि यह इस तथ्य के कारण है कि यह प्रत्येक दौर के लिए अपने संभावित अंकों की अधिकतम संख्या को अधिकतम करते हुए अपने प्रतिद्वंद्वी को प्राप्त होने वाले अंकों की सीमा को सीमित कर सकता है)।

मैंने 100 बार और केवल सीमित संख्या में बॉट्स के साथ एक त्वरित प्रयास किया, और यही मुझे result_stand से मिला है:

  • randombotfunc, 35
  • nashbotfunc, 333
  • greedyfunc, 172
  • antigreedyfunc, 491
  • themessengerfunc, 298
  • rockstarfunc, 200
  • statistician2func, 748
  • fitterfunc, 656
  • expectedbayesfunc, 601

जो बुरा नहीं है!

from sklearn.naive_bayes import MultinomialNB
import random

#Number of past moves used to compute the probability of next move
#I did not really try to make such thing as a cross-validation, so this number is purely random
n_data = 10

#Some useful data structures
choices = ['R','P','S']
choices_dic = {'R':0,'P':1,'S':2}
point_dic = {(0,0):0,(1,1):0,(2,2):0, #Same choices
             (0,1):-1,(0,2):1, #me = rock
             (1,0):1,(1,2):-1, #me = paper
             (2,0):-1,(2,1):1} #me = scissor

def compute_points(my_choice,opp_choice,my_load,opp_load):
    """
    Compute points
    @param my_choice My move as an integer
    @param opp_choice Opponent choice as an integer
    @param my_load my_load array
    @param opp_load opp_load array
    @return A signed integer (+ = points earned, - = points losed)
    """
    points = point_dic[(my_choice,opp_choice)] #Get -1, 0 or 1
    if points > 0:
        return points*my_load[my_choice] 
    else:
        return points*opp_load[opp_choice]

#This use to be a decision tree, before I changed it to something else. Nevertheless, I kept the name
class Decision_tree:
    def __init__(self):
        self.dataX = []
        self.dataY = []
        self.clf = MultinomialNB()

    def decide(self,my_load,opp_load,my_history,opp_history):
        """
        Returns the decision as an integer

        Done through a try (if a prediction could be made) except (if not possible)
        """
        try:
            #Let's try to predict the next move
            my_h = list(map(lambda x: choices_dic[x],my_history[-n_data:-1]))
            opp_h = list(map(lambda x: choices_dic[x],opp_history[-n_data:-1]))
            pred = self.clf.predict_proba([my_h+opp_h])
            #We create a points array where keys are the available choices
            pts = []
            for i in range(3):
                #We compute the expected gain/loss for each choice
                tmp = 0
                for j in range(3):
                    tmp += compute_points(i,j,my_load,opp_load)*pred[0][j]
                pts.append(tmp)
            return pts.index(max(pts)) #We return key for the highest expected value
        except:
            return random.choice(range(3))

    def append_data(self,my_history,opp_history):
        if my_history == "":
            self.clf = MultinomialNB()
        elif len(my_history) < n_data:
            pass
        else:
            my_h = list(map(lambda x: choices_dic[x],my_history[-n_data:-1]))
            opp_h = list(map(lambda x: choices_dic[x],opp_history[-n_data:-1]))
            self.dataX = self.dataX + [my_h+opp_h]
            self.dataY = self.dataY + [choices_dic[opp_history[-1:]]]

            if len(self.dataX) >= 10:
                self.clf.partial_fit(self.dataX,self.dataY,classes=[0,1,2])

                self.dataX = []
                self.dataY = []


#Once again, this is not actually a decision tree
dt = Decision_tree()

#There we go:
def expectedbayesfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    dt.append_data(my_history,opp_history)
    choice = choices[dt.decide(my_loaded,opp_loaded,my_history,opp_history)]
    return choice

PPCG में आपका स्वागत है, और अच्छी पहली पोस्ट!
ज़ाचारि

आपका बहुत बहुत धन्यवाद! मैं लंबे समय से पीपीसीजी में भाग लेना चाहता था। अब यह तय हो गया है!
lesibius

0

साइक्लर

def cycler(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    return "RPS"[len(myhistory)%3]

0


0

कलाकारों की टुकड़ी

from random import *
def f(I):
    if I==0:return "R"
    if I==1:return "P"
    return "S"
def b(I):
    if I=="R":return 0
    if I=="P":return 1
    return 2
def Ensemble(mp,op,ml,ol,mh,oh):
    A=[0]*3
    B=[0]*3
    if(len(oh)):
        k=b(oh[-1])
        A[k-2]+=0.84
        A[k]+=0.29
        for x in range(len(oh)):
            g=b(oh[x])
            B[g-2]+=0.82
            B[g]+=0.22
        s=sum(B)
        for x in range(len(B)):
            A[x]+=(B[x]*1.04/s)
        r=max(A)
    else:
        r=randint(0,3)
    return f(r)

कई प्रतिस्पर्धी एल्गोरिदम सबसे अच्छे समाधान पर मतदान करते हैं।

विनिमय

from random import *
def f(I):
    if I==0:return "R"
    if I==1:return "P"
    return "S"
def b(I):
    if I=="R":return 0
    if I=="P":return 1
    return 2
def Swap(mp,op,ml,ol,mh,oh):
    A=[0]*3
    B=[0]*3
    if(len(mh)):
        r=(b(mh[-1])+randint(1,2))%3
    else:
        r=randint(0,3)
    return f(r)

एक यादृच्छिक चाल है, लेकिन आखिरी चाल को दोहराए बिना यह किया।


0

blodsocer

socery

मैंने इसे ठीक कर दिया है, इसलिए इसे शायद अब काम करना चाहिए

मैंने फिर से कुछ गड़बड़ कर दिया, इसलिए मैंने हटा दिया और बिना मिटाया हुआ। मैं बहुत गड़बड़ कर रहा हूं।

def blodsocerfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    import random
    # tuned up an ready to go hopeful
    # s o c e r y
    if len(my_history) > 40 and len(set(opp_history[-30:])) == 1:
        if opp_history[-1] == "S":
            return "R"
        elif opp_history[-1] == "R":
            return "P"
        else:
            return "S"
        # against confused bots that only do one thing most of the time.
    elif len(my_history)>30 and min(opp_history.count(i) for i in "RPS")/max(opp_history.count(i) for i in "RPS") >0.8:
        return "RPS"[my_loaded.index(max(my_loaded))] # This is so if the other bot is acting errratic
                                                      # the max bonus is used for advantage
    elif len(my_history) < 10:
        if len(my_history) > 2 and all(i == "S" for i in opp_history[1:]):
            if len(my_history) > 5: return "S"
            return "P"
        return "S" # Be careful, because scissors are SHARP
    elif len(set(opp_history[1:10])) == 1 and len(my_history) < 20:
        if opp_history[1] == "S":
            return "R"
        elif opp_history[1] == "R":
            return "R"
        else:
            return "P"
    elif len(opp_history) -  max(opp_history.count(i) for i in "RPS") < 4 and len(my_history) < 30:
        if opp_history.count("R") > max(opp_history.count(i) for i in "PS"):
            return "P"
        if opp_history.count("P") > max(opp_history.count(i) for i in "RS"):
            return "S"
        if opp_history.count("S") > max(opp_history.count(i) for i in "RP"):
            return "R"
    elif len(my_history) < 15:
        if max(opp_loaded)<max(my_loaded):
            return "RPS"[len(my_history)%3]
        else:
            return "RPS"[(my_loaded.index(max(my_loaded))+len(my_history)%2)%3]
    elif len(my_history) == 15:
        if max(opp_loaded)<max(my_loaded):
            return "RPS"[(len(my_history)+1)%3]
        else:
            return "RPS"[(my_loaded.index(max(my_loaded))+ (len(my_history)%2)^1)%3]
    else:
        if max(opp_loaded)<max(my_loaded):
            return random.choice("RPS")
        else:
            return "RPS"[(my_loaded.index(max(my_loaded))+ (random.randint(0,1)))%3]

1
if opp_history[1] == "S": return "R" elif opp_history[1] == "R": return "R" else: return "P"यह किस प्रकार का समाज है?
रॉबर्ट फ्रेजर

@DestructibleLemon यह 0 से विभाजित होता है:elif min(opp_history.count(i) for i in "RPS")/max(opp_history.count(i) for i in "RPS") >0.8 and len(my_history)>30:
मैक्लिंस

@AlbertMasclans मैंने तय किया है।
विनाशकारी नींबू

@RobertFraser क्या वास्तव में उस कोड स्निपेट के बारे में बकाया है?
विनाशकारी नींबू

@DestructibleLemon मुझे पूरी तरह से यकीन नहीं है कि आप यहां क्या करना चाहते थे: "RPS"[my_loaded.index(max(my_loaded))+len(my_history)%2]लेकिन यह सीमा से बाहर लग रहा है (और आगे की लाइनें भी)।
मस्किन्स

0

भारहीन रैंडम

रैंडमबॉट की तरह, लेकिन यह हर बार फेंकने के लिए केवल 2 को चुनता है। कभी-कभी रॉकस्टार या हत्यारे को हरा देगा, लेकिन दूसरे के स्कोर को पंप करेगा (उदाहरण के लिए, यदि यह रॉकस्टार को हराता है, तो यह हत्यारे को एक बिंदु बढ़ावा देता है)।

import random

selection_set = ["R", "P", "S"]
selection_set.pop(random.randint(0,2))
def weightedrandombotfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    return random.choice(selection_set)

0

लालची मनोवैज्ञानिक

नाम दिया गया है कि क्योंकि यह लालची के लिए चूकता है, लेकिन अगर यह तय नहीं कर सकता है, तो यह इस बात पर भरोसा करता है कि अगर वे लालची रणनीति का इस्तेमाल करते हैं तो प्रतिद्वंद्वी जो भी करेगा। यदि यह अभी भी तय नहीं कर सकता है, तो यह अनियमित रूप से चला जाता है।

from random import choice

def greedypsychologistfunc(my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history):
    greedy = get_my_move(my_loaded)
    combined = list(set(greedy) & set(get_opp_counter(opp_loaded)))

    if len(combined) == 0:
        return choice(greedy)
    return choice(combined)

def get_indexes(lst, value):
    return [i for i,x in enumerate(lst) if x == value]

def get_my_move(my_loaded):
    return ["RPS"[i] for i in get_indexes(my_loaded, max(my_loaded))]

def get_opp_counter(opp_loaded):
    return ["PSR"[i] for i in get_indexes(opp_loaded, max(opp_loaded))]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.