Envahisseurs de l'espace proto
Il s'agit d'un défi de sortie graphique où la tâche consiste à donner le code le plus court par langue.
Tâche
Votre code doit permettre à l'utilisateur de déplacer l'étranger suivant sur l'écran / la fenêtre.
Votre code peut simplement le charger à partir d'un fichier local. N'hésitez pas à le convertir dans un autre format d'image standard ou même à corriger les petites erreurs de pixels de l'image qui ont été signalées dans les commentaires.
L'arrière-plan doit être blanc et la fenêtre / l'écran doit mesurer au moins 400 pixels sur 400 pixels. Si votre langue ne prend pas en charge les fenêtres / écrans de cette taille, utilisez la plus grande taille qu'elle prend en charge tant qu'elle n'est pas inférieure à 200 par 200.
Pour déplacer l'étranger sur l'écran, le code doit prendre en charge haut / bas / gauche / droite en utilisant les touches fléchées d'un clavier standard.
Votre code doit être un programme complet .
Restrictions / contraintes
L'étranger devrait s'arrêter aux frontières. Il doit également se déplacer à une vitesse uniforme en douceur sans scintillement ni bégaiement visible et être affiché à au moins 24 images par seconde. Cela devrait prendre entre 2 et 5 secondes pour passer d'un côté de l'écran / fenêtre à l'autre.
Langues et bibliothèques
Vous pouvez utiliser n'importe quelle langue ou bibliothèque que vous aimez (qui n'a pas été conçue pour ce défi). Cependant, j'aimerais pouvoir tester votre code si possible, donc si vous pouvez fournir des instructions claires sur la façon de l'exécuter dans Ubuntu, ce serait très apprécié.
Catalogue
L'extrait de pile au bas de cet article génère le catalogue à partir des réponses a) en tant que liste des solutions les plus courtes par langue et b) en tant que classement général.
Pour vous assurer que votre réponse s'affiche, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:
## Language Name, N bytes
où N
est la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou que vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:
## Perl, 43 + 2 (-p flag) = 45 bytes
Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de code:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 62426; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 9206; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>
Réponses:
Scratch ,
221217 octetsCliquez sur l'image pour la voir en action. Le mouvement est déterminé par les frappes , il sera donc plus fluide plus la répétition des touches est rapide.
L'image est incluse dans le projet, mais les octets de grattage sont généralement comptés à partir de la représentation textuelle du golf , par cette méta-publication . S'il y a désaccord quant à savoir si cela est acceptable (ou si le mouvement est assez fluide), faites-le moi savoir et j'essaierai de le contourner.
la source
Traitement 2,
219 199 241 220219 octetsNécessite l'image enregistrée comme
.png
dans le même répertoire que le .pdela source
Python 2,
262253246240 octetsSensationnel. Quel beaucoup de piratage.
Utilise le module 'pygame' disponible sur http://pygame.org .
Explication
key.set_repeat(1)
- Envoyer des événements clés répétés via le système d'événements toutes les millisecondesc=d.set_mode((400,)*2)
- Créez la surface d'affichage 400x400while c.fill((255,)*3):
- Effectivementwhile 1:
mais efface également l'écrane=event.get(2);c.blit(image.load("I"),p);d.flip()
- Ne collectez que les événements du clavier, chargez l'image stockée dans un fichier png appeléI
et dessinez-la. Mettre à jour l'écranif e:x=e[0].key+1;q=x&2;b=q/2;p[b]=max(0,min(336+b*16,p[b]+(1-q)*(1-(2*x&2))))
- S'il y a eu un événement, déterminez quelle touche fléchée a été enfoncée (fait des trucs bizarres si vous appuyez sur d'autres touches), puis changez la position de la surface en fonction de la touche sur laquelle vous avez appuyé.la source
Haskell, 410 octets
L'image de l'étranger est attendue dans un fichier nommé
b
au.bmp
format.Je suis nouveau dans la bibliothèque Gloss, donc ce n'est peut-être pas optimal. Est-ce que quelqu'un sait si je peux vérifier si une touche est enfoncée au lieu du suivi
KeyUp
/ desKeyDown
événements?Comment ça marche: les quatre derniers paramètres de
play
sont l'état du monde (initialisé avec((0,0),id)
, une fonction pour dessiner une image d'un état (#
), un gestionnaire d'événements (e
) et une fonction qui change l'état au fil du temps (%
).L'état est une paire de coordonnées xy et une fonction sur la façon de les changer à chaque
%
appel.#
déplace le bitmap (b
) vers les coordonnées actuelles et le dessine.e
recherche lesKeyDown
événements des touches de curseur et définit les fonctions appropriées dans l'état ou pourKeyUp
n'importe quelle touche pour réinitialiser la fonction dans l'état à la fonction d'identité.%
applique la fonction de l'état aux coordonnées actuelles et vérifie les limites.la source
Orme, 240 octets
Essayez-le ici . Le nombre d'octets est après avoir remplacé l'URL par
.png
.la source
AutoIt ,
269267 octetsNécessite que l'image soit enregistrée en tant que b.bmp dans le répertoire de script. Si vous souhaitez utiliser une image avec une transparence réelle, vous devez la convertir du PNG en un bitmap 32 bits (OT: un format vraiment peu apprécié).
Explication
Nous devons importer
Misc.au3
pour y accéder_IsPressed
. Une fonction qui accepte un code de touche et renvoieTrue
ouFalse
lorsque la touche est enfoncée.La spécification du défi est assez cool dans la façon dont nous devons créer une fenêtre carrée de 400 pixels. Les paramètres de taille par défaut (désignés par
-1
ouDefault
) sont 400x400. Le style de fenêtres étendues est défini sur34078728
. Cela force la fenêtre à être tamponnée deux fois et dessinée de bas en haut. Ceci est nécessaire pour éliminer le scintillement selon l'exigence de défi. Dans Windows 10, cette combinaison inhabituelle (et quelque peu non documentée) de styles brise la barre de titre de la fenêtre (tous les effets de survol sont désactivés).$1
et$2
sont déclarés et contiendront les décalages x et y de l'image chargée par le contrôle$0
.$3
devient un pointeur sur la fonction_IsPressed
pour raccourcir considérablement le code.Puisqu'il n'est pas nécessaire de pouvoir quitter le programme, ce script s'exécute dans une boucle infinie (
Until 0
).$1+=$3("27")-$3("25")
abuse du type de données variant dans AutoIt en transtypant dynamiquement la valeur booléenne renvoyée de_IsPressed
en un entier qui peut être ajouté ou remplacé par le décalage x. Idem pour y.$1=($1>336)?336:($1<0)?0:$1
utilise l'opérateur ternaire connu des langages de type C pour effectuer une vérification des limites afin d'arrêter l'étranger aux frontières.GuiCtrlSetPos
déplace le contrôle d'image vers les nouvelles coordonnées.Voici une capture d'écran avec un extraterrestre transparent (vous pouvez même vous déplacer en diagonale):
la source
Lua + LÖVE, 291 caractères
Cela utilise une fenêtre 400 x 400 non redimensionnable. Je n'ai pas réussi à régler
love.keyboard.setKeyRepeat()
pour accélérer la lecture des clés, j'ai donc fait la méthode recommandée, en interrogeant l'état de chaque touche.Comme ma relation avec Lua
for
n'est pas la meilleure, ni cette fois-ci n'a réussi à raccourcir la boucle que le codage en dur de l'état de chaque clé.la source
SpecBAS -
285255 octetsCharge l'image - la couleur 15 est d'un blanc brillant, de sorte qu'elle devient transparente.
L'utilisation de l'image d'origine et de la palette SpecBAS par défaut a rendu la chose un peu étrange, donc la ligne 2 les fait basculer pour correspondre à l'image d'entrée. L'image ci-dessous montre à quoi cela ressemble sans la ligne 2 et après.
La commande CLAMP limite le graphique entre 1 et 400 dans les deux sens, enregistre plusieurs instructions IF ... THEN.
La ligne 9 attend juste que les choses se rattrapent et empêche le scintillement.
Il se déplace d'un pixel à la fois sur la base d'une vérification booléenne de la touche enfoncée, ce qui prend un peu plus de 5 secondes pour aller d'un côté à l'autre.
la source
Rubis avec des chaussures,
252243 caractèresCela utilise une fenêtre redimensionnable à partir de 600 x 500 par défaut. Si vous redimensionnez la fenêtre de sorte que l'envahisseur soit laissé de côté, il reviendra lorsque la touche de mouvement suivante sera enfoncée.
L'astuce pour satisfaire aux exigences est que la position de l'envahisseur est modifiée par incréments de 4, mais le mouvement réel est effectué avec un incrément de 1 à 99 images par seconde.
la source
Tcl / Tk , 242 octets
la source
invaders.tcl
; vous devez également enregistrer l'image comme.png
dans le même dossier. Pour exécuter le script, tapezwish invaders.tcl
dans un shell. PS: Il peut être plus pratique si le code est plutôt collé dans un shell interactif, car il prend en charge les commandes abrégées par défaut.JavaScript (en utilisant paper.js), 215 octets
paper.js est un framework graphique JS, ce qui signifie qu'il comporte de nombreuses fonctionnalités utiles concernant la manipulation d'images. Pour exécuter, copiez simplement ce qui précède dans la section de gauche ici , puis, pour déplacer l'étranger, cliquez une fois dans la section de droite pour lui donner le focus. Si votre navigateur peut le gérer, il devrait fonctionner à 60 ips.
la source