Atomik oranların bir oyun


21

Göreviniz en yüksek skorla Atomas oynayan bir bot yapmak .

Oyun nasıl çalışır:

Gameboard arasında değişen sayıları ile, 6 "atomu" bir halka ile başlar 1için 3. Atomun kendisine bağlı olarak, bir atomu iki atom arasında veya başka bir atomda "oynatabilirsiniz".

Normal bir atom veya özel bir atom olabilir.

Normal atom:

Tahtadaki mevcut iki atom arasında normal bir atom oynayabilirsiniz.

Aralıktaki atomlarla başlarsınız 1 to 3, ancak aralık her 40 hamlede bir kez 1 artar (böylece 40 hamleden sonra aralık olur 2 to 4).

Tahta üzerinde aralıktan daha düşük atomlar varsa 1 / no. of atoms of that number on the board, yumurtlama olasılığı vardır .

Diyelim ki 2oynamak zorundasınız ve tahta şöyle gözüküyor:

   1 1 2 1

2En sağına koyalım 1.

Kurul şimdi olur:

   1 1 2 1 2

Not: tahta sarılır, bu yüzden en 1soldaki aslında aslında 2en sağdaki yanındadır . Bu daha sonra önemli olacak.

4 tip "özel" atom vardır ve bunlar:

+atom:

Bu atom iki atom arasında oynanır. Yumurtlama şansı 1'de birdir.

Atomun her iki tarafındaki atomlar +aynıysa, füzyon oluşur. İşte nasıl çalışıyor:

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.

Örnek:

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

Atomun her iki tarafındaki atomlar +farklıysa, o zaman +tahtada kalır.

Örnek:

   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)

-atom:

Bu atom başka bir atomda oynanır. Yumurtlama olasılığı 10'da 1'dir.

-Atom kurulu bir atom kaldırır ve ya size bir seçenek sunar:

  • kaldırılan atomu bir sonraki rauntta oynat
  • Bir sonraki raunt oynamak için onu bir + atomuna çevirin.

Örnek:

   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)

Siyah +atom ( B):

Bu atom 2 atom arasında oynanır. 80'de 1'lik bir yumurtlama şansı vardır ve puanınız> 750 olan sadece bir kez ortaya çıkar.

Bu atom temel olarak +atomla aynıdır , ancak iki atomu bir arada tutturması dışında +. O andan itibaren, +kuralı izler (kaynaşmış atomun her iki tarafındaki atomlar eşitse, yalnızca atomları birleştirir).

Siyahın bir sonucu olarak kaynaştırılmış atom +şuna eşittir:

  • füzyondaki + 3 atomu daha yüksek
  • 4iki kaynaşmış atomu ise +sitesindeki

Örnek:

   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)

Başka bir örnek:

   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)

Klon atomu ( C):

Bu atom başka bir atomda oynanır. 60'a 1'lik bir yumurtlama şansı vardır ve puanınız bir kez> 1500 olduğunda ortaya çıkar.

Klon atomu, bir atom seçmenize ve bir sonraki turda oynamanıza izin verir.

Örnek:

   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

İşte Python 2'deki oyunum.

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 şey nasıl çalışır:

Giriş

  • Botunuz 2 giriş alacaktır: şu anda çalmakta olan atom ve kartın durumu.
  • Atom şöyle olacak:
    • +bir +atom için
    • -bir -atom için
    • BSiyah bir +atom için
    • C Klon atomu için
    • {atom} normal bir atom için
  • Kurulun durumu şöyle olacak:
    • atom 0 atom 1 atom 2... atom natomlar boşluklarla ayrılmış olarak ( bir "halka" gameboard taklit etmek için atom ngeri sarılır atom 1)
  • Bu ikisi a ile ayrılacaktır /.

Örnek girişler:

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)

