KOTH - RPS đã tải


12

Cuộc thi mở vĩnh viễn - Cập nhật ngày 10 tháng 8 năm 2017

Mặc dù vào ngày 5 tháng 6 năm 2017, tôi đã tuyên bố một người chiến thắng (người sẽ được giữ là câu trả lời hay nhất) Tôi sẽ kiểm soát các bot mới và cập nhật kết quả.

Kết quả ngày 5 tháng 6

Xin chúc mừng người dùng1502040

Vì không có ràng buộc, tôi chỉ hiển thị% số trận thắng.

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- 40,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%

Tôi đã tạo một Trang tính Google với lưới kết quả của mỗi cặp: https://docs.google.com/s tràn tờ / d / 1KrMvcvWMkK-h1Ee50w0gWLh_L6rCFOgLhTN_QlEXHyk /edit? Usp = shaming


Nhờ có Petri Dilemma, tôi thấy mình có thể điều khiển vị Vua trên đồi này.

Tro choi

Trò chơi là một trò chơi "Rock-Paper-Kéo" đơn giản với một bước ngoặt: Điểm đạt được với mỗi lần tăng chiến thắng trong trận đấu (R, P hoặc S của bạn được tải).

  • Giấy thắng Rock
  • Kéo thắng giấy
  • Rock thắng Kéo

Người chiến thắng nhận được nhiều điểm như tải của mình vào trò chơi của mình.

Người thua cuộc tăng thêm 1 tải cho vở kịch của mình.

Trong trường hợp hòa, mỗi người chơi tăng tải cho lần chơi của mình thêm 0,5.

Sau 100 lượt chơi, người có nhiều điểm hơn là người chiến thắng.

ví dụ: P1 có tải [10,11,12] (Đá, Giấy, Kéo) và P2 [7,8,9]. P1 chơi R, P2 chơi P. P2 thắng và được 8 điểm. Tải P1 trở thành [11,11,12], tải P2 giữ nguyên.

Thông số kỹ thuật thử thách

Chương trình của bạn phải được viết bằng Python (xin lỗi, tôi không biết cách xử lý nó khác). Bạn phải tạo một hàm lấy từng biến này làm đối số cho mỗi lần thực hiện:

my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history

points - Điểm hiện tại (của bạn và opp của bạn)

loaded- Mảng có tải (theo thứ tự RPS) (của bạn và opp của bạn)

history- Chuỗi có tất cả các lần phát, nhân vật cuối cùng là lần chơi cuối cùng (của bạn và opp của bạn)

Bạn phải trở lại "R", "P"hoặc "S". Nếu bạn trả lại một cái gì đó khác nhau, nó sẽ tự động thua trận đấu.

Quy tắc

Bạn không thể thay đổi các chức năng tích hợp.

Kiểm tra

Tôi sẽ cập nhật Git với mã và tất cả các bot đang soạn thảo: https://github.com/Masclins/LoadedRPS

Đánh giá

Người chiến thắng sẽ được quyết định bằng cách chọn người có nhiều trận thắng nhất sau 1000 lượt đấu đầy đủ. Ties sẽ bị phá vỡ bởi các trận đấu gắn. 1000 trận đấu đang được chơi chứ không phải một vì tôi mong đợi rất nhiều sự ngẫu nhiên, và theo cách đó, sự ngẫu nhiên sẽ ít liên quan hơn.

Bạn có thể gửi tối đa 5 bot.

Cuộc thi kết thúc vào ngày 4 tháng 7 (đó sẽ là ngày cuối cùng tôi sẽ chấp nhận bất kỳ câu trả lời nào) và vào ngày 5 tháng 7, tôi sẽ đăng các bài viết cuối cùng (có thể cố gắng đăng một bài quảng cáo trước đó).


Vì đây là KOTH đầu tiên của tôi, tôi đã mở 100% để thay đổi bất cứ điều gì để cải thiện, chẳng hạn như số trận đấu được chơi với mỗi bot.

Đã chỉnh sửa tới 1000 trận đấu, vì tôi thấy thực sự có sự ngẫu nhiên liên quan.


với một số bot ngẫu nhiên, bạn thực sự muốn tạo ra nhiều trò chơi gồm nhiều vòng
Lemon

@DeststallibleLemon Tôi nghĩ về việc làm cho mỗi bot chơi ba lần với nhau thay vì một lần. Thấy bạn nghĩ tương tự, tôi sẽ làm như vậy.
Masclins

