KOTH: ทุกเหรียญมีสองด้าน


26

ผลลัพธ์สุดท้ายพร้อมใช้งาน

บทนำ

หลังจาก KOTH ฉันก่อนหน้านี้ที่มีรูปแบบหนัก ( สงครามแฟนตาซี , การแพร่ระบาดทั่วโลก ... ) ผมกลับมาพร้อมกับเกมในเฟซบุ๊คใหม่ เวลานี้คุณกำลังเผชิญหน้ากับสถานการณ์ "เหมือนเกมกระดาน" กองเหรียญคว่ำกลับถูกวางไว้ที่กลางโต๊ะใหญ่จริง ๆ และคุณตั้งใจที่จะรับส่วนแบ่งจากการปล้น!

อภิธานศัพท์

เหรียญ : เหรียญที่สามารถพลิกหรือไม่เปิดได้
Unflipped : เหรียญที่วางอยู่บนโต๊ะโดยมีค่าชี้ลง นี่คือสถานะเริ่มต้นของเหรียญ
พลิกแล้ว : เหรียญถูกวางไว้บนโต๊ะโดยมีค่าชี้ขึ้น
ในพื้นที่ : อ้างถึงกองเหรียญของคุณ
ทั่วโลก : หมายถึงกองเหรียญที่อยู่ตรงกลาง

หลัก

ในตอนเริ่มเกมผู้เล่นแต่ละคนจะเริ่มด้วย0 คะแนนและ0 เหรียญ (พลิกหรือไม่เปิด) เกมดังกล่าวเป็นแบบเลี้ยว ในช่วงเทิร์นของพวกเขาผู้เล่นสามารถดำเนินการได้ถึง 3 แอ็คชั่นที่มีปฏิสัมพันธ์กับกองเหรียญที่อยู่ตรงกลางโต๊ะกองเหรียญของตนเองหรือกับผู้เล่นอื่น

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

เกมดังกล่าวมีระยะเวลา50 รอบหรือจนกว่าจะมี0 เหรียญที่กึ่งกลางในตอนท้ายของการเปิดผู้เล่น (หมายความว่าคุณจะทำ 3 การกระทำของคุณให้เสร็จแม้ว่ากองจะว่างหลังจากการกระทำครั้งแรกของคุณและคุณสามารถนำเหรียญกลับมา เกมดำเนินต่อไป) จำนวนเริ่มต้นของเหรียญทั่วโลกถูกกำหนดแบบสุ่มด้วยสูตรนี้:

