เกมที่มีสัดส่วนของอะตอม


21

งานของคุณสร้างบอทที่เล่นAtomasด้วยคะแนนสูงสุด

เกมทำงานอย่างไร:

gameboard เริ่มต้นด้วยแหวน 6 "อะตอม" ที่มีจำนวนตั้งแต่การ1 3คุณสามารถ "เล่น" อะตอมระหว่างสองอะตอมหรืออะตอมอื่นขึ้นอยู่กับอะตอมเอง

คุณสามารถมีอะตอมปกติหรืออะตอมพิเศษ

อะตอมปกติ:

คุณสามารถเล่นอะตอมปกติระหว่างสองอะตอมที่มีอยู่บนกระดาน

คุณเริ่มต้นด้วยอะตอมในช่วง1 to 3แต่ช่วงเพิ่มขึ้น 1 ทุกๆ 40 การเคลื่อนไหว (ดังนั้นหลังจาก 40 การเคลื่อนไหวช่วงจะกลายเป็น2 to 4)

หากมีอะตอมบนกระดานที่ต่ำกว่าช่วงมันจะมี1 / no. of atoms of that number on the boardโอกาสเกิดการวางไข่

สมมติว่าคุณต้อง2เล่นและบอร์ดมีลักษณะดังนี้:

   1 1 2 1

สถานที่ Let 's ไปทางขวาของ21

กระดานตอนนี้กลายเป็น:

   1 1 2 1 2

หมายเหตุ: กระดานล้อมรอบดังนั้น1ทางด้านซ้ายสุดจะอยู่ติดกับ2ด้านขวาสุด สิ่งนี้จะมีความสำคัญในภายหลัง

อะตอม "พิเศษ" มี 4 ประเภทคือ:

+อะตอม:

อะตอมนี้เล่นระหว่างสองอะตอม มีโอกาส 1 ใน 5 ในการวางไข่

ถ้าอะตอมทั้งสองข้างของ+อะตอมเท่ากันจะเกิดการหลอมรวม นี่คือวิธีการทำงาน:

The two atoms fuse together to create an atom one higher.
(So, two 3 atoms fuse together to form one 4 atom.)
While the atoms on both sides of the fused atom are equal:
    If the atoms on the side >= the fused atom:
        The new fused atom = the old fused atom's value + 2.
    If the atoms on the side < the fused atom:
        The new fused atom = the old fused atom's value + 1.

ตัวอย่าง:

   1 1 3 2 2 3  (the 1 on the left-hand side "wraps back" 
                 to the 3 on the right-hand side)

Let's use the + on the two 2's in the middle.