Çıktı

  • Çalmakta olan atomun ne olduğuna bağlı olarak bir dizge çıkarırsınız.

    • Atom iki atom arasında çalınacaksa:

      • Atomun içinde oynamak istediğiniz boşluğu açın. Boşluklar, her atomun arasında olduğu gibidir;

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

        ( gap nEğer arasındaki atom yerleştirmek istediğiniz gösterir atom 1ve atom nçıkışı Yani) 2üzerinde atom oynamak istiyorsanız gap 2.

    • Atomun bir atomda oynatılması gerekiyorsa:
      • Üzerinde oynatmak istediğiniz atomun çıktısını verin, böylece 2atomu oynatmak istiyorsanız atom 2.
    • Atom bir - :
      • Üzerinde oynatmak istediğiniz atomun çıktısını alın, ardından boşluk bırakın, ardından y/natomu +daha sonraya çevirme seçimini yapın, 2, "y"eğer atomu oynatmak atom 2istiyorsanız ve onu a'ya dönüştürmek istiyorsanız +. Not: Bu 1 yerine 2 giriş gerektirir.

Örnek çıktılar:

(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 işi yapmak için, gitmek zorunda Popen(kodun sonuna etrafında) bit ve Pythonic liste olarak programın çalışmasını yapar ne olursa olsun ile değiştirin (böylece programı ise derp.java, değiştirin ["python", "bot.py"]ile["java", "derp.java"] ).

Cevap özel özellikleri:

  • Botunuzun tüm kodunu cevaba yerleştirin. Uygun değilse, sayılmaz.
  • Her kullanıcının 1 bottan daha fazlasına sahip olmasına izin verilir, ancak hepsinin ayrı cevaplarda olması gerekir.
  • Ayrıca, botunuza bir isim verin.

puanlama:

  • En yüksek puana sahip bot kazanır.
    • Botunuz 20 oyun için test edilecek ve son skor 20 oyunun ortalamasıdır.
  • Bağlayıcı, cevabın yüklenme zamanı olacaktır.
  • Yani cevabınız şu şekilde biçimlendirilecektir:

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

İyi şanslar!


+Bir -atom için oluşturulan nasıl çalışır? Seçtiğin ybir +sonraki hamleye geçme garantisi olacak mı ?
Ton Hospel

4
Bot sürücünüzü değiştirmenizi öneririm, böylece STDIN'e giriş yapan ve STDOUT'da bir sonuç veren herhangi bir bağımsız programı kullanabilir. Bu dil bağımsızlığı vermelidir ve bu sitede kullanılan dillerin çoğu bunu kolayca yapabilir. Elbette bu, katı bir G / Ç formatı tanımlamak anlamına gelir, örneğin input_atom\natom0 atom1 .... atomn\nSTDIN
Ton Hospel için

1
Kod +eleman listesine
girebilir

1
Ah, programı harici botları çağırabildiğini gördüm. Bununla birlikte, şu anki hareket numarasını ve STDIN'deki puanı geçmeniz gerekir, aksi takdirde bot gelecekte gerçekleşecek her bir atomun şansını tahmin edemez
Ton Hospel

1
Denetleyici iyileştirilmemişse, insanların bir çözüm oluşturmak için zaman harcayacaklarını düşünün. Soruyu beğendim ama uygulamayı değil.
mbomb007

Yanıtlar:


1

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

Kontrolör buldum:

  • puan 1500'ü aştığında çöküyor;
  • Aynı durumlarda atomları düzgün şekilde birleştirmez.

0

Python, RandomBot, Puan = 7,95

Hiçbir şey çok süslü, sadece rastgele bir bot.

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, Puan = 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()

Sadece denetleyicinin çökmesine neden olan çok kötü bir bot


Denetleyicinin çökmesine nasıl sebep olur? Ve eğer öyleyse, denetleyicide veya botunuzda bir sorun mu var?
mbomb007

@ mbomb007 Neden kaza yaptığını hatırlamıyorum, ancak kazalar denetleyicideydi
TuxCrafting 24:06

Bu bot herhangi bir hata olmadan çalışmalı, sadece güncellenen "stdin" olayına uyması için kodu biraz değiştirmelisin.
clismique
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.