1
(thực sự bạn cần một số lượng khá lớn, vì một số xác suất thực sự kéo dài qua nhiều trận đấu. Xem bot của tôi, nơi nó có thể bị đánh bại, nhưng có thể sẽ không có số lượng trận đấu hợp lý)
Lemon

1
Tôi rất vui vì câu hỏi của tôi đã giúp bạn có thể chạy nó, @AlbertMasclans!
Gryphon

2
@AlbertMasclans Bạn có thể đăng bản kiểm tra đầy đủ (bao gồm runcodebots) không?
Máy

Câu trả lời:


8

Thống kê (không còn chơi)

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)]

Chuyển đổi giữa một vài chiến lược đơn giản dựa trên hiệu suất trong quá khứ dự kiến

Thống kê 2

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]

Nash

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]

Tính toán cân bằng Nash gần đúng theo độ dốc gốc.


1
Tôi thực sự thích cách tiếp cận này và có thể hiểu lý do tại sao bạn muốn có thể giữ trạng thái giữa các vòng. Mặc dù tôi thấy đó là một vấn đề lớn để thay đổi nó với số lượng bài nộp. Tôi sẽ tính đến điều đó cho những thách thức tiếp theo (mà tôi dự kiến ​​sẽ làm khi việc này kết thúc).
Masclins

5

Cân nặng hơn

Tôi đã mất khả năng suy luận trong khi thử nghiệm mã, nhưng ý tưởng cơ bản là ước tính xác suất di chuyển của đối thủ bằng 3 lần di chuyển cuối cùng bằng cách sử dụng một số trọng số và nhân chúng với một trọng số khác phụ thuộc vào tải. Tôi nghĩ rằng bằng cách nào đó tôi cũng có thể sử dụng my_loaded, nhưng tôi không thể quyết định làm thế nào, vì vậy hãy bỏ nó đi.

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))]

Sa-tan

Có lẽ sẽ bị loại, bởi vì đó là loại gian lận và nó đưa ra một số giả định về chức năng kiểm tra (nó phải có chức năng của đối thủ trong một biến trên khung ngăn xếp của nó), nhưng về mặt kỹ thuật không phá vỡ bất kỳ quy tắc hiện hành nào - nó không xác định lại hoặc viết lại bất cứ điều gì. Nó chỉ đơn giản là sử dụng ma thuật đen để thực thi chức năng của đối thủ để xem những gì họ đã làm / sẽ làm. Nó không thể đối phó với sự ngẫu nhiên, nhưng các bot xác định không có cơ hội đánh bại Satan.

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

Không còn nghi ngờ gì nữa, đây là kết quả tốt nhất về Đơn giản-Kết quả
Masclins

Nhân tiện, để sử dụng, my_loadedbạn có thể thêm trọng số đánh giá bước di chuyển sẽ mất so với (các) bước di chuyển cuối cùng của bạn. Điều đó giống như giả sử đối thủ của bạn sẽ làm điều gì đó tương tự như những gì bạn đã làm, và do đó trừng phạt anh ta vì cho rằng bạn sẽ tiếp tục chơi như vậy. Một cái gì đó như:for i, m in enumerate(reversed(my_history[-3:])): sc[(idx[m]+1)%3] += (K / (1 + i))
Masclins

@AlbertMasclans đã thêm một giải pháp khác
Tên hiển thị

1
Tôi thực sự thích Satan. Nhưng như bạn đã nói, tôi tin rằng nó không nên đủ điều kiện: Ngay cả khi nó không phá vỡ bất kỳ quy tắc rõ ràng nào, nó rõ ràng chống lại tinh thần của trò chơi. Tuy nhiên, xin chúc mừng ý tưởng của bạn!
Masclins

4

Fitter

Bot này cải thiện Mô hình và hợp nhất với Nhà kinh tế (Mô hình và Nhà kinh tế sẽ không còn tham gia)

Sự cải tiến của Mô hình là Bot hiện đang tìm kiếm hai loại mẫu: Đối thủ phản ứng với lần chơi cuối cùng của anh ta và đối thủ phản ứng với lần chơi cuối cùng của tôi. Sau đó đánh giá cả hai dự đoán để sử dụng dự đoán phù hợp nhất.