-> 1 1 3 3 3    (the two 2's fused together to make a 3)
-> 1 1 5        (the two 3's fused with the 3, and because 3 >= 3,
                 the new fused atom = 3 + 2 = 5)
-> 6            (the two 1's fused with the 5, since the board wraps,
                 and because 1 < 5, the new fused atom = 5 + 1 = 6)

Because the atoms on the sides of the 6 don't exist, fusion stops,
and the board is now [6].

ถ้าอะตอมทั้งสองด้านของ+อะตอมแตกต่างกันแสดงว่า+อยู่บนกระดาน

ตัวอย่าง:

   1 3 2 3 1 1

Let's use the + on the 2 and 3 in the middle.

-> 1 3 2 + 3 1 1 (2 != 3, so the + stays on the board)

-อะตอม:

อะตอมนี้เล่นในอะตอมอื่น มีโอกาส 1 ใน 10 ของการวางไข่

-อะตอมเอาอะตอมจากคณะกรรมการและช่วยให้คุณเลือกอย่างใดอย่างหนึ่ง:

  • เล่นอะตอมที่ถูกลบออกในรอบถัดไปหรือ
  • เปลี่ยนเป็น + atom เพื่อเล่นรอบต่อไป

ตัวอย่าง:

   1 3 2 3 1 1

Let's use the - on the left-hand 2.

-> 1 3 3 1 1    (the 2 is now removed from the board)

Let's turn it into a +, and place it in between the 3's.

-> 1 4 1 1      (the two 3's fused together to make a 4)
-> 5 1          (the two 1's fused with the 4, and because 1 < 4,
                 the new fused atom = 4 + 1 = 5)

+อะตอมสีดำB ):

อะตอมนี้เล่นระหว่าง 2 อะตอม มีโอกาส 1 ใน 80 ในการวางไข่และวางไข่เมื่อคะแนนของคุณ> 750

อะตอมนี้เป็นพื้นเดียวกับ+อะตอมยกเว้นว่ามันฟิวส์สองอะตอมด้วยกันแม้+'s จากนั้นเป็นต้นไปจะปฏิบัติตาม+กฎ (มันจะรวมอะตอมเข้าด้วยกันก็ต่อเมื่ออะตอมทั้งสองด้านของอะตอมที่หลอมรวมมีค่าเท่ากัน)

อะตอมที่หลอมรวมเป็นผลมาจากสีดำ+เท่ากับ:

  • จำนวนอะตอมที่สูงขึ้นในฟิวชั่น + 3
  • 4ถ้าทั้งสองหลอมอะตอม+'s

ตัวอย่าง:

   1 3 2 1 3 1

Let's use the black + on the 2 and 1 in the middle.

-> 1 3 5 3 1    (the 2 and 1 fused together to make a 2 + 3 = 5)
-> 1 6 1        (+ rule)
-> 7            (+ rule)

ตัวอย่างอื่น:

   2 + + 2

Let's use the black + on the two +'s.

-> 2 4 2        (the two +'s fused together to make a 4)
-> 5            (+ rule)

อะตอมโคลน ( C):

อะตอมนี้เล่นในอะตอมอื่น มันมีโอกาส 1 ใน 60 ของการวางไข่และจะเกิดขึ้นเมื่อคะแนนของคุณ> 1500

อะตอมโคลนช่วยให้คุณสามารถเลือกอะตอมและเล่นรอบต่อไป

ตัวอย่าง:

   1 1 2 1

Let's use the clone on the 2, and place it to the right of the 1.

-> 1 1 2 1 2

นี่คือโครงสร้างของเกมของฉันใน Python 2:

import random
import subprocess

logs='atoms.log'
atom_range = [1, 3]
board = []
score = 0
move_number = 0
carry_over = " "
previous_moves = []

specials = ["+", "-", "B", "C"]


def plus_process(user_input):
    global board, score, previous_moves, matches
    previous_moves = []
    matches = 0

    def score_calc(atom):
        global score, matches
        if matches == 0:
            score += int(round((1.5 * atom) + 1.25, 0))
        else:
            if atom < final_atom:
                outer = final_atom - 1
            else:
                outer = atom
            score += ((-final_atom + outer + 3) * matches) - final_atom + (3 * outer) + 3
        matches += 1

    if len(board) < 1 or user_input == "":
        board.append("+")
        return None
    board_start = board[:int(user_input) + 1]
    board_end = board[int(user_input) + 1:]
    final_atom = 0
    while len(board_start) > 0 and len(board_end) > 0:
        if board_start[-1] == board_end[0] and board_end[0] != "+":
            if final_atom == 0:
                final_atom = board_end[0] + 1
            elif board_end[0] >= final_atom:
                final_atom += 2
            else:
                final_atom += 1
            score_calc(board_end[0])
            board_start = board_start[:-1]
            board_end = board_end[1:]
        else:
            break
    if len(board_start) == 0:
        while len(board_end) > 1:
            if board_end[0] == board_end[-1] and board_end[0] != "+":
                if final_atom == 0:
                    final_atom = board_end[0]
                elif board_end[0] >= final_atom:
                    final_atom += 2
                else:
                    final_atom += 1
                score_calc(board_end[0])
                board_end = board_end[1:-1]
            else:
                break
    if len(board_end) == 0:
        while len(board_start) > 1:
            if board_start[0] == board_start[-1] and board_start[0] != "+":
                if board_start[0] >= final_atom:
                    final_atom += 2
                else:
                    final_atom += 1
                score_calc(board_start[0])
                board_start = board_start[1:-1]
            else:
                break
    if matches == 0:
        board = board_start + ["+"] + board_end
    else:
        board = board_start + [final_atom] + board_end
        for a in range(len(board) - 1):
            if board[a] == "+":
                if board[(a + 1) % len(board)] == board[a - 1]:
                    board = board[:a - 1] + board[a:]
                    plus_process(a)
                    break


def minus_process(user_input, minus_check):
    global carry_over, board
    carry_atom = board[int(user_input)]
    if user_input == len(board) - 1:
        board = board[:-1]
    else:
        board = board[:int(user_input)] + board[int(user_input) + 1:]
    if minus_check == "y":
        carry_over = "+"
    elif minus_check == "n":
        carry_over = str(carry_atom)


def black_plus_process(user_input):
    global board
    if board[int(user_input)] == "+":
        if board[int(user_input) + 1] == "+":
            inter_atom = 4
        else:
            inter_atom = board[int(user_input) + 1] + 2
    else:
        if board[int(user_input)] + 1 == "+":
            inter_atom = board[int(user_input)] + 2
        else:
            inter_list = [board[int(user_input)], board[int(user_input) + 1]]
            inter_atom = (inter_list.sort())[1] + 2
    board = board[int(user_input) - 1:] + [inter_atom] * 2 + board[int(user_input) + 1:]
    plus_process(int(user_input) - 1)


def clone_process(user_input):
    global carry_over
    carry_over = str(board[int(user_input)])


def regular_process(atom,user_input):
    global board
    if user_input == "":
        board.append(random.randint(atom_range[0], atom_range[1]))
    else:
        board = board[:int(user_input) + 1] + [int(atom)] + board[int(user_input) + 1:]

def gen_specials():
    special = random.randint(1, 240)
    if special <= 48:
        return "+"
    elif special <= 60 and len(board) > 0:
        return "-"
    elif special <= 64 and len(board) > 0 and score >= 750:
        return "B"
    elif special <= 67 and len(board) > 0 and score >= 1500:
        return "C"
    else:
        small_atoms = []
        for atom in board:
            if atom not in specials and atom < atom_range[0]:
                small_atoms.append(atom)
        small_atom_check = random.randint(1, len(board))
        if small_atom_check <= len(small_atoms):
            return str(small_atoms[small_atom_check - 1])
        else:
            return str(random.randint(atom_range[0], atom_range[1]))


def specials_call(atom, user_input):
    specials_dict = {
        "+": plus_process,
        "-": minus_process,
        "B": black_plus_process,
        "C": clone_process
    }
    if atom in specials_dict.keys():
        if atom == "-":
            minus_process(user_input[0], user_input[1])
        else:
            specials_dict[atom](user_input[0])
    else:
        regular_process(atom,user_input[0])


def init():
    global board, score, move_number, carry_over, previous_moves
    board = []
    score = 0

    for _ in range(6):
        board.append(random.randint(1, 3))

    while len(board) <= 18:
        move_number += 1
        if move_number % 40 == 0:
            atom_range[0] += 1
            atom_range[1] += 1
        if carry_over != " ":
            special_atom = carry_over
            carry_over = " "
        elif len(previous_moves) >= 5:
            special_atom = "+"
        else:
            special_atom = gen_specials()
        previous_moves.append(special_atom)
        bot_command = "python yourBot.py"
        bot = subprocess.Popen(bot_command.split(),
                               stdout = subprocess.PIPE,
                               stdin = subprocess.PIPE)
        to_send="/".join([
            # str(score),
            # str(move_number),
            str(special_atom),
            " ".join([str(x) for x in board])
        ])
        bot.stdin.write(to_send)
        with open(logs, 'a') as f:f.write(to_send+'\n')
        bot.stdin.close()
        all_user_input = bot.stdout.readline().strip("\n").split(" ")
        specials_call(special_atom, all_user_input)

    print("Game over! Your score is " + str(score))

if __name__ == "__main__":
    for a in range(20):
        with open(logs, 'a') as f:f.write('round '+str(a)+'-'*50+'\n')
        init()

วิธีทำงานของ bot:

อินพุต

  • บอทของคุณจะได้รับ 2 อินพุท: อะตอมที่กำลังเล่นอยู่และสถานะของบอร์ด
  • อะตอมจะเป็นเช่นนั้น:
    • +สำหรับ+อะตอม
    • -สำหรับ-อะตอม
    • Bสำหรับ+อะตอมดำ
    • C สำหรับอะตอมโคลน
    • {atom} สำหรับอะตอมปกติ
  • สถานะของคณะกรรมการจะเป็นดังนี้:
    • atom 0 atom 1 atom 2... atom nโดยแยกอะตอมด้วยช่องว่าง ( atom nย้อนกลับไปที่atom 1เพื่อจำลองเกมกระดาน "วงแหวน")
  • /ทั้งสองจะถูกแยกจากกันโดย

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

1/1 2 2 3   (the atom in play is 1, and the board is [1 2 2 3])
+/1         (the atom in play is +, and the board is [1] on its own)

เอาท์พุต

  • คุณจะส่งออกสตริงขึ้นอยู่กับอะตอมในการเล่น

    • ถ้าตั้งใจจะเล่นเป็นอะตอมระหว่างสองอะตอม:

      • เอาท์พุทช่องว่างที่คุณต้องการเล่นอะตอมในช่องว่างเหมือนในระหว่างแต่ละอะตอมดังนี้:

        atom 0, GAP 0, atom 1, GAP 1, atom 2, GAP 2... atom n, GAP N
        

        ( gap nแสดงว่าคุณต้องการที่จะวางอะตอมระหว่างatom 1และอะตอมn) ดังนั้นการส่งออกถ้าคุณต้องการที่จะเล่นในอะตอม2gap 2

    • ถ้าตั้งใจจะเล่นกับอะตอม:
      • เอาท์พุทอะตอมที่คุณต้องการที่จะเล่นบนดังนั้นถ้าคุณต้องการที่จะเล่นในอะตอม2atom 2
    • ถ้าอะตอมเป็น-:
      • เอาท์พุทอะตอมที่คุณต้องการที่จะเล่นบนตามด้วยช่องว่างตามด้วยy/nทางเลือกของการเปลี่ยนอะตอมเป็น+ในภายหลังดังนั้น2, "y"ถ้าคุณต้องการที่จะเล่นอะตอมบนและคุณต้องการที่จะทำให้มันกลายเป็นatom 2 หมายเหตุ: ต้องใช้ 2 อินพุตแทน 1+

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

(Atom in play is a +)
2   (you want to play the + in gap 2 - between atom 2 and 3)
(Atom in play is a -)
3 y  (you want to play the - on atom 3, and you want to change it to a +)
2 n  (you want to play the - on atom 2, and you don't want to change it)
  • ในการทำให้ bot ทำงานคุณต้องไปที่Popenบิต (ที่ส่วนท้ายของโค้ด) และแทนที่ด้วยอะไรก็ตามที่ทำให้โปรแกรมของคุณทำงานเป็นรายการ Pythonic (ดังนั้นถ้าโปรแกรมของคุณderp.javaแทนที่["python", "bot.py"]ด้วย["java", "derp.java"])

รายละเอียดเฉพาะคำตอบ:

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

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

  • บอทที่มีคะแนนสูงสุดจะชนะ
    • บอทของคุณจะถูกทดสอบ 20 เกมและคะแนนสุดท้ายคือค่าเฉลี่ยของเกม 20 เกม
  • tie-breaker จะเป็นเวลาของการอัพโหลดคำตอบ
  • ดังนั้นคำตอบของคุณจะถูกจัดรูปแบบดังนี้:

    {language}, {bot name}
    Score: {score}
    

โชคดี!


สิ่งที่สร้างขึ้น+สำหรับ-อะตอมทำงานอย่างไร หากคุณเลือกyคุณจะรับประกันว่าจะได้รับ+ในการย้ายครั้งต่อไป?
Ton Hospel

4
ฉันขอแนะนำให้เปลี่ยนไดรเวอร์บ็อตของคุณเพื่อให้สามารถจัดการโปรแกรมแบบสแตนด์อโลนใด ๆ ที่รับอินพุตบน STDIN และให้ผลลัพธ์กับ STDOUT ที่ควรให้ความเป็นอิสระด้านภาษาและภาษาส่วนใหญ่ที่ใช้ในเว็บไซต์นี้สามารถทำได้อย่างง่ายดาย แน่นอนว่านี่หมายถึงการกำหนดรูปแบบ I / O ที่เข้มงวดเช่นinput_atom\natom0 atom1 .... atomn\nสำหรับ STDIN
Ton Hospel

1
ดูเหมือนว่ารหัสจะสามารถใส่+ในรายการองค์ประกอบ แต่ไม่มีที่ไหนในคำอธิบายต้นฉบับ
Ton Hospel

1
อ่าฉันเห็นว่าคุณทำให้โปรแกรมสามารถเรียกบอตภายนอก อย่างไรก็ตามคุณต้องผ่านหมายเลขการย้ายปัจจุบันและคะแนนบน STDIN ไม่เช่นนั้น ธ ปท. ไม่สามารถคาดการณ์โอกาสของแต่ละอะตอมที่จะเกิดขึ้นในอนาคต
Ton Hospel

1
Idk หากผู้คนใช้เวลาในการสร้างโซลูชันหากตัวควบคุมไม่ได้รับการปรับปรุง ฉันชอบคำถาม แต่ไม่ใช่การนำไปใช้
mbomb007

คำตอบ:


1

Python, draftBot, คะแนน = 889

import random
def h(b):
    s=0
    for x in b:
        try:
            s+=int(x)
        except: 
            s+=0
    return s
def d(i):g=i.split("/");a=g[0];b=g[1].split(" ");return(a,b)
def p(a,_,j):
    v=[]
    for x in _:
        try:
            v.append(int(x))
        except: 
            v.append(0)
    try:
        v=v[:j+1]+[int(a)]+v[j+1:]
    except: 
        v=v[:j+1]+[a]+v[j+1:]
    r1=[[]];b=[x for x in v];m=range(len(b)+1)
    for k in m:
        for i in m:
            for j in range(i):
                c = b[j:i + 1]
                if len(c)%2==0 and c==c[::-1] and 0 not in c:r1.append(c)
        b.insert(0, b.pop())
    q1=max(r1,key=len)
    r2=[[]];b=[x for x in v];m=range(len(b)+1)
    for k in m:
        for i in m:
            for j in range(i):
                c = b[j:i + 1]
                if len(c)>2 and len(c)%2==1 and c==c[::-1] and "+" in c and 0 not in c:r2.append(c)
        b.insert(0, b.pop())
    q2=max(r2,key=h)
    with open('f.log', 'a') as f:f.write('pal '+str(_)+' : '+str(q1)+' : '+str(q2)+'\n')
    if q2!=[]:return 100+h(q2)
    else:return len(q1)
i=raw_input()
(a,b)=d(i)
if a in ['C','B']:print('0')
elif a=='-':print("0 y" if random.randint(0, 1) == 1 else "0 n")
else:q,j=max((p(a,b,j),j)for j in range(len(b)));print(str(j))

ฉันพบว่าตัวควบคุม:

  • เกิดปัญหาเมื่อคะแนนเกิน 1,500;
  • ไม่รวมอะตอมอย่างถูกต้องในกรณีเดียวกัน

0

Python, RandomBot, คะแนน = 7.95

ไม่มีอะไรแฟนซีเกินไปเพียงบอทแบบสุ่ม

import random

game_input = raw_input().split("/")
current_atom = game_input[0]
board = game_input[1].split(" ")

if current_atom != "-":
    print(random.randint(0, len(board) - 1))
else:
    random_choice = " y" if random.randint(0, 1) == 1 else " n"
    print(str(random.randint(0, len(board) - 1)) + random_choice)

0

Python, BadPlayer, Score = 21.45

import random

try:
    raw_input
except:
    raw_input = input

game_input = raw_input().split("/")
current_atom = game_input[0]
board = game_input[1].split(" ")

def get_chain(board, base):
    chain = []
    board = board[:]
    try:
        while board[base] == board[base + 1]:
            chain = [board[base]] + chain + [board[base + 1]]
            del board[base]
            del board[base]
            base -= 1
    except IndexError:
        pass
    return chain

def biggest_chain(board):
    chains = []
    base = 0
    i = 0
    while i < len(board) - 1:
        chains.append([i, get_chain(board, i)])
        i += 1
    return sorted(chains, key=lambda x: len(x[1]) / 2)[-1]

def not_in_chain():
    a, b = biggest_chain(board)
    if len(b) == 0:
        print(random.randint(0, len(board) - 1))
    elif random.randint(0, 1) == 0:
        print(random.randint(a + len(b)/2, len(board) - 1))
    else:
        try:
            print(random.randint(0, a - len(b)/2 - 1))
        except:
            print(random.randint(a + len(b)/2, len(board) - 1))

if current_atom in "+B":
    a, b = biggest_chain(board)
    if len(b) == 0:
        print(0)
    else:
        print(a)
elif current_atom == "C":
    not_in_chain()
elif current_atom == "-":
    a, b = biggest_chain(board)
    if len(b) == 0:
        print(str(random.randint(0, len(board) - 1)) + " n")
    elif random.randint(0, 1) == 0:
        print(str(random.randint(a + len(b)/2, len(board) - 1)) + " n")
    else:
        try:
            print(str(random.randint(0, a - len(b)/2 - 1)) + " n")
        except:
            print(str(random.randint(0, len(board) - 1)) + " n")
else:
    not_in_chain()

บอทที่แย่มาก ๆ ที่มักจะทำให้คอนโทรลเลอร์พัง


มันทำให้คอนโทรลเลอร์ล่มได้อย่างไร? และถ้าเกิดว่าเป็นปัญหากับคอนโทรลเลอร์หรือบอทของคุณ?
mbomb007

@ mbomb007 ฉันจำไม่ได้ว่าทำไมมันถึงผิดพลาด แต่ความขัดข้องอยู่ในคอนโทรลเลอร์
TuxCrafting

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