Permainan proporsi atom

21

Tugas Anda membuat bot yang memainkan Atomas , dengan skor tertinggi.

Cara kerja gim:

Gameboard dimulai dengan cincin 6 "atom", dengan angka mulai dari 1hingga 3. Anda dapat "memainkan" sebuah atom di antara dua atom, atau pada atom lain, tergantung pada atom itu sendiri.

Anda dapat memiliki atom normal, atau atom khusus.

Atom normal:

Anda dapat memainkan atom normal di antara dua atom yang tersedia di papan.

Anda memulai dengan atom dalam rentang 1 to 3, tetapi rentang meningkat sebesar 1 kali setiap 40 gerakan (jadi setelah 40 bergerak, rentang menjadi 2 to 4).

Jika ada atom di papan yang lebih rendah dari jangkauannya, ia memiliki 1 / no. of atoms of that number on the boardpeluang untuk bertelur.

Katakanlah Anda harus 2bermain, dan papan terlihat seperti ini:

   1 1 2 1

Mari kita tempatkan di 2sebelah kanan 1.

Dewan sekarang menjadi:

   1 1 2 1 2

Catatan: papan membungkus, sehingga 1di paling kiri sebenarnya di sebelah 2di paling kanan. Ini akan menjadi penting nanti.

Ada 4 jenis atom "istimewa", dan mereka adalah:

The +atom:

Atom ini dimainkan di antara dua atom. Ini memiliki peluang 1 banding 5 untuk bertelur.

Jika atom di kedua sisi +atom adalah sama, terjadi fusi. Begini cara kerjanya:

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.

Contoh:

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

Jika atom di kedua sisi +atom berbeda, maka +tetap di papan.

Contoh:

   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)

The -atom:

Atom ini dimainkan pada atom lain. Ini memiliki peluang 1 banding 10 untuk bertelur.

The -atom menghilangkan atom dari papan, dan memberi Anda pilihan untuk baik:

  • mainkan atom yang dihapus di babak berikutnya, atau
  • mengubahnya menjadi atom + untuk bermain putaran selanjutnya.

Contoh:

   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)

+Atom hitam ( B):

Atom ini dimainkan antara 2 atom. Ini memiliki peluang 1 dari 80 untuk bertelur, dan hanya menumbuhkan skor Anda sekali> 750.

Atom ini pada dasarnya sama dengan +atom, kecuali bahwa ia menggabungkan dua atom bersamaan, bahkan +. Sejak saat itu, ia mengikuti +aturan (hanya menyatukan atom jika atom di kedua sisi atom yang menyatu sama).

Atom yang menyatu sebagai hasil dari hitam +sama dengan:

  • semakin banyak atom dalam fusi + 3
  • 4jika dua atom yang menyatu adalah +milik

Contoh:

   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)

Contoh lain:

   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)

Atom klon ( C):

Atom ini dimainkan pada atom lain. Ini memiliki peluang 1 dari 60 untuk pemijahan, dan hanya memunculkan skor sekali> 1500.

Atom klon memungkinkan Anda untuk memilih atom, dan memainkannya putaran berikutnya.

Contoh:

   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

Ini permainan saya, di 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()

Cara kerja bot:

Memasukkan

  • Bot Anda akan mendapatkan 2 input: atom yang sedang dimainkan, dan status papan.
  • Atom akan menjadi seperti ini:
    • +untuk +atom
    • -untuk -atom
    • Buntuk +atom Hitam
    • C untuk atom Klon
    • {atom} untuk atom normal
  • Kondisi dewan akan seperti ini:
    • atom 0 atom 1 atom 2... atom n, dengan atom yang dipisahkan oleh spasi ( atom nmembungkus kembali ke atom 1, untuk mensimulasikan gameboard "cincin")
  • Keduanya akan dipisahkan oleh a /.

Input contoh:

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)