Từ mô hình đó, Bot hiện có xác suất cho R, P và S. Nếu tính đến điều đó và giá trị kỳ vọng của mỗi lần chơi (như Kinh tế học đã làm), Bot đóng vai trò mang lại giá trị cao nhất.

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]

Đây là hai mã cũ

Hoa văn (không còn chơi)

Mẫu cố gắng tìm các mẫu trên đối thủ của mình. Nó trông giống như những gì đối thủ đã chơi sau lần chơi cuối cùng mà anh ta đã làm (tăng thêm trọng lượng cho những lần chơi sau). Thông qua đó, nó đoán đối thủ sẽ chơi gì, và đóng vai trò đối trọng với điều đó.

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]

Nhà kinh tế (không còn chơi)

Nhà kinh tế thực hiện như sau: Đoán xác suất mỗi lần chơi của đối thủ bằng cách xem những gì anh ta đã chơi trong 9 lượt cuối cùng. Từ đó, tính toán lợi ích dự kiến ​​của mỗi lần chơi và đi với cái có giá trị mong đợi tốt nhất.

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

Cái này được đặt tên là "Yggdrasil" vì nó nhìn về phía trước trong cây trò chơi. Bot này không thực hiện bất kỳ dự đoán nào của đối thủ, nó chỉ đơn giản là cố gắng duy trì lợi thế thống kê nếu nó được đưa ra (bằng cách cân bằng lợi nhuận hiện tại và tương lai). Nó tính toán một chiến lược hỗn hợp xấp xỉ lý tưởng và trả về một nước đi được chọn ngẫu nhiên với các trọng số đó. Nếu bot này hoàn hảo (điều đó không phải, bởi vì chức năng định giá trạng thái khá tệ và nó không nhìn xa về phía trước), thì không thể đánh bại bot này hơn 50% thời gian. Tôi không biết bot này sẽ hoạt động tốt như thế nào trong thực tế.

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]})

vui lòng xóa các bình luận không làm cho mã dễ hiểu hơn
Tên hiển thị

@SUNDBorsch đã hoàn thành
PhiNotPi

1
@PhiNotPi Tôi biết rằng tôi đã đăng không giới hạn thời gian, nhưng Yggdrasil đang mất hơn một phút để chống lại mỗi đối thủ. Nó sẽ có thể tối ưu hóa nó một chút?
Masclins

vâng, nó chậm
Tên hiển thị

@AlbertMasclans theo phút cho mỗi đối thủ, ý bạn là tổng cộng 1 phút cho tất cả các trận đấu với đối thủ? Ngoài ra tôi có thể cố gắng tăng tốc nhưng tôi thực sự không biết làm thế nào, nó chỉ đi trước 1 bước.
PhiNotPi

4

Chống lặp

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"

Chọn giấy ở lượt đầu tiên, sau đó nó trả lại bất cứ thứ gì đánh bại những gì đối thủ đã làm nhiều nhất, chọn giấy trong trường hợp hòa.

Sao ché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]

Đơn giản chỉ cần sao chép các đối thủ di chuyển cuối cùng.

Chống tham lam

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"])

Chọn bất cứ điều gì thua cho sự lựa chọn nặng nề nhất của đối thủ.

Hơi đói

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

Người báo tin

def Themesbahfunc (I, do, not, need, These, argument): trả về "P"

Ngôi sao nhạc rock

def rockstarfunc (I, do, not, need, These, argument): return "R"

Kẻ ám sát

def assassinfunc (I, do, not, need, These, argument): return "S"

Giải trình

Bây giờ, bạn có thể nghĩ rằng những bot này hoàn toàn ngu ngốc.

không hoàn toàn đúng, những điều này thực sự dựa trên ý tưởng, tích lũy một khoản tiền thưởng khổng lồ, và kẻ thù đã làm sai và bị bao vây với nó.

Bây giờ, các bot này chơi rất giống với tham lam, tuy nhiên, chúng đơn giản hơn và không chọn ngẫu nhiên cho đến khi chúng tải một vũ khí, chúng gắn bó với vũ khí của chúng.

Một điều khác cần lưu ý: mỗi thứ sẽ đánh bại tham lam khoảng một nửa thời gian, rút ​​ra một phần ba thời gian và mất một phần sáu thời gian. Khi họ giành chiến thắng, họ sẽ có xu hướng chiến thắng rất nhiều. tại sao lại thế này

