Votre tâche consiste à créer un bot qui joue Atomas , avec le meilleur score.
Fonctionnement du jeu:
Le plateau de jeu commence par un anneau de 6 "atomes", avec des nombres allant de 1
à 3
. Vous pouvez "jouer" un atome entre deux atomes, ou sur un autre atome, selon l'atome lui-même.
Vous pouvez soit avoir un atome normal, soit un atome spécial.
L'atome normal:
Vous pouvez jouer un atome normal entre deux atomes disponibles sur le plateau.
Vous commencez avec des atomes dans la plage 1 to 3
, mais la plage augmente de 1 une fois tous les 40 mouvements (donc après 40 mouvements, la plage devient 2 to 4
).
S'il y a des atomes sur la carte qui sont inférieurs à la plage, il a une 1 / no. of atoms of that number on the board
chance de se reproduire.
Disons que vous avez un 2
jeu à jouer, et le tableau ressemble à ceci:
1 1 2 1
Plaçons le 2
à droite de la 1
.
Le tableau devient maintenant:
1 1 2 1 2
Remarque: la carte s'enroule, donc l' 1
extrême gauche est en fait à côté de 2
l'extrême droite. Ce sera important plus tard.
Il existe 4 types d'atomes "spéciaux", à savoir:
L' +
atome:
Cet atome se joue entre deux atomes. Il a 1 chance sur 5 de se reproduire.
Si les atomes des deux côtés de l' +
atome sont identiques, la fusion se produit. Voici comment ça fonctionne:
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.
Exemple:
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].
Si les atomes des deux côtés de l' +
atome sont différents, alors les +
restes sur le plateau.
Exemple:
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)
L' -
atome:
Cet atome est joué sur un autre atome. Il a 1 chance sur 10 de se reproduire.
L' -
atome supprime un atome de la carte et vous donne le choix entre:
- jouer l'atome retiré le tour suivant, ou
- transformez-le en atome + pour jouer le tour suivant.
Exemple:
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)
L' +
atome noir ( B
):
Cet atome se joue entre 2 atomes. Il a 1 chance sur 80 de se reproduire et n'apparaît qu'une fois votre score> 750.
Cet atome est fondamentalement le même que l' +
atome, sauf qu'il fusionne deux atomes ensemble, même +
des atomes . À partir de là, il suit la +
règle (il ne fusionne les atomes que si les atomes des deux côtés de l'atome fusionné sont égaux).
L'atome fusionné résultant du noir +
est égal à:
- l'atome de nombre le plus élevé dans la fusion + 3
4
si les deux atomes fusionnés sont+
de
Exemple:
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)
Un autre exemple:
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)
L'atome clone ( C
):
Cet atome est joué sur un autre atome. Il a 1 chance sur 60 de se reproduire et n'apparaît qu'une fois votre score> 1500.
L'atome clone vous permet de choisir un atome et de le jouer au tour suivant.
Exemple:
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
Voici ma version du jeu, en 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()
Comment fonctionne le robot:
Contribution
- Votre bot obtiendra 2 entrées: l'atome actuellement en jeu et l'état de la carte.
- L'atome sera ainsi:
+
pour un+
atome-
pour un-
atomeB
pour un+
atome noirC
pour un atome de clone{atom}
pour un atome normal
- L'état du conseil sera le suivant:
atom 0 atom 1 atom 2... atom n
, avec les atomes séparés par des espaces (atom n
revient àatom 1
, pour simuler un plateau de jeu "en anneau")
- Ces deux seront séparés par un
/
.
Exemples d'entrées:
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)
Production
Vous produirez une chaîne, en fonction de l'atome en jeu.
Si l'atome est destiné à être joué entre deux atomes:
Générez l'espace dans lequel vous voulez jouer l'atome. Les espaces sont comme entre chaque atome, comme ceci:
atom 0, GAP 0, atom 1, GAP 1, atom 2, GAP 2... atom n, GAP N
(
gap n
indique que vous voulez placer l'atome entreatom 1
et atomen
) Donc sortez2
si vous voulez jouer l'atome dessusgap 2
.
- Si l'atome est destiné à être joué sur un atome:
- Sortez l'atome sur lequel vous voulez jouer, donc
2
si vous voulez jouer sur l'atomeatom 2
.
- Sortez l'atome sur lequel vous voulez jouer, donc
- Si l'atome est un
-
:- Sortez l'atome sur lequel vous voulez le jouer, suivi d'un espace, suivi d'un
y/n
choix de transformer l'atome en un+
plus tard, donc2, "y"
si vous voulez jouer l'atomeatom 2
et que vous voulez le transformer en un+
. Remarque: cela nécessite 2 entrées, au lieu de 1.
- Sortez l'atome sur lequel vous voulez le jouer, suivi d'un espace, suivi d'un
Exemples de sorties:
(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)
- Pour faire fonctionner le bot, vous devez aller dans le
Popen
bit (à la fin du code) et le remplacer par tout ce qui fait que votre programme fonctionne comme une liste Pythonic (donc si votre programme l'estderp.java
, remplacez["python", "bot.py"]
par["java", "derp.java"]
).
Spécifications spécifiques à la réponse:
- Placez le code entier de votre bot dans la réponse. Si ça ne va pas, ça ne compte pas.
- Chaque utilisateur est autorisé à avoir plus d'un bot, cependant, ils doivent tous être dans des messages de réponse séparés.
- Donnez également un nom à votre robot.
Notation:
- Le bot avec le score le plus élevé gagne.
- Votre bot sera testé pendant 20 matchs, et le score final est la moyenne des 20 matchs.
- Le bris d'égalité sera le moment du téléchargement de la réponse.
Votre réponse sera donc formatée comme ceci:
{language}, {bot name} Score: {score}
Bonne chance!
input_atom\natom0 atom1 .... atomn\n
pour STDIN
+
dans la liste des éléments, mais cela ne se trouve nulle part dans la description textuelle
+
pour un-
atome? Si vous avez choisi,y
serez-vous assuré d'obtenir un+
sur le prochain déménagement?