Trong câu hỏi này , một trò chơi đã được nghĩ ra trong đó người chơi sẽ đối đầu với nhau theo từng cặp trong Thế lưỡng nan của tù nhân, để xác định chiến lược lặp nào đạt điểm cao nhất so với những người khác.
Trong câu hỏi này , tôi đã nghĩ ra một cách để nhiều người chơi tiến thoái lưỡng nan của tù nhân đối với nhau cùng một lúc. Trong biến thể này, ma trận xuất chi là không cần thiết, với mỗi kết quả giữa mỗi cặp hai người chơi là tổng của hai quyết định độc lập về chức năng.
Nhiệm vụ của bạn là xây dựng một AI để chơi phiên bản tổng quát, đối xứng này của Dilemma nhiều người chơi sẽ đạt được số điểm cao nhất có thể.
Nội quy của trò chơi
Trong mỗi vòng của trò chơi Dilemma nhiều người chơi, nhiều vòng này, một người chơi A
có thể quyết định "lấy 1" từ một số người chơi khác B
. Trong trường hợp này, A
điểm của tăng thêm 1, trong khi B
điểm của giảm xuống 2. Quyết định này được cho phép xảy ra giữa mỗi cặp người chơi được đặt hàng.
Đây là quyết định duy nhất được đưa ra cho mỗi người chơi - có thể "lấy 1" hoặc không "lấy 1" từ mỗi người chơi khác, tương đồng với sự đào tẩu và hợp tác tương ứng. Ma trận xuất chi hiệu quả giữa hai người chơi P1
và P2
trông như sau:
P1/P2 P1 Take1 P1 Don't
P2 Take1 -1/-1 -2/+1
P2 Don't +1/-2 0/ 0
Thủ tục thi đấu
Trò chơi sẽ bao gồm các P * 25
vòng, trong đó P
số lượng người chơi tham gia. Tất cả người chơi bắt đầu với một số điểm 0
. Mỗi vòng sẽ bao gồm các thủ tục sau đây:
Khi bắt đầu một vòng, mỗi chương trình sẽ được cung cấp lịch sử của các vòng trước từ đầu vào tiêu chuẩn , theo định dạng sau:
Một dòng chứa 3 số,
P
,D
, vàN
.P
là tổng số người chơi trong trò chơi. Mỗi người chơi được chỉ định ngẫu nhiên một số ID từ1
đếnP
đầu trò chơi.D
là ID của người chơi hiện tại.N
là số vòng đã được chơi.
N
dòng, mỗi dòng đại diện cho kết quả của một vòng. On linek
củaN
, sẽ có một số sốn_k
của cặp có thứ tự(a, b)
, cách nhau bằng khoảng trắng, trong đó tuyên bố rằng máy nghe nhạc với IDa
"mất 1" từ máy nghe nhạc với IDb
trong vòng đó.Một số ngẫu nhiên thống nhất
R
từ0
đến18446744073709551615
(2 64 - 1), để hoạt động như một hạt giống giả. Những con số này sẽ được đọc từ một tập tin được tạo trước, sẽ được phát hành vào cuối giải đấu để mọi người có thể tự xác minh kết quả.Một dòng bổ sung đại diện cho một số dạng trạng thái được đọc vào chương trình của bạn, nếu chương trình của bạn tạo ra đầu ra như vậy trong vòng trước. Khi bắt đầu trò chơi, dòng này sẽ luôn trống. Dòng này sẽ không được sửa đổi bởi mã điểm hoặc các chương trình khác.
Mỗi chương trình sau đó sẽ sử dụng chiến lược của mình để tạo ra các mục sau cho đầu ra tiêu chuẩn :
Một danh sách các
K
số, là ID của các chương trình mà nó sẽ "lấy 1" từ vòng này. Một đầu ra trống có nghĩa là nó sẽ không làm gì.Tùy chọn, một dòng bổ sung đại diện cho một số dạng trạng thái để chuyển sang các vòng sau. Dòng chính xác này sẽ được đưa trở lại chương trình trong vòng tiếp theo.
Dưới đây là một ví dụ đầu vào cho phần đầu của trò chơi dành cho người chơi ID 3
trong trò chơi 4 người:
4 3 0
4696634734863777023
Dưới đây là một ví dụ đầu vào cho cùng một trò chơi với một vài vòng đã chơi:
4 3 2
(1, 2) (1, 3) (1, 4) (4, 2)
(1, 3) (2, 1) (2, 4) (3, 1) (4, 1)
4675881156406346380
Mỗi chương trình sẽ được cung cấp chính xác cùng một đầu vào cho một vòng ngoại trừ số ID D
duy nhất cho mỗi chương trình.
Dưới đây là một ví dụ đầu ra trong đó người chơi 3
lấy 1 từ mọi người khác:
1 2 4
Kết thúc tất cả các vòng yêu cầu, người chơi có số điểm cuối cùng cao nhất sẽ là người chiến thắng.
Mốc thời gian
Việc mã hóa cho giải đấu này sẽ kéo dài tổng cộng 7 ngày. Thời hạn nộp là 2014-05-09 00:00 UTC
.
Không đăng các chương trình thực tế trước ngày này - đăng băm SHA256 của mã nguồn chương trình của bạn như một cam kết. Bạn có thể thay đổi hàm băm này bất cứ lúc nào trước thời hạn, nhưng các cam kết được đăng sau thời hạn sẽ không được chấp nhận để phán xét. (Vui lòng sử dụng ký hiệu cơ sở 64 cho băm của bạn, vì chương trình xác minh của tôi đã loại bỏ cơ sở 64 và đó là ký hiệu nhỏ gọn hơn.)
Sau khi thời hạn kết thúc, bạn sẽ có 1 ngày (cho đến khi 2014-05-10 00:00 UTC
) để đăng mã nguồn thực tế của chương trình để gửi. Nếu hàm băm SHA256 của mã nguồn được đăng của bạn không khớp với bất kỳ hàm băm nào bạn đã đăng trước thời hạn, mã của bạn sẽ không được chấp nhận vào giải đấu.
Sau này, tôi sẽ tải xuống tất cả các bài nộp vào máy tính của riêng tôi và chạy tất cả các mục tham gia giải đấu trong cuộc chiến này, hy vọng sẽ đăng kết quả trong vòng 2 ngày kể từ đó, bởi 2014-05-12 00:00 UTC
.
Tôi sẽ chấp nhận câu trả lời với số điểm cao nhất và trao phần thưởng +100 cho câu trả lời đó nếu điểm cuối cùng của nó lớn hơn 0
.
Sau khi giải đấu kết thúc, tôi sẽ đăng tệp hạt giống ngẫu nhiên được sử dụng để điều hành cuộc thi và mọi người có thể bắt đầu đăng các giải pháp khác để cố gắng đứng đầu các giải pháp được sử dụng trong giải đấu. Tuy nhiên, họ sẽ không được tính cho sự chấp nhận hoặc tiền thưởng.
Máy chủ
Tôi sẽ chạy các giải pháp này trên một máy ảo trên máy tính của tôi. Máy ảo này sẽ chạy Ubuntu Linux 14.04, với 2 GB RAM. Máy cơ sở của tôi có bộ xử lý Intel i7-2600K tốc độ 3,40 GHz.
Yêu cầu
Chương trình của bạn phải được viết bằng ngôn ngữ mà trình biên dịch hoặc trình thông dịch sẽ biên dịch chương trình của bạn tồn tại và có sẵn cho phiên bản Ubuntu Linux mới nhất, để tôi có thể chạy tất cả các bài nộp và đánh giá chúng trong một máy ảo.
Chương trình của bạn không được mất nhiều hơn 2.000 seconds
để chạy mỗi vòng. Nếu chương trình của bạn hết thời gian hoặc phát sinh lỗi, đầu ra của nó sẽ được coi là trống cho vòng đó.
Chương trình của bạn phải có tính quyết định; nghĩa là, nó phải luôn trả về cùng một đầu ra cho cùng một đầu vào. Giải pháp giả danh được cho phép; tuy nhiên, tính ngẫu nhiên của chúng phải phụ thuộc vào hạt giống ngẫu nhiên được cung cấp cho nó làm đầu vào và không có gì khác. Tệp hạt giống được tạo bằng Python os.urandom
. Nó chứa tổng cộng 500 dòng (sẽ được tạo nhiều hơn nếu cần thiết) và hàm băm SHA256 của nó là K+ics+sFq82lgiLanEnL/PABQKnn7rDAGmO48oiYxZk=
. Nó sẽ được tải lên ở đây khi giải đấu kết thúc.
Cây
Để bắt đầu, sẽ có bốn "nhà máy", đại diện cho các chiến lược ngây thơ ban đầu. Chúng sẽ được chơi trong giải đấu cùng với bài dự thi của bạn. Tuy nhiên, trong trường hợp không chắc là một trong số họ thắng, số điểm cao nhất mà người chơi không phải là nhà máy sẽ được coi là người chiến thắng.
Để tính toán hàm băm của mỗi tệp của nhà máy, hãy thay thế mỗi nhóm 4 khoảng trắng bằng một tab, vì trình định dạng ở đây dường như không thích các ký tự tab.
Người lười biếng - không bao giờ làm bất cứ điều gì.
n1bnYdeb/bNDBKASWGywTRa0Ne9hMAkal3AuVZJgovI=
pass
Greedy - luôn lấy 1 từ mọi người khác.
+k0L8NF27b8+Xf50quRaZFFuflZhZuTCQOR5t5b0nMI=
import sys
line1 = sys.stdin.readline()
n = [int(i) for i in line1.split()]
for i in range(n[0]):
if i+1 != n[1]:
print i+1,
print
The Wrathful - lấy 1 từ những người khác trong vòng đầu tiên và lấy 1 từ tất cả những người đã lấy 1 từ vòng trước đó sau đó.
Ya2dIv8TCh0zWzRfzUIdFKWj1DF9GXWhbq/uN7+CzrY=
import sys
import re
line1 = [int(i) for i in sys.stdin.readline().split()]
players = line1[0]
pid = line1[1]
rounds = line1[2]
lines = []
if rounds == 0:
for i in range(players):
if i+1 != pid:
print i+1,
print
else:
for i in range(rounds):
lines.append(sys.stdin.readline())
lastline = lines[-1]
takes = re.findall(r'\([0-9]+, [0-9]+\)', lastline)
for take in takes:
sides = [int(i) for i in re.findall(r'[0-9]+', take)]
if sides[1] == pid:
print sides[0],
print
The Eningly - lấy 1 trong số 50% người chơi có số điểm cao nhất hiện tại không bao gồm chính nó, làm tròn xuống.
YhLgqrz1Cm2pEcFlsiIL4b4MX9QiTxuIOBJF+wvukNk=
import sys
import re
line1 = [int(i) for i in sys.stdin.readline().split()]
players = line1[0]
pid = line1[1]
rounds = line1[2]
lines = []
scores = [0] * players
if rounds == 0:
for i in range(players):
if i+1 != pid:
print i+1,
print
else:
for i in range(rounds):
takes = re.findall(r'\([0-9]+, [0-9]+\)', sys.stdin.readline())
for take in takes:
sides = [int(i) for i in re.findall(r'[0-9]+', take)]
scores[sides[0] - 1] += 1
scores[sides[1] - 1] -= 2
score_pairs = [(i+1, scores[i]) for i in range(players)]
score_pairs.sort(key=lambda x:(x[1], x[0]))
score_pairs.reverse()
taken = 0
j = 0
while taken < (players) / 2:
if score_pairs[j][0] != pid:
print score_pairs[j][0],
taken += 1
j += 1
Trong một giải đấu gồm 100 vòng chỉ trong số bốn vòng này, họ nhận được số điểm:
Lazy: -204
Greedy: -100
Wrathful: -199
Envious: -199
Chương trình đánh giá
Tôi đã đăng chương trình thẩm phán mà tôi sẽ sử dụng tại Github . Tải về và kiểm tra nó. (Và có thể sửa một hoặc hai lỗi nếu bạn tìm thấy .: P)
Hiện tại nó không có tùy chọn biên dịch cho bất cứ thứ gì ngoài Python. Tôi sẽ bao gồm những người sau này - nếu mọi người có thể đóng góp các trình biên dịch hoặc biên dịch cho các ngôn ngữ khác, tôi sẽ có nhiều nghĩa vụ.
Giai đoạn 2: Gửi mã nguồn
Tôi đã đăng một chi nhánh mới tournament
lên kho lưu trữ Github cho cuộc thi, chứa tệp pd_rand và các mục nhập khác của nhà máy. Bạn có thể đăng mã nguồn của mình tại đây hoặc gửi nó đến chi nhánh đó dưới dạng yêu cầu kéo.
Thứ tự của các thí sinh sẽ như sau:
'begrudger'
'regular'
'patient'
'lazy'
'backstab'
'bully'
'lunatic'
'envious'
'titfortat'
'greedy'
'wrathful'
'judge'
'onepercent'
Điểm cuối cùng
Đầu ra của chương trình thử nghiệm của tôi:
Final scores:
begrudger -2862
regular -204
patient -994
lazy -2886
backstab -1311
bully -1393
lunatic -1539
envious -2448
titfortat -985
greedy -724
wrathful -1478
judge -365
onepercent -1921
Xếp hạng:
1. regular -204
2. judge -365
3. greedy -724
4. titfortat -985
5. patient -994
6. backstab -1311
7. bully -1393
8. wrathful -1478
9. lunatic -1539
10. onepercent -1921
11. envious -2448
12. begrudger -2862
13. lazy -2886
Vì vậy, hóa ra người chiến thắng thực sự là một người chơi - đó là Người thường xuyên, với -204 điểm!
Thật không may, điểm số của nó không tích cực, nhưng chúng ta khó có thể mong đợi rằng trong một mô phỏng của Thế lưỡng nan tù nhân lặp đi lặp lại nơi mọi người đang chơi để giành chiến thắng.
Một số kết quả đáng ngạc nhiên (ít nhất là tôi nghĩ là đáng ngạc nhiên):
Greedy ghi được nhiều hơn Tit cho Tat, và trên thực tế, nhìn chung cao hơn hầu hết những người ghi bàn.
Người phán xử, có nghĩa là một loại nhân vật "thực thi đạo đức" (về cơ bản, nó lấy 1 từ bất kỳ ai lấy 1 từ bất kỳ ai với số lần trên trung bình) đã kết thúc với số điểm khá cao, trong khi thử nghiệm mô phỏng, nó thực sự sẽ đạt điểm khá thấp.
Và những người khác (tôi nghĩ) không ngạc nhiên lắm:
The Patient ghi được 484 điểm nhiều hơn The Wrathful. Nó thực sự trả tiền để hợp tác lần đầu tiên.
Một phần trăm rất nhanh không có ai đá trong khi họ ngã xuống. Có vẻ như 1% chỉ có thể duy trì như vậy vì họ có nhiều người chơi hơn trong trò chơi.
Dù sao, bây giờ khi giải đấu kết thúc, vui lòng đăng thêm bao nhiêu người chơi tùy thích và thử nghiệm với họ bằng chương trình giám khảo.