Tham lam, cho đến khi anh ta thua một vòng, sẽ ngẫu nhiên chọn một vũ khí. điều này có nghĩa là khi anh ta không giành chiến thắng trong một vòng, anh ta sẽ chọn một vũ khí một lần nữa, đó có thể là một lần nữa chiến thắng. nếu tham lam rút hoặc thua, anh ta sẽ dùng vũ khí đó. nếu tham lam thắng ít nhất một vòng, sau đó chọn vũ khí giống như bot, tham lam thắng. Nếu tham lam chọn vũ khí thua tại một số điểm, bot của chúng ta sẽ thắng, bởi vì tải trọng trên vũ khí của chúng ta sẽ cao hơn điểm số mà tham lam có được.

Giả sử tham lam không phải lúc nào cũng chọn vũ khí chiến thắng thông qua cơ hội lớn, điều này có nghĩa là cơ hội là:

1/3: {1/2 thắng (tổng 1/6). Mất 1/2 (tổng 1/6). }

Bốc thăm 1/3

Chiến thắng 1/3

vì vậy: 1/3 cơ hội hòa, 1/6 cơ hội thua, 1/2 cơ hội thắng.

điều này có thể cho thấy rằng bạn cần phải làm nhiều trò chơi nhiều vòng

chủ yếu là để vượt qua thử thách


3

Lò phản ứng

Làm cho vở kịch sẽ giành chiến thắng trong vòng trước.

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
Bạn có thể thay thế opp_history[len(opp_history)-1]bằng opp_history[-1].
Máy

3

Đứa trẻ nghệ thuật

Bot này hoạt động như một đứa trẻ chơi nghệ thuật và thủ công, sẽ bắt đầu bằng giấy và sử dụng giấy hoặc kéo ngẫu nhiên, nhưng sẽ không sử dụng kéo sau khi đá hoặc kéo vì cô ấy cần sử dụng kéo trên giấy. Sẽ ném đá lại bất cứ ai ném đá vào cô.

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

Ở đây có ba Bots tôi đã xây dựng để thử nghiệm:


RandomBot

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

Tham

Đơn giản chỉ cần chọn tùy chọn tải nhất của mình.

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"])

Phản đối

Giả sử đối thủ sẽ chơi tham lam và chơi thay thế chiến thắng.

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

Không đói

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"])

Đây thực sự là nghịch đảo của Greedy, nó chọn tùy chọn điểm thấp nhất có sẵn.


1

Sử dụng yêu thích của đối thủ

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"])

Đối với lượt đầu tiên, chọn một mục ngẫu nhiên. Đối với mỗi lượt khác, sử dụng lựa chọn phổ biến nhất của đối thủ. Nếu có một chiếc cà vạt, nó mặc định là lựa chọn phổ biến sớm nhất.

// Tôi đã đánh cắp mã từ đây


Chiến thắng là tốt

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"])

Trả về sự lựa chọn của người chiến thắng của vòng trước. Nếu vòng trước là hòa, kiểm tra đệ quy vòng trước đó. Nếu đó chỉ là mối quan hệ, hoặc đó là vòng đầu tiên, trả về một lựa chọn ngẫu nhiên.


1

Tốt nhất của cả hai thế giới

Bot này về cơ bản kết hợp Anti-Greedy và Greedy (do đó có tên).

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

Đây là Antigreedy, đã được đăng làm một ví dụ.
Masclins

@AlbertMasclans Thay đổi nó thành bot khác.
clismique

findlà cho chuỗi. my_loadedopp_loadedlà cả hai danh sách. indexnên tốt cho những gì bạn muốn
Masclins

@AlbertMasclans Rất tiếc, đã sửa bây giờ. Cảm ơn đã bắt! Tôi hy vọng đây không phải là một bản sao khác ... Tôi không muốn xóa bài đăng này một lần nữa.
clismique

Không sao, cảm ơn vì đã chơi
Masclins

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"

Chọn ngẫu nhiên giữa ba tùy chọn theo cách mà đối thủ thống kê không có sự ưu tiên giữa các lần di chuyển liên quan đến số điểm mà nó ghi được; nói cách khác, cả Greedy và Not Hungry nên có cùng số điểm dự kiến ​​trung bình so với nó.


1

Dự kiến

Chỉnh sửa: Xếp hạng cập nhật