Keluaran

  • Anda akan menghasilkan string, tergantung pada apa atom yang dimainkan.

    • Jika atom dimaksudkan untuk dimainkan di antara dua atom:

      • Keluarkan celah tempat Anda ingin memainkan atom. Kesenjangannya seperti di antara setiap atom, seperti:

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

        ( gap nMenunjukkan Anda ingin menempatkan atom antara atom 1dan atom n) Jadi output 2jika Anda ingin memainkan atom gap 2.

    • Jika atom dimaksudkan untuk dimainkan pada atom:
      • Keluarkan atom yang ingin Anda mainkan, jadi 2jika Anda ingin memainkan atom atom 2.
    • Jika atomnya adalah -:
      • Keluarkan atom yang ingin Anda mainkan, diikuti dengan spasi, diikuti oleh y/npilihan untuk mengubah atom menjadi yang +lebih baru, jadi 2, "y"jika Anda ingin memainkan atom atom 2, dan Anda ingin mengubahnya menjadi a +. Catatan: ini membutuhkan 2 input, bukan 1.

Output contoh:

(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)
  • Untuk membuat bot berfungsi, Anda harus pergi ke Popenbit (sekitar akhir kode), dan menggantinya dengan apa pun yang membuat program Anda berjalan sebagai daftar Pythonic (jadi jika program Anda derp.java, ganti ["python", "bot.py"]dengan ["java", "derp.java"]).

Spesifikasi khusus jawaban:

  • Tempatkan seluruh kode bot Anda ke dalam jawabannya. Jika tidak cocok, itu tidak masuk hitungan.
  • Setiap pengguna diizinkan memiliki lebih dari 1 bot, namun, mereka semua harus berada di pos jawaban yang terpisah.
  • Juga, beri nama bot Anda.

Mencetak:

  • Bot dengan skor tertinggi menang.
    • Bot Anda akan diuji untuk 20 game, dan skor akhir adalah rata-rata dari 20 game.
  • Tie-breaker akan menjadi waktu pengunggahan jawaban.
  • Jadi jawaban Anda akan diformat seperti ini:

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

Semoga berhasil!

clismique
sumber
Bagaimana dihasilkan +untuk -bekerja atom? Jika Anda memilih, yapakah Anda akan dijamin mendapatkan +langkah selanjutnya?
Ton Hospel
4
Saya sarankan mengganti driver bot Anda sehingga dapat menangani program mandiri yang mengambil input pada STDIN dan memberikan hasil pada STDOUT. Itu harus memberikan kemandirian bahasa dan sebagian besar bahasa yang digunakan di situs ini dapat dengan mudah melakukannya. Tentu saja ini berarti mendefinisikan format I / O yang ketat, misalnya input_atom\natom0 atom1 .... atomn\nuntuk STDIN
Ton Hospel
1
Kode tampaknya dapat dimasukkan ke +dalam daftar elemen, tetapi ini tidak ditemukan dalam deskripsi tekstual
Ton Hospel
1
Ah, saya melihat Anda membuat program dapat memanggil bot eksternal. Namun, Anda juga harus memberikan nomor bergerak saat ini dan skor pada STDIN jika bot tidak dapat memprediksi peluang setiap atom terjadi di masa depan
Ton Hospel
1
Idk jika orang akan menghabiskan waktu untuk membuat solusi jika controller tidak diperbaiki. Saya suka pertanyaannya, tetapi bukan implementasinya.
mbomb007

Jawaban:

1

Python, draftBot, Skor = 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))

Saya menemukan bahwa controller:

  • lumpuh saat skor melebihi 1500;
  • tidak menggabungkan atom dengan benar dalam kasus yang sama.
mdahmoune
sumber
0

Python, RandomBot, Skor = 7.95

Tidak ada yang terlalu mewah, hanya bot acak.

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)
clismique
sumber
0

Python, BadPlayer, Skor = 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()

Hanya bot yang sangat buruk yang sering membuat crash controller

TuxCrafting
sumber
Bagaimana cara membuat controller crash? Dan jika ya, itu masalah dengan controller, atau bot Anda?
mbomb007
@ mbomb007 Saya tidak ingat mengapa crash, tapi crash ada di controller
TuxCrafting
Bot ini harus bekerja tanpa bug, cukup ubah sedikit kode untuk mengakomodasi hal "stdin" yang diperbarui.
clismique