Programmer une IA 2048 en utilisant un Framework existant

17

EDIT: Récemment, ma question a été proposée comme un double de 2048 Bot Challenge . Je voudrais souligner que cette question est différente de cette question et nécessitera que les réponses soient pensées différemment de cette question. 2048 Bot Challenge a demandé à l'utilisateur de créer un bot, et il serait exécuté pendant une heure, le score le plus élevé étant le score de l'utilisateur. De plus, il avait une limite de 555 octets. Mon défi exécute le code beaucoup moins fréquemment, seulement 3 fois. Votre score est calculé en utilisant le score moyen de ces trois fois et en divisant par la longueur des caractères de votre code joué. Ma question encourage les entrées à être «plus intelligentes» et à ne pas essayer d'obtenir le meilleur score par la force brute.

-

EDIT: La méthode get a été changée en getTile, pour éviter la confluence avec le mot clé JS get. De plus, une section de score élevé a été ajoutée.

Récemment, j'ai créé un site qui permet de contrôler le jeu populaire 2048 en utilisant JavaScript. Mon site est lié ici:

http://thatcoolidea.com/2048

Comment:

Un éditeur Ace est situé au-dessus du plateau. Vous y insérez du code, qui est exécuté une fois toutes les 250 ms, ou 4 fois par seconde. C'est ce qu'on appelle un cycle.

Utilisez les méthodes suivantes pour contrôler la carte. Vous ne pouvez pas utiliser les touches fléchées.

up();            //move up
down();          //move down
left();          //move left
right();         //move right

move(integer);   //integer is a direction. 0:up,1:right,2:down,3:left

getTile(y,x);        //gets the value of the tile in position y,x on the board. See diagram

Carte de bord pour la méthode get.

Les variables suivantes sont définies pour votre commodité:

eother        //boolean, alternates every cycle
frozen        //integer, counts how many cycles the board has remained stationary
lastDir       //integer, indicates the last direction that was tried to move in
              //uses same format as the move method above.
startup       //boolean, will always be true when the game first starts
              //you can change it as you wish
a
b             //a b and c are all persistant variables, they do not change each cycle
c             //any other variables defined in the cycle will be reset every time