Đây là thứ hạng hàng đầu mới sau khi bao gồm Expectedbayes:

  • thống kê2func 91,89%
  • fitterfunc 85,65%
  • nashfunc 80,40%
  • cân nặng 76,39%
  • dự kiến ​​73,33%
  • antirepeaterfunc 68,52%
  • ...

Giải thích

(NB: gửi ngày 05/06/2017)

Bot này cố gắng tối đa hóa giá trị dự kiến ​​của bước tiếp theo của nó bằng cách:

  • Tính toán xác suất cho mỗi lần di chuyển tiếp theo của đối thủ
  • Sử dụng hình đó và các tải để tính giá trị mong đợi cho mỗi R, P và S
  • Chọn di chuyển có giá trị mong đợi cao nhất
  • Chọn ngẫu nhiên một giá trị nếu dự đoán thất bại

Xác suất được cập nhật cứ sau mười lần di chuyển. Số lần di chuyển trong quá khứ được sử dụng để tính toán xác suất đã được đặt thành 10 cho mỗi bot (vì vậy 20 tính năng tổng thể). Điều này có thể là quá mức dữ liệu, nhưng tôi đã không cố kiểm tra thêm.

Nó dựa vào thư viện scikit để tính xác suất di chuyển của đối thủ (tôi đang nói trong trường hợp tôi đọc sai các quy tắc và thực tế nó không được phép).

Nó dễ dàng chiến thắng trước các bot luôn đưa ra lựa chọn tương tự. Đáng ngạc nhiên, nó khá hiệu quả so với bot ngẫu nhiên với tỷ lệ thắng 93% (tôi tin rằng điều này là do thực tế là nó giới hạn số điểm mà đối thủ của anh ta có thể nhận được trong khi tối đa hóa số điểm có thể có của mình cho mỗi vòng).

Tôi đã thử nhanh với 100 lượt và chỉ một số lượng bot giới hạn và đây là những gì tôi nhận được từ result_ Hiểu:

  • randombotfunc, 35
  • nashbotfunc, 333
  • tham lam, 172
  • chống tham lam, 491
  • chủ đề hành khách, 298
  • rockstarfunc, 200
  • thống kê2func, 748
  • fitterfunc, 656
  • dự kiến

Điều đó không tệ!

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

Chào mừng bạn đến với PPCG, và bài đăng đầu tiên tốt đẹp!
Zacharý

Cảm ơn rất nhiều! Tôi muốn tham gia PPCG trong một thời gian dài. Bây giờ nó đã được sửa!
lesibius

0

Cycler

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

0


0

Bộ quần áo

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)

Một số thuật toán cạnh tranh bỏ phiếu về giải pháp tốt nhất.

Trao đổi

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)

Có một động thái ngẫu nhiên, nhưng không lặp lại động tác cuối cùng nó đã làm.


0

blodsocer

xã hội

Tôi đã cho nó một bản sửa lỗi, vì vậy nó có thể sẽ hoạt động ngay bây giờ tôi hy vọng

Tôi đã làm hỏng một cái gì đó một lần nữa để tôi xóa và không bị xóa. Tôi đang làm cho rất nhiều lộn xộn.

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"đây là loại xã hội nào?
Robert Fraser

@DesturationibleLemon Điều này chia cho 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:
Masclins

@AlbertMasclans Tôi đã sửa nó.
Lemon phá hủy

@RobertFraser chính xác thì điều gì là nổi bật về đoạn mã đó?
Lemon phá hủy

@DeststallibleLemon Tôi không hoàn toàn chắc chắn những gì bạn muốn làm ở đây: "RPS"[my_loaded.index(max(my_loaded))+len(my_history)%2]nhưng nó nằm ngoài phạm vi (và các dòng tiếp theo cũng vậy).
Masclins

0

Trọng số ngẫu nhiên

Giống như RandomBot, nhưng nó chỉ chọn 2 để ném mỗi lần nó được gọi. Đôi khi sẽ đánh bại Rockstar hoặc Assassin, nhưng sẽ tăng điểm số của người khác (ví dụ: nếu đánh bại Rockstar, nó sẽ giúp Assassin tăng điểm).

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

Nhà tâm lý học tham lam

Được đặt tên là bởi vì nó mặc định là tham lam, nhưng nếu không thể quyết định, nó phản ánh bất cứ điều gì đối thủ sẽ làm nếu họ sử dụng chiến lược tham lam. Nếu nó vẫn không thể quyết định, nó sẽ đi ngẫu nhiên.

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))]
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.