(2 ^ nb_players) + (nb_players * 10) - random(1 + (nb_players ^ 2))`

การกระทำแต่ละอย่างจะทำให้คุณได้รับคะแนน (หรือทำให้คุณแพ้) และในตอนท้ายของเกมเหรียญแต่ละอันที่คุณมีจะถูกเพิ่มเข้าไปในคะแนนของคุณ ( -1 สำหรับการเปิดไม่ได้ +2 สำหรับการพลิก ) ผู้เล่นที่มีคะแนนสูงสุดจะเป็นผู้ชนะ

คอนโทรลเลอร์จะให้อินพุตกับคุณผ่านอาร์กิวเมนต์ของคำสั่งและโปรแกรมของคุณจะต้องเอาต์พุตผ่าน stdout

วากยสัมพันธ์

อินพุต

แต่ละครั้งที่โปรแกรมของคุณถูกเรียกมันจะได้รับข้อโต้แย้งในรูปแบบนี้:

Round;YourPlayerId;Coins;PlayerId_Points_Flipped_Unflipped;PlayerId_Points_Flipped_Unflipped;...

การปัดเศษเป็น 1 การจัดทำดัชนี

ตัวอย่างอินพุต

6;2;52;1_20_3_12;0_-2_0_1;2_12_1_0

ที่นี่คุณจะเห็นว่ามันเป็นรอบที่ 6 และคุณเป็นผู้เล่น 2 มี 52 เหรียญในกองกลาง คุณมี 12 คะแนน, 1 เหรียญพลิกและ 0 เหรียญพลิก คะแนนอาจเป็นลบ

เอาท์พุต

คุณต้องส่งออกอักขระสามตัว (ไม่เว้นวรรคไม่มีตัวคั่น) ซึ่งแต่ละตัวสอดคล้องกับการกระทำหนึ่งที่คุณจะต้องทำ คำสั่งของตัวละครกำหนดลำดับของการกระทำ คุณสามารถแสดงผลการกระทำเดียวกันหลาย ๆ ครั้ง ในกรณีที่มีเหรียญไม่เพียงพอที่จะทำให้การกระทำของคุณเสร็จสมบูรณ์มันจะใช้เหรียญสูงสุดที่มีให้และนับแต้มเฉพาะเหรียญที่ใช้

N: ไม่ทำอะไรเลย
1: นำเหรียญ 1 กองจากกองกลาง[เอฟเฟ็กต์: + 1 จุดเปิด / -1 จุด / -1 ปลดล็อกทั่วโลก]
2 : นำ 2 เหรียญจากกองกลาง[เอฟเฟกต์: +2 จุดเปิด / -2 จุด / -2 โกลบอล unflipped]
3 : รับ 3 เหรียญจากกองกลาง[เอฟเฟกต์: +3 จุดที่ไม่ได้เปิดในระบบ / -3 แต้ม / -3 Global unflipped]
A : นำกลับมา 1 เหรียญจากกองของคุณ[เอฟเฟ็กต์: -1 จุดเปิด / +1 ท้องถิ่น / +1 โกลบอล unflipped]
B : ใส่กลับ 2 เหรียญจากกองของคุณ[เอฟเฟกต์: -2 unflipped ในพื้นที่ / +2 แต้ม / + 2 โกลบอล unflipped]
C : ใส่กลับ 3 เหรียญจากกองของคุณ[เอฟเฟกต์: -3 unflipped ในท้องถิ่น / +3 คะแนน / +3 การเปิดตัวทั่วโลก]
X : ลบ 1 เหรียญออกจากกองของคุณ[เอฟเฟ็กต์: -1 จุดเปิด / 0 จุด]
Y : ลบ 2 เหรียญออกจากกองของคุณ[เอฟเฟ็กต์: -2 จุดเปิด / 0 จุด]
Z : ลบ 3 เหรียญออกจากกองของคุณ[เอฟเฟ็กต์: -3 จุดเปิด / 0
Rหมุนท้องถิ่น] : หมุนเหรียญ ถึงผู้เล่นคนก่อน[เอฟเฟกต์: -1 จุดต่อการเปิดรับที่ได้รับ +2 คะแนนต่อการ
Tหมุนที่ได้รับ / นำไปใช้กับผู้เล่นทุกคน] : หมุนเหรียญไปยังผู้เล่นถัดไป[เอฟเฟ็กต์: -1 จุดต่อการรับที่ยังไม่ได้รับ ผู้เล่นทุกคน]
F : พลิก 1 เหรียญ[เอฟเฟกต์: -1 จุดเปิด / 1 จุดพลิกในท้องถิ่น +2 จุด]
U : ปลดล็อก 1 เหรียญ[เอฟเฟกต์: +1 จุดเปิด / -1 พลิกระดับท้องถิ่น / -2

ตัวอย่างผลลัพธ์

2FF : ใช้สองเหรียญและพลิกสองเหรียญทำคะแนน -2 + 2 + 2 = 2 points

NNNหากส่งออกของคุณไม่ถูกต้องควบคุมจะถือว่า

ตัวควบคุม

คุณสามารถค้นหาตัวควบคุมบนGitHub นอกจากนี้ยังมีบอตสองตัวอย่างที่เขียนด้วย Java ในการทำให้มันทำงานให้ตรวจสอบโครงการและเปิดใน Java IDE ของคุณ จุดเริ่มต้นในวิธีการของการเรียนmain Gameต้องใช้ Java 8

ในการเพิ่มบ็อตอันดับแรกคุณต้องใช้เวอร์ชันรวบรวมสำหรับ Java (ไฟล์. classclass) หรือแหล่งที่มาสำหรับภาษาที่ตีความ วางไว้ในโฟลเดอร์รูทของโครงการ จากนั้นสร้างคลาส Java ใหม่ในplayersแพ็คเกจ (คุณสามารถนำตัวอย่างบนบอตที่มีอยู่แล้ว) ชั้นนี้จะต้องดำเนินการเพื่อแทนที่วิธีPlayer String getCmd()String ที่ส่งคืนคือคำสั่ง shell เพื่อรันบ็อตของคุณ เช่นคุณสามารถทำให้การทำงานของ ธ return "C:\Ruby\bin\ruby.exe MyBot.rb";ปททับทิมด้วยคำสั่งนี้ ในที่สุดเพิ่ม bot ในอาร์เรย์ผู้เล่นที่ด้านบนของGameชั้นเรียน

กฎระเบียบ

  • ไม่ควรเขียนบอทเพื่อเอาชนะหรือสนับสนุนบอทอื่น ๆ โดยเฉพาะ
  • อนุญาตให้เขียนไฟล์ได้ โปรดเขียนถึง "yoursubmissionname.txt" โฟลเดอร์จะถูกทำให้ว่างเปล่าก่อนที่เกมจะเริ่ม ทรัพยากรภายนอกอื่น ๆ ไม่ได้รับอนุญาต
  • ข้อมูลที่คุณส่งมี 1 วินาทีเพื่อตอบสนอง
  • ให้คำสั่งเพื่อรวบรวมและเรียกใช้การส่งของคุณ

ภาษาที่รองรับ

ฉันจะพยายามและสนับสนุนทุกภาษา แต่จะต้องออนไลน์ให้ฟรี โปรดให้คำแนะนำสำหรับการติดตั้งหากคุณไม่ได้ใช้ภาษา "หลัก"

ณ ตอนนี้ฉันสามารถเรียกใช้: Java 6-7-8, PHP, Ruby, Perl, Python 2-3, Lua, R, node.js, Haskell, Kotlin, C ++ 11

ผลสุดท้าย

เหล่านี้คือผลลัพธ์ของเกม 100 เกม (มีการเพิ่มคะแนน):

1. BirdInTheHand: 1017790
2. Balance: 851428
3. SecondBest: 802316
4. Crook: 739080
5. Jim: 723440
6. Flipper: 613290
7. Wheeler: 585516
8. Oracle: 574916
9. SimpleBot: 543665
10. TraderBot: 538160
11. EgoisticalBot: 529567
12. RememberMe: 497513
13. PassiveBot: 494441
14. TheJanitor: 474069
15. GreedyRotation: 447057
16. Devil: 79212
17. Saboteur: 62240

ผลลัพธ์ส่วนบุคคลของเกมมีให้ที่นี่: http://pasted.co/63f1e924 (ด้วยเหรียญเริ่มต้นและจำนวนรอบต่อเกม)

โปรดปราน 50 ชื่อเสียงเป็นรางวัลให้กับผู้ชนะ: นกในมือโดยมาร์ตินBüttner

ขอบคุณทุกท่านที่มีส่วนร่วมพบกันต่อไป KOTH ~


1
" เอฟเฟ็กต์: -1 การเปิด / ปิดการ +1 โลคัล / +2 จุดพลิกเฉพาะที่ " ผิดปกติสำหรับฉัน ไม่ควรจะเป็นคะแนน +3 เพราะคุณไปจาก -1 สำหรับเหรียญที่ไม่ได้พลิกเป็น +2 สำหรับเหรียญที่พลิกหรือไม่
Peter Taylor

1
@ PeterTaylor ฉันคิดว่าคะแนนนั้นไม่ขึ้นกับเหรียญ การกระทำแต่ละอย่างเกี่ยวข้องกับจำนวนคะแนนที่ได้รับหรือสูญหายและสิ่งเหล่านี้เป็นอิสระจากคะแนนที่คุณได้รับสำหรับเหรียญในตอนท้ายของเกม
Martin Ender

คุณพูดถึงเหรียญที่มี "ค่า" ชี้ขึ้นหรือลง ค่าเหล่านี้ใช้ทำอะไร สามารถแยกเหรียญได้หรือไม่?
user2357112 รองรับ Monica

@PeterTaylor อย่างที่ Martin Büttnerพูดว่าคุณจะได้รับเหรียญสำหรับการกระทำ (ในกรณีนี้คือ +2 สำหรับการพลิก) และคุณยังได้รับคะแนนสำหรับการมีเหรียญในตอนท้าย (ในกรณีนี้คือ +2 สำหรับการโยนแต่ละครั้ง)
Thrax

ID เป็นแบบ zero-based หรือ one-based หรือไม่?
frederick

คำตอบ:


12

นกในมือทับทิม

def deep_copy(o)
  Marshal.load(Marshal.dump(o))
end

ID = 0
PTS = 1
FLP = 2
UFL = 3

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |i, p, f, u| i == id }

state = {
    round: round,
    id: id,
    global: global,
    players: players,
    my_pos: my_pos,
    me: players[my_pos],
    prev_p: players[my_pos-1],
    next_p: players[(my_pos+1)%nplayers],
    ends_game: round == 50 && my_pos == nplayers-1,
    score: 0
}

moves = {
    'N' => ->s{deep_copy(s)},
    '1' => ->s{t = deep_copy(s); coins = [1, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    '2' => ->s{t = deep_copy(s); coins = [2, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    '3' => ->s{t = deep_copy(s); coins = [3, t[:global]].min; t[:global] -= coins; t[:me][UFL] += coins; t[:score] -= coins; t},
    'A' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'B' => ->s{t = deep_copy(s); coins = [2, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'C' => ->s{t = deep_copy(s); coins = [3, t[:me][UFL]].min; t[:global] += coins; t[:me][UFL] -= coins; t[:score] += coins; t},
    'X' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'Y' => ->s{t = deep_copy(s); coins = [2, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'Z' => ->s{t = deep_copy(s); coins = [3, t[:me][UFL]].min; t[:me][UFL] -= coins; t},
    'F' => ->s{t = deep_copy(s); coins = [1, t[:me][UFL]].min; t[:me][UFL] -= coins; t[:me][FLP] += coins; t[:score] += 2*coins; t},
    'U' => ->s{t = deep_copy(s); coins = [1, t[:me][FLP]].min; t[:me][FLP] -= coins; t[:me][UFL] += coins; t[:score] -= 2*coins; t},
    'R' => ->s{
        t = deep_copy(s)
        (-1...t[:players].size-1).each do |i|
            t[:players][i][FLP] = s[:players][i+1][FLP]
            t[:players][i][UFL] = s[:players][i+1][UFL]
        end
        t[:score] += 2*t[:me][FLP] - t[:me][UFL];
        t
    },
    'T' => ->s{
        t = deep_copy(s)
        (0...t[:players].size).each do |i|
            t[:players][i][FLP] = s[:players][i-1][FLP]
            t[:players][i][UFL] = s[:players][i-1][UFL]
        end
        t[:score] += 2*t[:me][FLP] - t[:me][UFL];
        t
    }
}


results = {}

'N123ABCXYZFURT'.each_char { |c1| 
    s1 = moves[c1][state]
    'N123ABCXYZFURT'.each_char { |c2| 
        s2 = moves[c2][s1]
        'N123ABCXYZFURT'.each_char { |c3| 
            s3 = moves[c3][s2]
            s3[:ends_game] ||= s3[:global] == 0
            results[c1+c2+c3] = s3
        }
    }
}

endingMoves = results.keys.select{|k| results[k][:ends_game]}

endingMoves.each{|k| results[k][:score] += 2*results[k][:me][FLP] - results[k][:me][UFL]}

$> << results.keys.shuffle.max_by {|k| results[k][:score]}

หากเราไม่มีข้อผิดพลาดในโปรแกรมของพวกเขาอัลกอริทึมหลักของสิ่งนี้น่าจะคล้ายกับ Oracle ของ Mathias มาก ตามสมมติฐานที่ว่าก่อนรอบสุดท้ายเราไม่สามารถรู้ได้ว่าเราจะใช้เหรียญใดเราจะประเมินชุดการเคลื่อนไหวปัจจุบันตามจุดที่ได้รับทันทีโดยไม่สนใจเหรียญที่เราจะเรียงลำดับ กับ เนื่องจากมีเพียง14 3 = 2744ชุดการเคลื่อนไหวที่เป็นไปได้เราจึงสามารถจำลองพวกเขาทั้งหมดได้อย่างง่ายดายเพื่อหาว่ามีกี่คะแนนที่พวกเขาจะนำมา

อย่างไรก็ตามหากการย้ายชุดจบเกม (เพราะมันจะช่วยลด pot ทั่วโลกให้เป็นศูนย์หรือเพราะนี่คือรอบ 50 และเราเป็นคนสุดท้ายที่จะย้าย) ดังนั้นมันจึงคำนึงถึงเหรียญที่เป็นเจ้าของในตอนท้ายของ ชุดย้ายเพื่อกำหนดค่าของชุดย้าย ครั้งแรกที่ฉันคิดว่าจะยุติเกมเมื่อเป็นไปได้ แต่สิ่งนี้จะส่งผลให้เกิดการเคลื่อนไหวที่น่ากลัว333เมื่อมีเหลือเพียง 9 เหรียญในหม้อ

หากมีชุดการย้ายหลายชุดที่ให้ผลลัพธ์เดียวกันเราจะเลือกชุดการสุ่ม (ฉันอาจเปลี่ยนสิ่งนี้ให้มีอคติกับชุดเกมที่ยุติการเคลื่อนไหว)


17

Oracle, Python 3

อัปเดต: เปลี่ยนลำดับของการพยายามต่างๆเพื่อสนับสนุนกองต่ำของเหรียญในการหมุน

import sys
import itertools
from copy import deepcopy


MOVES_REQUIRED = 3

FLIPPED = 0
UNFLIPPED = 1


def filter_neighbors(neighbors, me, size):
    limit = size - MOVES_REQUIRED
    for data in neighbors:
        i, _, flipped, unflipped = map(int, data.split('_'))
        if MOVES_REQUIRED < (me - i) % size < limit:
            continue  # Skip neighbors that are too far away
        yield i, [flipped, unflipped]


class Player:
    def __init__(self, raw_data):
        _, me, coins, *data = raw_data.split(';')

        self.num_players = len(data)
        self._me = int(me)
        self._coins = int(coins)
        self._state = dict(filter_neighbors(data, self._me, self.num_players))

    def reset(self):
        self.me = self._me
        self.coins = self._coins
        self.state = deepcopy(self._state)
        self.my_state = self.state[self.me]

    def invalid_move(self, move):
        if move in 'NRT':
            return False

        if move in '123'[:self.coins]:
            return False

        flipped, unflipped = self.my_state
        if flipped and move == 'U':
            return False
        if unflipped and move == 'F':
            return False

        if move in 'AXBYCZ'[:2 * unflipped]:
            return False

        return True

    def N(self):
        return 0

    def one(self):
        self.coins -= 1
        self.my_state[UNFLIPPED] += 1
        return -1

    def two(self):
        self.coins -= 2
        self.my_state[UNFLIPPED] += 2
        return -2

    def three(self):
        self.coins -= 3
        self.my_state[UNFLIPPED] += 3
        return -3

    def A(self):
        self.coins += 1
        self.my_state[UNFLIPPED] -= 1
        return 1

    def B(self):
        self.coins += 2
        self.my_state[UNFLIPPED] -= 2
        return 2

    def C(self):
        self.coins += 3
        self.my_state[UNFLIPPED] -= 3
        return 3

    def X(self):
        self.my_state[UNFLIPPED] -= 1
        return 0

    def Y(self):
        self.my_state[UNFLIPPED] -= 2
        return 0

    def Z(self):
        self.my_state[UNFLIPPED] -= 3
        return 0

    def R(self):
        self.me = (self.me + 1) % self.num_players
        flipped, unflipped = self.my_state = self.state[self.me]
        return 2 * flipped - unflipped

    def T(self):
        self.me = (self.me - 1) % self.num_players
        flipped, unflipped = self.my_state = self.state[self.me]
        return 2 * flipped - unflipped

    def F(self):
        self.my_state[FLIPPED] += 1
        self.my_state[UNFLIPPED] -= 1
        return 2

    def U(self):
        self.my_state[FLIPPED] -= 1
        self.my_state[UNFLIPPED] += 1
        return -2

setattr(Player, '1', Player.one)
setattr(Player, '2', Player.two)
setattr(Player, '3', Player.three)


def scenarii(player):
    for tries in itertools.product('FUABCXYZ123NRT', repeat=MOVES_REQUIRED):
        player.reset()
        points = 0
        for try_ in tries:
            if player.invalid_move(try_):
                break
            points += getattr(player, try_)()
        else:
            yield points, ''.join(tries)


if __name__ == '__main__':
    player = Player(sys.argv[1])
    print(max(scenarii(player))[1])

พยายามเอาท์พุทที่เป็นไปได้ทุกครั้งและรักษาให้ได้คะแนนสูงสุดสำหรับเทิร์นนี้


อ๊ะฉันเพิ่งจะใช้สิ่งนี้ +1 :) (จริง ๆ แล้วฉันอาจจะยังเป็นเพราะฉันมีความคิดเล็ก ๆ น้อย ๆ หนึ่งหรือสองอย่างเพื่อปรับปรุงสิ่งนี้เล็กน้อย )
Martin Ender

@ MartinBüttnerฉันคิดว่าการปรับปรุงพื้นที่ (เช่นเวลา [ deepcopy]) มีความซับซ้อนโดยการรักษาเพื่อนบ้านที่เกี่ยวข้องเท่านั้น ไม่แน่ใจว่ามันจะส่งผลกระทบต่อสิ่งต่าง ๆ อย่างไร
409_Conflict

@Thrax ฉันแก้ไขข้อผิดพลาดในfilter_neighborsและแก้ไขinvalid_moveเพื่อบัญชีชี้แจงในคำถาม ฉันไม่สามารถทำซ้ำข้อผิดพลาด: $ python oracle.py '4;7;2040;8_-28_1_10;9_-43_0_9;2_-10_4_3;6_-24_6_3;0_6_2_12;1_48_3_0;10_21_4_8;5_6_5_1;4_-12_3_7;7_10_1_3;3_1_1_0'พิมพ์TTR
409_Conflict

7

การหมุนโลภ, ทับทิม

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |i, p, f, u| i == id }

prev_p = players[my_pos-1]
next_p = players[(my_pos+1)%nplayers]

prev_score = 2*prev_p[2] - prev_p[3]
next_score = 2*next_p[2] - next_p[3]

take_from = prev_p

$><< '3'
if prev_score > next_score || prev_score == next_score && prev_p[3] > next_p[3]
    $><< 'T'
else
    $><< 'R'
    take_from = next_p
end

if take_from[3] >= 3
    $><< 'C'
elsif take_from[3] >= 1
    $><< 'F'
else
    $><< 'N'
end

นี่ค่อนข้างคล้ายกับวิธีการของ ArtOfCode ยกเว้นว่าการตรวจสอบจากเพื่อนบ้านที่เราจะได้รับคะแนนมากขึ้นและมันเลือกCแทนFถ้าเราจบด้วย 3 เหรียญหรือมากกว่าหลังจากการหมุน

หลังจากเขียนสิ่งนี้ขึ้นมาฉันค่อนข้างแน่ใจว่าวิธีการที่ดีกว่านั้นคือการเลือกสิ่งที่ดีที่สุดของการเคลื่อนไหวทุกครั้งก่อนการหมุนโดยการใช้ถ้าเป็นไปได้ (แทนที่จะเป็นไปตามที่กำหนด จากรูปแบบ unflipped ")

สิ่งนี้ยังไม่ได้คำนึงถึงคะแนนโดยนัยที่แสดงโดยเหรียญที่เป็นเจ้าของจริง ๆ (ตามข้อสันนิษฐานว่าเกมจะดำเนินต่อไปจนถึงรอบสุดท้ายที่ฉันน่าจะไม่จบลงด้วยการรักษาเหรียญของฉันไว้)


@ MegaTom อ๊ะขอบคุณสำหรับการจับที่
Martin Ender

6

Flipper, Python 2

ฟลิปเปอร์รวบรวมเหรียญและพยายามที่จะพลิกเพื่อพลิก Flipper ไม่ได้เป็นผู้เล่นที่ฉลาด แต่พยายามที่จะเป็นแรงบวกในเกม

import sys, random

# process input data (not used here):
args = sys.argv[1].split(';')
rounds, myid, coins = map(int, args[:3])
players = [map(int, data.split('_')) for data in args[3:]]

# implement strategy using multiples of 'N123ABCXYZRTFU':
options = '12333FFFFFFFFFFF'
print ''.join(random.choice(options) for i in range(3))

ฟลิปเปอร์แค่ต้องการpython flipper.py <arg>วิ่ง


5

SimpleBot, Python 3

SimpleBot ง่ายดี เขาใช้กลยุทธ์เดียวและเขาจะทำตามมัน

วิ่ง:

python3 main.py

ที่เนื้อหาของmain.pyไฟล์คือ:

def main():
    print("3RF")


if __name__ == "__main__":
    main()

5

ยอดคงเหลือ Lua

ยอดคงเหลือจะพยายามรักษาสมดุลในโทเค็นของมันลดการสูญเสียในกรณีที่มีคนใช้RและTดำเนินการกับเขา เขาคิดว่ารูปแบบของชีวิตนี้เป็นสิ่งที่แท้จริงและควรบังคับใช้กับทุกคนที่ไม่ได้รักษาสมดุลของเหรียญที่พลิก / ไม่เปิดดังนั้นทุกคนที่อยู่ใกล้เขาจะถูกลงโทษทันทีที่สามารถทำให้พวกเขาเสียคะแนน

เขาต้องการคำสั่งต่อไปนี้เพื่อเรียกใช้:

lua balance.lua

โดยที่ไฟล์ balance.lua มีรหัสต่อไปนี้

local datas={}
local arg=arg[1]..";"

-- parse the arguments
-- add some meta datas for debuging purpose/usefulness
arg:gsub("(.-);",function(c)
  if not datas.round
  then
    datas.round=c+0
  elseif not datas.myID
  then
    datas.myID=c+0
  elseif not datas.coins
  then
    datas.coins=c+0
  else
    datas[#datas+1]={}
    datas[#datas].repr=c
    c=c.."_"
    tmp={}
    c:gsub("(.-)_",function(d) tmp[#tmp+1]=d end)
    datas[#datas].id=tmp[1]+0
    datas[#datas].points=tmp[2]+0
    datas[#datas].flip=tmp[3]+0
    datas[#datas].unflip=tmp[4]+0
    if datas[#datas].id==datas.myID
    then
      datas.myOrder=#datas
      datas.myDatas=datas[#datas]
    end
  end
end)

local actions=""
-- construct actions
for i=1,3
do
  -- if we aren't in balance and can grab more coins
  -- we do it
  if #actions==0 and datas.myDatas.unflip<=datas.myDatas.flip/2 and datas.coins>=3
  then
    actions=actions.."3"
    datas.myDatas.unflip=datas.myDatas.unflip+3
    datas.coins=datas.coins-3
  -- if we couldn't grab coins, but aren't in balance, we flip some coins
  elseif datas.myDatas.unflip>datas.myDatas.flip/2
  then
    actions=actions.."F"
    datas.myDatas.unflip=datas.myDatas.unflip-1
    datas.myDatas.flip=datas.myDatas.flip+1

  -- if we didn't have anything to do on our pile, let's punish
  -- the fools who doesn't follow the great Balance principle
  else
    previous=datas.myOrder<2 and #datas or datas.myOrder-1
    following=datas.myOrder>=#datas and 1 or datas.myOrder+1

    lossPrev=-datas[previous].flip + 2*datas[previous].unflip
    lossFoll=-datas[following].flip+ 2*datas[following].unflip
    if lossFoll>0 and lossPrev>0
    then
      actions =actions.."N"
    elseif lossFoll>=lossPrev
    then
      actions=actions.."T"
      datas[following].unflip,datas[following].flip=datas[following].flip,datas[following].unflip
    else
      actions=actions.."R"
      datas[previous].unflip,datas[previous].flip=datas[previous].flip,datas[previous].unflip
    end
  end
end
print(actions)

@ Thrax ขอบคุณคงที่ ลืมทำงานกับค่าที่มีการจัดทำดัชนี 1 รายการสำหรับบรรทัดนี้ ...
Katenkyo

4

ภารโรง, Python 3

เขาพยายามที่จะทำความสะอาดความยุ่งเหยิงที่ผู้เล่นคนอื่นทำด้วยเหรียญเหล่านี้และนำพวกเขากลับไปที่สระ

import sys;
def Parse(S):
    T = S.split(';');
    me = eval(T[1]);
    N = len(T)-3;
    A = list(map(lambda x: list(map(lambda y:int(y),T[3+((2*N+x+me)%N)].split('_'))),range(-3,4)));    
    Dic = {}
    for a in A:
        Dic[a[0]] = a[1:];
    Dic[-1] = [me];
    return Dic;
def Recursive(Dic,me,D):
    if D==3: return '';
    V = Dic[me];
    N = max(Dic.keys());
    Next = (me+1)%N;
    Prev = (N+1+me)%N;
    for i in range(3,0,-1):
        if V[2]>=i:
            Dic[me][2] = Dic[me][2]-i;
            return chr((i-1)+ord('A'))+Recursive(Dic,me,D+1);
    if V[1]>0:
        Dic[me][1] = Dic[me][1]-1;
        Dic[me][2] = Dic[me][2]+1;
        return 'U'+Recursive(Dic,me,D+1);
    if Dic[Next][2]>Dic[Prev][2]:
        return 'T'+Recursive(Dic,Next,D+1);
    return 'R'+Recursive(Dic,Prev,D+1);
Dic = Parse(sys.argv[1]);
me = Dic[-1][0];
print(Recursive(Dic,me,0));

เขาพยายามที่จะคืนเหรียญที่ยังไม่ได้เปิดทั้งหมดของเขาถ้าเขามีเหรียญที่พลิกอยู่ติดอยู่เขาจะปลดเหรียญเหล่านั้นและถ้าเขากำจัดเหรียญทั้งหมดเขาจะได้คนอื่น


3

คด

args <- strsplit(commandArgs(TRUE),";")[[1]]
state <- as.data.frame(do.call(rbind,strsplit(args[-(1:3)],"_")), stringsAsFactors=FALSE)
colnames(state) <- c("id","pts","flipped","unflipped")
state$flipped <- as.integer(state$flipped)
state$unflipped <- as.integer(state$unflipped)
nb <- nrow(state)
score <- function(place) 2*state$flipped[place]-state$unflipped[place]
my_place <- which(state$id==args[2])
next_1 <- ifelse(my_place!=nb,my_place+1,1)
next_2 <- ifelse(next_1!=nb,next_1+1,1)
next_3 <- ifelse(next_2!=nb,next_2+1,1)
previous_1 <- ifelse(my_place!=1,my_place-1,nb)
previous_2 <- ifelse(previous_1!=1,previous_1-1,nb)
previous_3 <- ifelse(previous_2!=1,previous_2-1,nb)
n <- 3
out <- c()
while(n){
    M <- N <- score(my_place)
    R <- switch(n,"1"=score(next_1),
                "2"=cumsum(c(score(next_1),score(next_2))),
                "3"=cumsum(c(score(next_1),score(next_2),score(next_3))))
    P <- switch(n,"1"=score(previous_1),
                "2"=cumsum(c(score(previous_1),score(previous_2))),
                "3"=cumsum(c(score(previous_1),score(previous_2),score(previous_3))))
    M <- c(M,M+R[-n])
    N <- c(N,N+P[-n])
    if(any(R>M & R>0)){
        action <- c("R","RR","RRR")[which.max(R-M)]
        out <- c(out, action)
        state[,3:4] <- state[c((nchar(action)+1):nb,seq_len(nchar(action))),3:4]
        n <- n-nchar(action)
    }else if(any(P>N & P>0)){
        action <- c("T","TT","TTT")[which.max(P-N)]
        out <- c(out, action)
        state[,3:4] <- state[c((nb+1-seq_len(nchar(action))),1:(nb-seq_len(nchar(action)))),3:4]
        n <- n-nchar(action)
    }else if(n>1 & all(R[1]+M[1]>c(0,P[1]+M[1],R[1]+R[2]))){
        out <- c(out,"RT")
        n <- n-2
    }else if(n>1 & all(P[1]+M[1]>c(0,R[1]+M[1],P[1]+P[2]))){
        out <- c(out,"TR")
        n <- n-2
    }else{
        out <- c(out, switch(n,"1"="A","2"="1F","3"="2FF"))
        n <- 0
        }
    }
cat(paste(out,collapse=""))

วิ่ง: Rscript Crook.R

โดยพื้นฐานแล้วมันจะแลกเปลี่ยนเหรียญกับเพื่อนบ้านเมื่อการแลกเปลี่ยนนั้นไม่เท่าเทียมกัน หากไม่มีการแลกเปลี่ยนที่เป็นประโยชน์เป็นไปได้ก็จะแลกเปลี่ยนเหรียญกับกองทั่วโลกในลักษณะที่รักษาอัตราส่วนไว้ แต่สร้างบางจุด

แก้ไข:ฉันเพิ่มความลึกลงไปในบ็อตนี้ด้วยการทำให้มันตรวจสอบสแต็คผู้เล่น 2 และ 3 คนถัดไปแทนที่จะเป็นคนถัดไป

2nd แก้ไข : ตามความคิดของ @ MartinBüttnerตอนนี้ bot ทำการ "RT" หรือ "TR" ถ้ามันจะเป็นประโยชน์สำหรับเขามากกว่าเพื่อนบ้าน (ถ้าฉันไม่ได้ยุ่งกับการนำมันไปใช้ :))


การแก้ไขของคุณอีกครั้ง: หากคนที่อยู่ถัดจากคุณมีเหรียญพลิกเป็นจำนวนมากมันอาจเป็นการดีที่สุดถ้าRTRคุณได้คะแนนจากเหรียญของเขาสองครั้ง
Martin Ender

จริง แม้ว่ามันจะให้หนึ่งในเพื่อนบ้านที่ทำคะแนนครั้งเดียว แต่ฉันจะคิดเกี่ยวกับมันแน่นอนมันเป็นความคิดที่แน่นอนในการสำรวจ
plannapus

@ MartinBüttnerตกลงในที่สุดฉันก็พบวิธีที่จะใช้มันในขณะที่รักษาวิญญาณของบอท ขอบคุณสำหรับคำแนะนำ!
plannapus

@thrax เพียงเพื่อที่คุณจะไม่ลืมที่จะอัพเดทบอทของฉันเมื่อใช้งานเกมถัดไปฉันคิดว่าฉันควรเตือนคุณว่าเวอร์ชัน bot ของฉันใน repo github ของคุณนั้นเก่า
plannapus

3

จิมทับทิม

ขึ้นอยู่กับมาร์ตินBüttnerของโลภหมุน

PlayerId = 0
Points = 1
Flipped = 2
Unflipped = 3

round, id, global, *players = ARGV[0].split(';')
round = round.to_i
id = id.to_i
global = global.to_i

if(round == 1)
    print '3FF'
    exit
end

players.map!{ |s| s.split('_').map(&:to_i) }

nplayers = players.size

my_pos = players.find_index { |a| a[PlayerId] == id }

coin_vals = players.map{|a| a[Flipped]*2 - a[Unflipped]}

move = [-1,1].max_by{|s|
    swap_gain = coin_vals.rotate(s)
    scores = (0...nplayers).map{|i|
        swap_gain[i]+players[i][Points]
    }
    scores.delete_at(my_pos)-scores.max
}
if move == 1
    print 'R'
else
    print 'T'
end

print ['1F', 'FF'][rand 2]

จะหมุนทางเดียวหรืออื่น ๆ ขึ้นอยู่กับสิ่งที่จะให้คะแนนมากที่สุดเมื่อเทียบกับผู้เล่นอื่นที่ดีที่สุด จากนั้นเขาพลิกเป็นเงินสดได้อย่างรวดเร็ว


2

TraderBot

บอทนี้พยายามหมุนเมื่อใดก็ตามที่เป็นจุดที่มีแต้มมากที่สุดในการกระทำนั้น หากไม่สามารถหมุนได้ให้พยายามกำจัดเหรียญที่ไม่ได้พลิกหรือใช้เวลาเพิ่มอีกสองสามครั้งในการเปลี่ยนในการกระทำดังต่อไปนี้

import java.util.ArrayList;

นำเข้า java.util.List;

ชั้นสาธารณะ TraderBot {

class Player{
    private int id;
    private int points;
    private int flip;
    private int unflip;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getFlip() {
        return flip;
    }
    public void setFlip(int flip) {
        this.flip = flip;
    }
    public int getUnflip() {
        return unflip;
    }
    public void setUnflip(int unflip) {
        this.unflip = unflip;
    }


}

int round;
int coins;
int otherMaxPoints = 0;
Player myself = new Player();
List<Player> players = new ArrayList<>();

public static void main (String[] s){
    new TraderBot().play(s);
}

private void play(String[] s){
    parse(s[0]);
    System.out.println(action() + action() + action());
}

private int simRotateNext(){
    int flip, unflip;
    int maxP = Integer.MIN_VALUE;
    int myP = 0;
    for (int i = 0; i < players.size(); i++){
        flip = players.get(i).getFlip();
        unflip = players.get(i).getUnflip();
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        int p = 2 * flip - unflip;
        if (p > maxP && players.get(next).getId() != myself.getId()){
            maxP = p;
        } else if (players.get(next).getId() == myself.getId()){
            myP = p;
        }

    }
    return  myP - maxP;
}

private int simRotatePrev(){
    int flip, unflip;
    int maxP = Integer.MIN_VALUE;
    int myP = 0;
    for (int i = players.size() -1; i > 0; i--){
        flip = players.get(i).getFlip();
        unflip = players.get(i).getUnflip();
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        int p = 2 * flip - unflip;
        if (p > maxP && players.get(prev).getId() != myself.getId()){
            maxP = p;
        } else if (players.get(prev).getId() == myself.getId()){
            myP = p;
        }
    }
    return  myP - maxP;
}

private int rotateNext(){
    int flip, unflip, nflip, nunflip;
    flip = players.get(0).getFlip();
    unflip = players.get(0).getUnflip();
    for (int i = 0; i < players.size(); i++){
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        nflip = players.get(next).getFlip();
        nunflip = players.get(next).getUnflip();
        players.get(next).setFlip(flip);
        players.get(next).setUnflip(unflip);
        players.get(next).setPoints(players.get(next).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private int rotatePrev(){
    int flip, unflip,  nflip, nunflip;
    flip = players.get(players.size() -1).getFlip();
    unflip = players.get(players.size() -1).getUnflip();
    for (int i = players.size() -1; i > 0; i--){
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        nflip = players.get(prev).getFlip();
        nunflip = players.get(prev).getUnflip();
        players.get(prev).setFlip(flip);
        players.get(prev).setUnflip(unflip);
        players.get(prev).setPoints(players.get(prev).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private String action() {
    int next = simRotateNext();
    int prev = simRotatePrev();

    if (next > 0 || prev > 0){
        if (next > prev){
            rotateNext();
            return "T";
        } else {
            rotatePrev();
            return "R";
        }
    }

    if (myself.getUnflip() > 3){
        myself.unflip -= 3;
        myself.points += 3;
        return "C";
    }

    if (myself.getUnflip() > 0){
        myself.unflip -= 1;
        myself.points += 2;
        return "F";
    }

    if (myself.getPoints() > otherMaxPoints){
        return "N";
    } else {
        myself.unflip += 3;
        myself.points -= 3;
        return "3";
    }

}

private void parse(String s){
    String[] ps = s.split(";");
    round = Integer.parseInt(ps[0]);
    myself.setId(Integer.parseInt(ps[1]));
    coins = round = Integer.parseInt(ps[2]);
    for (int i = 3; i < ps.length; i++){
        String[] sp2 = ps[i].split("_");
        if (Integer.parseInt(sp2[0]) == myself.getId()){
            myself.setPoints(Integer.parseInt(sp2[1]));
            myself.setFlip(Integer.parseInt(sp2[2]));
            myself.setUnflip(Integer.parseInt(sp2[3]));
            players.add(myself);
        } else {
            Player p = new Player();
            p.setId(Integer.parseInt(sp2[0]));
            p.setPoints(Integer.parseInt(sp2[1]));
            p.setFlip(Integer.parseInt(sp2[2]));
            p.setUnflip(Integer.parseInt(sp2[3]));
            players.add(p);
            if (p.getPoints() > otherMaxPoints){
                otherMaxPoints = p.getPoints();
            }
        }
    }
}
}

วิธีเรียกใช้: เพียงเพิ่มลงในโฟลเดอร์เดียวกับบ็อตเริ่มต้นจากนั้นสร้างคลาสต่อไปนี้

package players;

import controller.Player;

public class TraderBot extends Player {

    @Override
    public String getCmd() {
        return "java TraderBot";
    }   
}

จากนั้นเพิ่มคลาสนั้นลงในPlayer[] playersอาร์เรย์


2

ล้อ

Wheeler คำนวณการเคลื่อนที่ที่ดีที่สุดเท่าที่จะเป็นไปได้เมื่อหมุนเหรียญ

import java.util.ArrayList;
import java.util.List;

public class Wheeler {

String[] actions = {"TTT", "TTR", "TRR", "TRT", "RRR", "RRT", "RTR", "RTT"};
String paramString;

class Player{
    private int id;
    private int points;
    private int flip;
    private int unflip;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public int getFlip() {
        return flip;
    }
    public void setFlip(int flip) {
        this.flip = flip;
    }
    public int getUnflip() {
        return unflip;
    }
    public void setUnflip(int unflip) {
        this.unflip = unflip;
    }
    @Override
    public String toString() {
        return "Player [id=" + id + ", points=" + points + ", flip=" + flip + ", unflip=" + unflip + "]";
    }




}

int round;
int coins;
int otherMaxPoints = 0;
Player myself = new Player();
List<Player> players = new ArrayList<>();

public static void main (String[] s){
    new Wheeler().play(s);
}

private void play(String[] s){
    paramString = s[0];
    reset();
    System.out.println(action());
}

private int rotateNext(){
    int flip, unflip, nflip, nunflip;
    flip = players.get(0).getFlip();
    unflip = players.get(0).getUnflip();
    for (int i = 0; i < players.size(); i++){
        int next = i + 1 <= players.size() - 1 ? i + 1 : 0;
        nflip = players.get(next).getFlip();
        nunflip = players.get(next).getUnflip();
        players.get(next).setFlip(flip);
        players.get(next).setUnflip(unflip);
        players.get(next).setPoints(players.get(next).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private int rotatePrev(){
    int flip, unflip,  nflip, nunflip;
    flip = players.get(players.size() -1).getFlip();
    unflip = players.get(players.size() -1).getUnflip();
    for (int i = players.size() -1; i > 0; i--){
        int prev = i - 1 >= 0 ? i - 1 : players.size() - 1;
        nflip = players.get(prev).getFlip();
        nunflip = players.get(prev).getUnflip();
        players.get(prev).setFlip(flip);
        players.get(prev).setUnflip(unflip);
        players.get(prev).setPoints(players.get(prev).getPoints() + 2 * flip - unflip);
        flip = nflip;
        unflip = nunflip;
    }
    return myself.getPoints();
}

private String action() {
    int maxPoints = myself.getPoints();
    String action = "1F2";
    for (String s : actions){
        int cPoints = 0;
        for (char c : s.toCharArray()){
            if (c == 'T'){
                cPoints += rotateNext();
            } else {
                cPoints += rotatePrev();
            }
        }
        if (cPoints > maxPoints){
            action = s;
        }
        reset();
    }
    return action;      
}


private void reset(){
    players = new ArrayList<>();
    String[] ps = paramString.split(";");
    round = Integer.parseInt(ps[0]);
    myself.setId(Integer.parseInt(ps[1]));
    coins = round = Integer.parseInt(ps[2]);
    for (int i = 3; i < ps.length; i++){
        String[] sp2 = ps[i].split("_");
        if (Integer.parseInt(sp2[0]) == myself.getId()){
            myself.setPoints(Integer.parseInt(sp2[1]));
            myself.setFlip(Integer.parseInt(sp2[2]));
            myself.setUnflip(Integer.parseInt(sp2[3]));
            players.add(myself);
        } else {
            Player p = new Player();
            p.setId(Integer.parseInt(sp2[0]));
            p.setPoints(Integer.parseInt(sp2[1]));
            p.setFlip(Integer.parseInt(sp2[2]));
            p.setUnflip(Integer.parseInt(sp2[3]));
            players.add(p);
            if (p.getPoints() > otherMaxPoints){
                otherMaxPoints = p.getPoints();
            }
        }
    }
}

}

2

ผู้ก่อวินาศกรรม Python 2

import random
moves = '3R'
print '33' + ''.join(random.choice(moves))

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


สิ่งที่คนคนนี้ทำมากที่สุดคือกองเหรียญ รวมถึงให้คะแนนตัวเองกับคนอื่น ๆ
MegaTom

@ MegaTom ใช่ฉันคิดว่ามันจะเป็นผลข้างเคียงฉันชอบเคลือบสูตรสำหรับเหรียญทั้งหมดที่ฉันเดา ฉันสามารถทำให้มันเป็นตัวเลขสุ่ม และในจุดลบการให้คะแนนด้านลบกับคนอื่น ๆ เป็นอีกวิธีหนึ่งในการชนะ!
Neal

คุณไม่จำเป็นต้องนำเข้า sys : P
cat

2

SecondBest, Python 3

โปรแกรมนี้จะผ่านการผสม 3 แบบที่เป็นไปได้ทั้งหมดและเลือกอันที่ดีที่สุดอันดับสอง

เพราะถ้าคุณมีท่าที่สมบูรณ์แบบมันอาจเป็นกับดัก

แก้ไข: ลบอินพุตที่ใส่ความคิดเห็นออก

import sys
from copy import deepcopy
from random import randint
In=str(sys.argv[1])
def V(n,f=10,t=14):
 n=str(n);z=0;s='';d='0123456789';d1='N123ABCXYZRTFU'
 for i in n:z=z*f+d.index(i)
 while z:z,m=divmod(z,t);s=d1[m]+s
 while len(s)<3:s='N'+s
 return s
In=In.split(';')
number=In[0:3]
players=In[3:]
for x in range(0,len(players)):players[x]=players[x].split('_')
for x in players:
 if number[1] in x[0]:self=x
for x in range(0,len(players)):
 for y in range(0,len(players[x])):
  players[x][y]=int(players[x][y])
for x in range(0,len(number)):number[x]=int(number[x])
Pos=list(map(V,range(0,14**3)))
B=[]
C=[]
P1=deepcopy(players)
N1=deepcopy(number)
for x in range(len(Pos)):
    P=True
    y=Pos[x]
    if '1A'in y or '2B'in y or '3C'in y or 'FU'in y or 'A1'in y or 'B2'in y or 'C3'in y or 'UF'in y:
            P=False#stupid check
    if P:#legality check
        z=0
        players=deepcopy(P1)
        number=deepcopy(N1)
        for x in players:
            if str(number[1]) in str(x[0]):self=x
        for w in range(0,3):
            if y[w] in '3':
                if int(number[2])<3:P=False;break
                else:z-=3;self[3]+=3;number[2]-=3
            if y[w] in '2':
                if int(number[2])<2:P=False;break
                else:z-=2;self[3]+=2;number[2]-=2
            if y[w] in '1':
                if int(number[2])<1:P=False;break
                else:z-=1;self[3]+=1;number[2]-=1
            if y[w] in 'A':
                if int(self[3])<1:P=False;break
                else:z+=1;self[3]-=3;number[2]+=3
            if y[w] in 'B':
                if int(self[3])<2:P=False;break
                else:z+=2;self[3]-=2;number[2]+=2
            if y[w] in 'C':
                if int(self[3])<3:P=False;break
                else:z+=3;self[3]-=1;number[2]+=1
            if y[w] in 'X':
                if int(self[3])<1:P=False;break
                else:self[3]-=1
            if y[w] in 'Y':
                if int(self[3])<2:P=False;break
                else:self[3]-=2
            if y[w] in 'Z':
                if int(self[3])<3:P=False;break
                else:self[3]-=3
            if y[w] in 'F':
                if int(self[3])<1:P=False;break
                else:z+=2;self[3]-=1;self[2]+=1
            if y[w] in 'U':
                if int(self[3])<1:P=False;break
                else:z-=2;self[3]+=1;self[2]-=1
            if y[w] in 'R':
                self[2:4]=players[(players.index(self)+1)%len(players)][2:4]
                z+=int(self[3])*-1
                z+=int(self[2])*2
            if y[w] in 'T':
                self[2:4]=players[(players.index(self)-1)%len(players)][2:4]
                z+=int(self[3])*-1
                z+=int(self[2])*2
    if P:
        C.append(z);B.append((z,y))
c=list(set(C))
c.sort()
c=c[::-1][1];D=[]
for x in B:
    if c in x:D.append(x)
print(D[randint(0,len(D)-1)][1])

แก้ไข: รหัสกำลังพิมพ์การย้ายทางกฎหมายแบบสุ่ม ตอนนี้มันควรจะกลับมาผลลัพธ์ที่ดีที่สุดที่สอง


1

บอทปีศาจ

แม้ว่าผลผลิตของมันจะมีอยู่เพียงครึ่งเดียวของจำนวนมาร แต่ผลลัพธ์ก็น่าหายนะ การรับ 9 เหรียญต่อการหมุนแต่ละครั้งในที่สุดก็หมดแรงกองเหรียญ เนื่องจากบอทนี้ไม่เคยโยนเหรียญใด ๆ ที่ใช้ไปมันจึงเป็นเรื่องที่แย่มากสำหรับคนอื่น ๆ ที่อยู่ถัดจากมันเมื่อมีการหมุน (-9 คะแนนสำหรับการหมุนแต่ละครั้งที่บอทนี้ใช้)

print("333")

คำสั่ง: python3 devil.py

ฉันหวังว่าจะทำให้บอทที่แท้จริงบางอย่างในภายหลัง


@plannapus อ๊ะ! ฉันไม่ได้สังเกตสิ่งนั้น ขอบคุณที่บอกฉัน!
frederick

1

จำฉันไว้ด้วย Python 3

โปรแกรมนี้มีข้อมูล inbuilt จำนวนมากจากการทดสอบกับบอท SecondBest คงที่

มันควรจะเรียนรู้เกี่ยวกับสิ่งที่ย้ายที่ดีที่สุดที่จะใช้ แต่มันไม่ได้ใช้การป้อนข้อมูลผู้เล่นอื่น

แก้ไข: ลบการคำนวณจุดที่ไม่จำเป็นออก

แก้ไข: อินพุตของผู้เล่นที่ไม่ใส่เครื่องหมายข้อคิดเห็น

import sys
file=sys.argv[0].split('\\')[::-1][0]
from copy import deepcopy
from random import randint
In=str(sys.argv[1])
def V(n,f=10,t=14):
 n=str(n);z=0;s='';d='0123456789';d1='N123ABCXYZRTFU'
 for i in n:z=z*f+d.index(i)
 while z:z,m=divmod(z,t);s=d1[m]+s
 while len(s)<3:s='N'+s
 return s
In=In.split(';')
number=In[0:3]
players=In[3:]
for x in range(0,len(players)):players[x]=players[x].split('_')
for x in players:
 if number[1] in x[0]:self=x
for x in range(0,len(players)):
 for y in range(0,len(players[x])):
  players[x][y]=int(players[x][y])
for x in range(0,len(number)):number[x]=int(number[x])
Pos=list(map(V,range(0,14**3)))
B=[]
P1=deepcopy(players)
N1=deepcopy(number)
for x in range(len(Pos)):
    P=True
    y=Pos[x]
    if '1A'in y or '2B'in y or '3C'in y or 'FU'in y or 'A1'in y or 'B2'in y or 'C3'in y or 'UF'in y:
            P=False
    if P:
        players=deepcopy(P1)
        number=deepcopy(N1)
        for x in players:
            if str(number[1]) in str(x[0]):self=x
        for w in range(0,3):
            if y[w] in '3':
                if int(number[2])<3:P=False;break
                else:self[3]+=3;number[2]-=3
            if y[w] in '2':
                if int(number[2])<2:P=False;break
                else:self[3]+=2;number[2]-=2
            if y[w] in '1':
                if int(number[2])<1:P=False;break
                else:self[3]+=1;number[2]-=1
            if y[w] in 'A':
                if int(self[3])<1:P=False;break
                else:self[3]-=3;number[2]+=3
            if y[w] in 'B':
                if int(self[3])<2:P=False;break
                else:self[3]-=2;number[2]+=2
            if y[w] in 'C':
                if int(self[3])<3:P=False;break
                else:self[3]-=1;number[2]+=1
            if y[w] in 'X':
                if int(self[3])<1:P=False;break
                else:self[3]-=1
            if y[w] in 'Y':
                if int(self[3])<2:P=False;break
                else:self[3]-=2
            if y[w] in 'Z':
                if int(self[3])<3:P=False;break
                else:self[3]-=3
            if y[w] in 'F':
                if int(self[3])<1:P=False;break
                else:self[3]-=1;self[2]+=1
            if y[w] in 'U':
                if int(self[3])<1:P=False;break
                else:self[3]+=1;self[2]-=1
            if y[w] in 'R':
                self[2:4]=players[(players.index(self)+1)%len(players)][2:4]
            if y[w] in 'T':
                self[2:4]=players[(players.index(self)-1)%len(players)][2:4]
    if P:
        B.append(y)
Pos=list(B)
B=[]
#
C=[['NNN',0],['NN1',-1],['NN2',-2],['NN3',-3],['NNR',-6],['NNT',-1],['N1N',-1],['N11',-2],['N12',-3],['N13',-4],['N1X',-1],['N1R',-7],['N1T',-2],['N1F',1],['N1U',-3],['N2N',-2],['N21',-3],['N22',-4],['N23',-5],['N2A',-1],['N2X',-2],['N2Y',-2],['N2R',-8],['N2T',-3],['N2F',0],['N2U',-4],['N3N',-3],['N31',-4],['N32',-5],['N33',-6],['N3A',-2],['N3B',-1],['N3X',-3],['N3Y',-3],['N3Z',-3],['N3R',-9],['N3T',-4],['N3F',-1],['N3U',-5],['NRN',-6],['NR1',-7],['NR2',-8],['NR3',-9],['NRA',-5],['NRB',-4],['NRC',-3],['NRX',-6],['NRY',-6],['NRZ',-6],['NRR',-12],['NRT',-7],['NRF',-4],['NRU',-8],['NTN',-1],['NT1',-2],['NT2',-3],['NT3',-4],['NTA',0],['NTX',-1],['NTR',-7],['NTT',-2],['NTF',1],['NTU',-3],['1NN',-1],['1N1',-2],['1N2',-3],['1N3',-4],['1NA',0],['1NX',-1],['1NR',-7],['1NT',-2],['1NF',1],['1NU',-3],['11N',-2],['111',-3],['112',-4],['113',-5],['11B',0],['11X',-2],['11Y',-2],['11R',-8],['11T',-3],['11F',0],['11U',-4],['12N',-3],['121',-4],['122',-5],['123',-6],['12A',-2],['12C',0],['12X',-3],['12Y',-3],['12Z',-3],['12R',-9],['12T',-4],['12F',-1],['12U',-5],['13N',-4],['131',-5],['132',-6],['133',-7],['13A',-3],['13B',-2],['13X',-4],['13Y',-4],['13Z',-4],['13R',-10],['13T',-5],['13F',-2],['13U',-6],['1XN',-1],['1X1',-2],['1X2',-3],['1X3',-4],['1XR',-7],['1XT',-2],['1RN',-7],['1R1',-8],['1R2',-9],['1R3',-10],['1RA',-6],['1RB',-5],['1RC',-4],['1RX',-7],['1RY',-7],['1RZ',-7],['1RR',-13],['1RT',-8],['1RF',-5],['1RU',-9],['1TN',-2],['1T1',-3],['1T2',-4],['1T3',-5],['1TA',-1],['1TX',-2],['1TR',-8],['1TT',-3],['1TF',0],['1TU',-4],['1FN',1],['1F1',0],['1F2',-1],['1F3',-2],['1FR',-5],['1FT',0],['1UN',-3],['1U1',-4],['1U2',-5],['1U3',-6],['1UA',-2],['1UB',-1],['1UX',-3],['1UY',-3],['1UR',-9],['1UT',-4],['1UU',-5],['2NN',-2],['2N1',-3],['2N2',-4],['2N3',-5],['2NA',-1],['2NB',0],['2NX',-2],['2NY',-2],['2NR',-8],['2NT',-3],['2NF',0],['2NU',-4],['21N',-3],['211',-4],['212',-5],['213',-6],['21B',-1],['21C',0],['21X',-3],['21Y',-3],['21Z',-3],['21R',-9],['21T',-4],['21F',-1],['21U',-5],['22N',-4],['221',-5],['222',-6],['223',-7],['22A',-3],['22C',-1],['22X',-4],['22Y',-4],['22Z',-4],['22R',-10],['22T',-5],['22F',-2],['22U',-6],['23N',-5],['231',-6],['232',-7],['233',-8],['23A',-4],['23B',-3],['23X',-5],['23Y',-5],['23Z',-5],['23R',-11],['23T',-6],['23F',-3],['23U',-7],['2AN',-1],['2A2',-3],['2A3',-4],['2AR',-7],['2AT',-2],['2XN',-2],['2X1',-3],['2X2',-4],['2X3',-5],['2XA',-1],['2XX',-2],['2XR',-8],['2XT',-3],['2XF',0],['2XU',-4],['2YN',-2],['2Y1',-3],['2Y2',-4],['2Y3',-5],['2YR',-8],['2YT',-3],['2RN',-8],['2R1',-9],['2R2',-10],['2R3',-11],['2RA',-7],['2RB',-6],['2RC',-5],['2RX',-8],['2RY',-8],['2RZ',-8],['2RR',-14],['2RT',-9],['2RF',-6],['2RU',-10],['2TN',-3],['2T1',-4],['2T2',-5],['2T3',-6],['2TA',-2],['2TX',-3],['2TR',-9],['2TT',-4],['2TF',-1],['2TU',-5],['2FN',0],['2F1',-1],['2F2',-2],['2F3',-3],['2FA',1],['2FX',0],['2FR',-6],['2FT',-1],['2FF',2],['2UN',-4],['2U1',-5],['2U2',-6],['2U3',-7],['2UA',-3],['2UB',-2],['2UC',-1],['2UX',-4],['2UY',-4],['2UZ',-4],['2UR',-10],['2UT',-5],['2UU',-6],['3NN',-3],['3N1',-4],['3N2',-5],['3N3',-6],['3NA',-2],['3NB',-1],['3NC',0],['3NX',-3],['3NY',-3],['3NZ',-3],['3NR',-9],['3NT',-4],['3NF',-1],['3NU',-5],['31N',-4],['311',-5],['312',-6],['313',-7],['31B',-2],['31C',-1],['31X',-4],['31Y',-4],['31Z',-4],['31R',-10],['31T',-5],['31F',-2],['31U',-6],['32N',-5],['321',-6],['322',-7],['323',-8],['32A',-4],['32C',-2],['32X',-5],['32Y',-5],['32Z',-5],['32R',-11],['32T',-6],['32F',-3],['32U',-7],['33N',-6],['331',-7],['332',-8],['333',-9],['33A',-5],['33B',-4],['33X',-6],['33Y',-6],['33Z',-6],['33R',-12],['33T',-7],['33F',-4],['33U',-8],['3AN',-2],['3A2',-4],['3A3',-5],['3AR',-8],['3AT',-3],['3BN',-1],['3B1',-2],['3B3',-4],['3BA',0],['3BX',-1],['3BR',-7],['3BT',-2],['3BF',1],['3BU',-3],['3XN',-3],['3X1',-4],['3X2',-5],['3X3',-6],['3XA',-2],['3XB',-1],['3XX',-3],['3XY',-3],['3XR',-9],['3XT',-4],['3XF',-1],['3XU',-5],['3YN',-3],['3Y1',-4],['3Y2',-5],['3Y3',-6],['3YA',-2],['3YX',-3],['3YR',-9],['3YT',-4],['3YF',-1],['3YU',-5],['3ZN',-3],['3Z1',-4],['3Z2',-5],['3Z3',-6],['3ZR',-9],['3ZT',-4],['3RN',-9],['3R1',-10],['3R2',-11],['3R3',-12],['3RA',-8],['3RB',-7],['3RC',-6],['3RX',-9],['3RY',-9],['3RZ',-9],['3RR',-15],['3RT',-10],['3RF',-7],['3RU',-11],['3TN',-4],['3T1',-5],['3T2',-6],['3T3',-7],['3TA',-3],['3TX',-4],['3TR',-10],['3TT',-5],['3TF',-2],['3TU',-6],['3FN',-1],['3F1',-2],['3F2',-3],['3F3',-4],['3FA',0],['3FB',1],['3FX',-1],['3FY',-1],['3FR',-7],['3FT',-2],['3FF',1],['3UN',-5],['3U1',-6],['3U2',-7],['3U3',-8],['3UA',-4],['3UB',-3],['3UC',-2],['3UX',-5],['3UY',-5],['3UZ',-5],['3UR',-11],['3UT',-6],['3UU',-7],['RNN',-6],['RN1',-7],['RN2',-8],['RN3',-9],['RNA',-5],['RNB',-4],['RNC',-3],['RNX',-6],['RNY',-6],['RNZ',-6],['RNR',-12],['RNT',-7],['RNF',-4],['RNU',-8],['R1N',-7],['R11',-8],['R12',-9],['R13',-10],['R1B',-5],['R1C',-4],['R1X',-7],['R1Y',-7],['R1Z',-7],['R1R',-13],['R1T',-8],['R1F',-5],['R1U',-9],['R2N',-8],['R21',-9],['R22',-10],['R23',-11],['R2A',-7],['R2C',-5],['R2X',-8],['R2Y',-8],['R2Z',-8],['R2R',-14],['R2T',-9],['R2F',-6],['R2U',-10],['R3N',-9],['R31',-10],['R32',-11],['R33',-12],['R3A',-8],['R3B',-7],['R3X',-9],['R3Y',-9],['R3Z',-9],['R3R',-15],['R3T',-10],['R3F',-7],['R3U',-11],['RAN',-5],['RA2',-7],['RA3',-8],['RAA',-4],['RAB',-3],['RAC',-2],['RAX',-5],['RAY',-5],['RAZ',-5],['RAR',-11],['RAT',-6],['RAF',-3],['RAU',-7],['RBN',-4],['RB1',-5],['RB3',-7],['RBA',-3],['RBB',-2],['RBC',-1],['RBX',-4],['RBY',-4],['RBZ',-4],['RBR',-10],['RBT',-5],['RBF',-2],['RBU',-6],['RCN',-3],['RC1',-4],['RC2',-5],['RCA',-2],['RCB',-1],['RCC',0],['RCX',-3],['RCY',-3],['RCZ',-3],['RCR',-9],['RCT',-4],['RCF',-1],['RCU',-5],['RXN',-6],['RX1',-7],['RX2',-8],['RX3',-9],['RXA',-5],['RXB',-4],['RXC',-3],['RXX',-6],['RXY',-6],['RXZ',-6],['RXR',-12],['RXT',-7],['RXF',-4],['RXU',-8],['RYN',-6],['RY1',-7],['RY2',-8],['RY3',-9],['RYA',-5],['RYB',-4],['RYC',-3],['RYX',-6],['RYY',-6],['RYZ',-6],['RYR',-12],['RYT',-7],['RYF',-4],['RYU',-8],['RZN',-6],['RZ1',-7],['RZ2',-8],['RZ3',-9],['RZA',-5],['RZB',-4],['RZC',-3],['RZX',-6],['RZY',-6],['RZZ',-6],['RZR',-12],['RZT',-7],['RZF',-4],['RZU',-8],['RRN',-12],['RR1',-13],['RR2',-14],['RR3',-15],['RRA',-11],['RRB',-10],['RRC',-9],['RRX',-12],['RRY',-12],['RRZ',-12],['RRR',-18],['RRT',-13],['RRF',-10],['RRU',-14],['RTN',-7],['RT1',-8],['RT2',-9],['RT3',-10],['RTA',-6],['RTX',-7],['RTR',-13],['RTT',-8],['RTF',-5],['RTU',-9],['RFN',-4],['RF1',-5],['RF2',-6],['RF3',-7],['RFA',-3],['RFB',-2],['RFC',-1],['RFX',-4],['RFY',-4],['RFZ',-4],['RFR',-10],['RFT',-5],['RFF',-2],['RUN',-8],['RU1',-9],['RU2',-10],['RU3',-11],['RUA',-7],['RUB',-6],['RUC',-5],['RUX',-8],['RUY',-8],['RUZ',-8],['RUR',-14],['RUT',-9],['RUU',-10],['TNN',-1],['TN1',-2],['TN2',-3],['TN3',-4],['TNA',0],['TNX',-1],['TNR',-7],['TNT',-2],['TNF',1],['TNU',-3],['T1N',-2],['T11',-3],['T12',-4],['T13',-5],['T1B',0],['T1X',-2],['T1Y',-2],['T1R',-8],['T1T',-3],['T1F',0],['T1U',-4],['T2N',-3],['T21',-4],['T22',-5],['T23',-6],['T2A',-2],['T2C',0],['T2X',-3],['T2Y',-3],['T2Z',-3],['T2R',-9],['T2T',-4],['T2F',-1],['T2U',-5],['T3N',-4],['T31',-5],['T32',-6],['T33',-7],['T3A',-3],['T3B',-2],['T3X',-4],['T3Y',-4],['T3Z',-4],['T3R',-10],['T3T',-5],['T3F',-2],['T3U',-6],['TAN',0],['TA2',-2],['TA3',-3],['TAR',-6],['TAT',-1],['TXN',-1],['TX1',-2],['TX2',-3],['TX3',-4],['TXR',-7],['TXT',-2],['TRN',-7],['TR1',-8],['TR2',-9],['TR3',-10],['TRA',-6],['TRB',-5],['TRC',-4],['TRX',-7],['TRY',-7],['TRZ',-7],['TRR',-13],['TRT',-8],['TRF',-5],['TRU',-9],['TTN',-2],['TT1',-3],['TT2',-4],['TT3',-5],['TTA',-1],['TTX',-2],['TTR',-8],['TTT',-3],['TTF',0],['TTU',-4],['TFN',1],['TF1',0],['TF2',-1],['TF3',-2],['TFR',-5],['TFT',0],['TUN',-3],['TU1',-4],['TU2',-5],['TU3',-6],['TUA',-2],['TUB',-1],['TUX',-3],['TUY',-3],['TUR',-9],['TUT',-4],['TUU',-5]]
#
points=0
#
dpoints=self[1]-points
z=0
for x in range(len(Pos)):
    y=Pos[x]
    z=0
    for x in C:
     if x[0]==y:z=x[1]
    B.append((z,y))
B.sort()
B=B[::-1]
G=open(file,'r')
H=G.read().split('#')[::-1]
G.close()
G=open(file,'w')
H[3]=H[3].replace(H[3][8:-1],str(self[1]))
J=eval(H[4][3:-1])
A=[B[0][1],dpoints]
P=1
for x in range(0,len(J)):
 if J[x][0]==A[0]:J[x][1]+=A[1];P=0
if P:J.append(A)
H[4]='\nC='+str(J)+'\n'
s=''
for x in H[::-1]:s+=x;s+='#'
G.write(s[:-1])
G.close()
print(B[0][1])

ฉันคิดว่าคุณมีการป้อนความเห็นในบรรทัด # 5
Averroes

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