Règles:

  • Pas de hasard, vous devez utiliser la logique. (Oui, je sais que l'exemple de code utilise aléatoire.)
  • Pas d'accrochage aux fonctions de jeu ni de tricherie autrement
  • En règle générale, essayez d'appeler une seule méthode de déplacement par cycle. C'est OK si vous en utilisez plus, mais ça se visse avec l'animation
  • Le plateau doit commencer dans un état aléatoire, aucune modification de l'état d'avant-match
  • Vous devez fournir à la fois la version non compressée et la version golfée du code dans votre message.
  • Vous devez fournir un lien vers le site qui charge déjà la version non compressée de votre code, diffusé via PasteBin (par exemple, ... thatcoolidea.com/2048?i=pH18GWtu charge l'exemple de code.)

Notation:

  • Votre code sera marqué par moi.
  • La partie A de votre score est une moyenne de 3 exécutions du code, arrondies vers le bas.
  • La partie B de votre score est la longueur des caractères de votre code golfé.
  • Votre score final est la partie A divisée par la partie B

Le gagnant verra son code immortalisé comme l'exemple de code sur le site, s'il le souhaite, et reconnu dans un commentaire dans le code.

Bonne chance! J'espère que vous apprécierez le défi.

Score actuel actuel 225,22 - Congélateur - user3217109

Sam Weaver
la source
10
Le fait que vous ayez écrit un cadre pour 2048 est assez génial et très pratique pour ce type de défi, mais je ne vois pas comment cela affecte réellement les stratégies déjà trouvées dans notre défi AI 2048 existant.
Martin Ender
3
Eh bien, je dirais que le mien est différent, simplement parce que vous devez utiliser une base de code qui sera la même à chaque exécution. C'est beaucoup plus convivial et je ne pense pas que cela constituerait un doublon.
Sam Weaver
2
L'autre question semble assez morte. Il n'y avait que quatre réponses et un délai d'une heure, donc je vais répondre parce que ça a l'air vraiment cool.
krs013
@samweaver ajoutez une note en haut de votre question pour expliquer pourquoi les réponses de l'autre question ne seraient pas valides / compétitives pour votre question, puis créez une méta-publication pour examen.
rdans
Si vous ne pouvez pas faire cela, vous devrez probablement changer votre défi afin de le rouvrir, par exemple règles / notation / restrictions
rdans

Réponses:

6

Sinker / Shaker, 65 octets

Voici le mien . C'est aussi simple et aveugle que possible.

if(startup){startup=false;a=0}b=(a++)%4;move(frozen>2?0:b==0?2:b)

Non compressé (ish) ...

if(startup){startup=false;a=0;}
b=(a++)%4;
move(frozen>2?0:b==0?2:b)

Il ne fait que répéter en bas, à droite, en bas, à gauche, etc. et frappe une fois s'il est bloqué. Il ne fait pas toujours très bien, mais il obtiendra parfois 512s. Mon score élevé lors des tests était de 7520.

krs013
la source
Je commence le processus de notation maintenant! Merci pour la première entrée!
Sam Weaver
Score final: 67,6! Exécution 1: 3980 Exécution 2: 4080 Exécution 3: 5128 J'ai vraiment aimé cela, je ne pensais pas que vous pourriez obtenir un score aussi élevé avec un si petit bot.
Sam Weaver
Merci de l'avoir installé! Je trouve que c'est plutôt cool. C'est triste que les gens aient réagi de cette façon jusqu'à présent. Les utilisateurs SO ont tendance à être très négatifs envers les questions en double, généralement pour de bonnes raisons.
krs013
Pourquoi merci! J'apprécie le soutien! Ce projet est né du fait qu'un ami et moi sommes restés tard au travail une nuit et que nous voulions voir qui pourrait faire le meilleur bot. J'ai cherché dans le code, mais je n'ai pas trouvé de moyen de bien le faire. J'ai construit cela avec les méthodes d'assistance pour le rendre tellement plus facile!
Sam Weaver
3

Feu de circulation - 23 21 octets

move(frozen&2|eother)

Voici le lien.

Celui-ci se déplacera alternativement vers le haut et vers la droite, sauf lorsque le plateau est resté immobile pendant les deux derniers mouvements, auquel cas il se déplacera respectivement vers le bas et vers la gauche.

Ma soumission originale, fonctionnellement équivalente, faisait 23 octets de long et a obtenu 182,72:

move((frozen&2)+eother)
moi et mon chat
la source
C'est à peu près la même chose que je fais quand je joue rapidement sans vraiment regarder le tableau.
moi et mon chat
Excellent travail. Exécution 1: 2208 Exécution 2: 1216 Exécution 3: 2336 23 octets Score final: 182,72
Sam Weaver
2

Whirlpool - 37 21 17 octets - Score: 211,22

J'ai décidé d'adopter une approche «moins c'est plus». Mon code est un design simple qui essaie de monter, de droite, de bas, de gauche ... Je vais travailler sur une IA d'apprentissage pour voir une façon plus optimale d'aborder le puzzle.

a=a|0;move(a++%4)

L'optimiseur a contribué à raccourcir al'initialisation de.

Sam a aidé à raccourcir al'initialisation de, supprimé var.

Ungolfed?

var a=a|0;
a++;
move(a%4);

Mon meilleur score avec cette IA est 5120.

Congélateur - 12 octets - Score: 225,22

Ce bot a la priorité de déplacement. Il essaie de monter. Si ça peut monter, ça va bien. Si ça ne peut pas aller correctement, ça baisse. S'il ne peut pas descendre, il va à gauche.

move(frozen)

Explication de James Bond

Le code crypté déchiffre pour dire:

HTMLActuator.prototype.updateScore=function (score) {score*=9989800000;
  this.clearContainer(this.scoreContainer);

  var difference = score - this.score;
  this.score = score;

  this.scoreContainer.textContent = this.score;

  if (difference > 0) {
    var addition = document.createElement("div");
    addition.classList.add("score-addition");
    addition.textContent = "+" + difference;

    this.scoreContainer.appendChild(addition);
  }
}

L'optimiseur aurait dû jouer à son code déchiffré. Cela aurait pu être #Optimisé.

Zylviij
la source
Vous devez en fait définir aaussi. Cela devrait donc être ajouté dans la longueur du code.
Optimizer
Malheureusement, le backend préserve les variables par le biais de réinitialisations, vous pouvez donc définir / initialiser aune fois et l'oublier, mais si vous fermez l'onglet / fenêtre et y revenez, je ne pense pas que cela fonctionnera plus. C'est pourquoi j'ai dû ajouter le bit if (startup) sur le mien.
krs013
1
vous pouvez utiliser var a=a|0;move(a++%4)- 21 octets
Optimizer
Je vous remercie! Je n'ai jamais utilisé javascript auparavant, donc je vais faire des erreurs comme ça ...
Zylviij
En fait, A n'a pas besoin d'être défini. A est défini dans le backend, vous pouvez donc le référencer en utilisant juste asans fairevar a
Sam Weaver
1

Cintre - 20 octets

Score officiel: 224,87 - 2e place par 0,35 points

Ce bot utilise l'approche vers le bas, la gauche, le bas et la droite, mais avec la caractéristique inhabituelle qu'il ne montera jamais. Je ne sais pas comment noter les cas où il se bloque et ne se termine pas, ni si le fait que cela se produit le rend illégal. Le voici, cependant:

b=b|0;move(b++%4||2)
OR
move(startup++%4||2)

Schéma d'initialisation grâce à @Optimizer.

Au cours de mes 3 tests, il a obtenu 4284, 6352 et 4232, pour une moyenne de 4956. Je mettrai à jour lorsque le test officiel sera exécuté.


Version alternative qui sort des blocages (27 octets):

b=b|0;move(b++%4||b%997&&2)
isaacg
la source
Pas besoin de laisser un coup, le score y sera simplement mesuré comme si la partie était terminée.
Sam Weaver
Comment le dernier sort-il des blocages?
krs013
@ krs013 Le dernier montera une fois tous les 4 * 997 cycles, donc si up est la seule façon de se déplacer, il montera.
isaacg
Je t'ai eu. Je me demandais si c'était quelque chose comme ça; Je n'ai juste pas attendu assez longtemps, je suppose.
krs013
Score final: 224,87, excellent travail!
Sam Weaver