Twoim zadaniem jest stworzenie bota, który gra w Atomy , z najwyższym wynikiem.
Jak działa gra:
Plansza zaczyna się od pierścienia 6 „atomów”, z liczbami od 1do 3. Możesz „grać” atomem między dwoma atomami lub innym atomem, w zależności od samego atomu.
Możesz mieć zwykły atom lub specjalny atom.
Normalny atom:
Możesz grać normalnym atomem pomiędzy dowolnymi dwoma dostępnymi atomami na planszy.
Zaczynasz z atomami w zakresie 1 to 3, ale zasięg zwiększa się o 1 raz na 40 ruchów (więc po 40 ruchach zasięg staje się 2 to 4).
Jeśli na planszy znajdują się atomy, które są niższe niż zasięg, ma 1 / no. of atoms of that number on the boardszansę na odrodzenie.
Powiedzmy, że masz 2do zagrania, a plansza wygląda następująco:
1 1 2 1
Umieśćmy 2po prawej stronie 1.
Plansza staje się teraz:
1 1 2 1 2
Uwaga: plansza się zawija, więc 1 skrajnie po lewej stronie jest właściwie obok 2skrajnie po prawej. Będzie to ważne później.
Istnieją 4 rodzaje „specjalnych” atomów i są to:
The +Atom:
Ten atom jest odtwarzany między dwoma atomami. Ma szansę na odrodzenie 1 na 5.
Jeśli atomy po obu stronach +atomu są takie same, następuje fuzja. Oto jak to działa:
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.
Przykład:
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].
Jeśli atomy po obu stronach +atomu są różne, to+ pozostają na planszy.
Przykład:
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:
Ten atom jest odtwarzany na innym atomie. Ma szansę na odrodzenie 1 na 10.
-Atom atom usuwa z planszy, a daje możliwość wyboru albo:
- zagraj usunięty atom w następnej rundzie lub
- zamień go w atom +, aby zagrać w następnej rundzie.
Przykład:
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)
Czarny +atom (B ):
Ten atom jest odtwarzany między 2 atomami. Ma szansę na odrodzenie 1 na 80 i odradza się tylko wtedy, gdy twój wynik> 750.
Ten atom jest w zasadzie taki sam jak +atom, z tym wyjątkiem, że łączy ze sobą dowolne dwa atomy, a nawet atom +. Odtąd postępuje zgodnie z +zasadą (łączy tylko atomy razem, jeśli atomy po obu stronach skondensowanego atomu są równe).
Skondensowany atom w wyniku czerni +jest równy:
- atom o wyższej liczbie w fuzji + 3
4Jeśli dwa skondensowane atomy+„s
Przykład:
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)
Inny przykład:
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 klonu (C ):
Ten atom jest odtwarzany na innym atomie. Ma szansę na odrodzenie 1 na 60 i pojawia się tylko wtedy, gdy twój wynik> 1500.
Atom klonu pozwala wybrać atom i zagrać go w następnej rundzie.
Przykład:
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
Oto moja wersja gry w 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()
Jak działa bot:
Wkład
- Twój bot otrzyma 2 wejścia: atom, który jest obecnie w grze, i stan planszy.
- Atom będzie taki:
+dla+atomu-dla-atomuBdla czarnego+atomuCdla atomu klonu{atom}dla normalnego atomu
- Stan planszy będzie taki:
atom 0 atom 1 atom 2... atom n, z atomami oddzielonymi spacjami (atom nwraca doatom 1, aby symulować planszę „pierścieniową”)
- Te dwa zostaną oddzielone przez
/.
Przykładowe dane wejściowe:
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)
Wydajność
Wyprowadzisz ciąg, w zależności od tego, jaki atom jest w grze.
Jeśli atom ma być odtwarzany między dwoma atomami:
Wypisuj przerwę, w której chcesz zagrać atom. Przerwy są jak pomiędzy każdym atomem, tak:
atom 0, GAP 0, atom 1, GAP 1, atom 2, GAP 2... atom n, GAP N(
gap nwskazuje, że chcesz umieścić atom międzyatom 1i atomn) Więc wyślij,2jeśli chcesz zagrać atomgap 2.
- Jeśli atom ma być odtwarzany na atomie:
- Wyjmij atom, na którym chcesz grać, więc
2jeśli chcesz grać na atomieatom 2.
- Wyjmij atom, na którym chcesz grać, więc
- Jeśli atom jest
-:- Wyjmij atom, na którym chcesz go zagrać, następnie spację, a następnie
y/nwybór zamiany atomu na+później, więc2, "y"jeśli chcesz zagrać atomatom 2, a chcesz go zamienić na+. Uwaga: wymaga to 2 danych wejściowych zamiast 1.
- Wyjmij atom, na którym chcesz go zagrać, następnie spację, a następnie
Przykładowe wyniki:
(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)
- Aby uczynić pracę bota, trzeba udać się do
Popenbitu (w całym końcu kodu) i zastąpić go co sprawia, że Twój program uruchamiany jako listy pythonic (więc jeśli program jestderp.javawymienić["python", "bot.py"]z["java", "derp.java"]).
Specyfikacje specyficzne dla odpowiedzi:
- Umieść cały kod swojego bota w odpowiedzi. Jeśli nie pasuje, to się nie liczy.
- Każdy użytkownik może mieć więcej niż 1 bota, jednak wszyscy powinni znajdować się w osobnych postach z odpowiedziami.
- Nadaj też botowi nazwę.
Punktacja:
- Bot z najwyższym wynikiem wygrywa.
- Twój bot zostanie przetestowany na 20 gier, a końcowy wynik to średnia z 20 gier.
- Remis będzie czasem przesłania odpowiedzi.
Twoja odpowiedź zostanie sformatowana w następujący sposób:
{language}, {bot name} Score: {score}
Powodzenia!
input_atom\natom0 atom1 .... atomn\nDla STDIN
+na liście elementów, ale nigdzie nie ma go w opisie tekstowym
+przez-pracę atomu? Jeśli wybierzeszy, czy zagwarantujesz sobie+następny ruch?