Une jolie visualisation des événements DOM. Il manque juste (ou je ne l’ai pas trouvé) un lien avec le code Javascript correspondant.






Pas forcément la meilleure, mais néanmoins une archive correctement navigable de cette excellente liste de discussion





Cette semaine, c'était le challenge Codingame de printemps.

Il s'agissait cette fois-ci de faire pousser des arbres, en évitant de subir l'ombre de l'adversaire. Et du fait du contexte épidémique actuel, je ne pouvais pas participer comme je l'aurai souhaité : j'ai arrêté de coder mercredi soir, et j'ai choisi très volontairement, de coder en Rust, qui n'est pas le langage le plus simple (franchement l'un des plus complexes que je connaisse, en fait).

Et comme un bonheur n'arrive jamais seul, les règles incluaient certains éléments qui ont clairement augmenté la complexité du problème.

  • D'abord le fait que le terrain soit hexagonal ajoute une complexité certaine : le stockage de données dans un tableau de tableaux n'est à priori pas utilisable (j'écris à priori très volontairement parce que je conservais, depuis Coders of the Carribean, un excellent article de référence sur la modélisation de terrains hexagonaux).
  • Par ailleurs, l'unité de tour de jeu, le jour, n'est en fait pas atomique : les deux joueurs vont effectuer alternativement autant d'opérations qu'ils le peuvent, en continuant même si l'adversaire n'a plus d'actions possibles. Pour moi, ça a ajouté beaucoup de complexité.
  • En plus, chaque joueur a deux échelles à optimiser : le nombre de points de soleil produits chaque jour, et le score final (qui dépend des arbres récoltés, de leur ordre de récolte et de la position de la récolte).

Franchement, quand on ajoute tout ça, ça donne un résultat facilement complexe. Et comme je n'avais aucune intuition géniale, j'ai utilisé un modèle de programmation hyper classique (pour moi) :

  1. Décrire chaque entité du jeu dans un type (on a donc une Action qui est un enum Rust, un struct pour chaque arbre, et enfin un modèle représentant le terrain). Petite subtilité : j'avais commencé par représenter le terrain via l'une des structures indiqué dans l'article mentionné plus haut, avant de me rendre compte que le moteur de jeu fournissait la géométrie du terrain au démarrage, du coup, il était bien plus simple de simplement stocker la géométrie dans un Vec, et le contenu dans un autre Vec.
  2. A partir de là, déterminer toutes les actions possibles
  3. Éliminer les actions dont le coût est supérieur aux points de soleil disponilbe
  4. Et trier les actions selon une heuristique

Avec ça, j'arrive à cette solution qui atteint le niveau argent. Pas trop mal en sachant que j'ai arrêté de coder mercredi ...

Bon, là; je me donne des excuses faciles.

En vérité, je savais dès Lundi, en particulier à la lecture de cet article sur les échecs "A step-by-step guide to building a simple chess AI" que ce que je faisais n'avait pas du tout les moyens d'atteindre le haut niveau. Sauf que j'ai été intellectuellement bloqué par le fait que ce que je voyais comme l'unité de durée du tour (la journée) ne l'était pas. Et je pense sincèrement que c'est un blocage psychologique stupide de ma part. Ca veut dire quelque chose sur moi, et quelque chose de pas très chouette (mais que je sais déjà). J'ai bien l'impression d'être incapable de tenter des solutions authentiquement innovantes (pour moi) quand je suis pris par la pression du temps. Pour le dire autrement, le biais d'ancrage est fort. Suffisamment fort pour que, la prochaine fois que je suis tenté de faire un challenge codingame, je m'oblige à utiliser ces fameuses techniques de Monte-Carlo, de min-max et autres, qui impliqueront des solutions pas forcément répétables, mais ça n'est pas trop grave.

Parce qu'il y a quand même des choses qui ont bien marché !

J'ai enfin réussi à comprendre le sens des lifetimes Rust ! Et ça implique que j'ai réussi à écrire du code avec beaucoup moins de clone(). Et ça implique à son tour que ce code, qui certes ne fait pas grand chose, est beaucoup plus efficace que mes précédentes solutions.

En bonus, mon article précédent expliquant comment démarrer une solution Rust m'a vraiment beaucoup aidé : je n'ai eu aucun mal à produire une solution raisonnablement intéressante.

Bref, j'ai encore appris beaucoup sur moi, et c'est ce que je demande à Codingame !





Un site marrant qui résoud des labyrinthes …​ uniquement de façon décorative. C’est amusant.



Je pense que vous vous en doutez, je suis d’accord avec ce qu’écrit ce site. Le mail a actuellement deux problèmes : des logiciels à l’ergonomie datée, et un support impossible du chiffrement.




Sapristi ! C’est une sacrément belle attaque du poste de dév ! (en vérité, c’est plus une exploitation du Rust Server Protocol, à mon sens)





La magie d’internet se trouve dans ce genre de truc bien planqué : on ne comprend pas pourquoi ces vidéos sont tournées, ni par qui. Et elles ont l’air presque assez fausses. C’est fou.


Je crois qu’il va bien falloir que je comprenne comment marche escalidraw, parce que ça m’a l’air riche de possibilité (évidement, il faudrait que j’arrive à le brancher à Structurizr)


Pour ceux qui ne savent pas de quoi je parle, j'ai un projet de lifestream sur lequel je travaille depuis des années (les archives du tag remontent à 2010 au moins). ce projet a connu plusieurs incarnations. La dernière était un ensemble de plugins maven générant des fichiers Asciidoc que je passais ensuite dans un plugin JBake pour générer un site statique. Sur le papier, l'idée était chouette.

Mais le vrai problème d'un projet de développeur, c'est de le faire survivre à la prod. Mon choix pour la prod était de tout faire tourner sur mon Raspberry, parce qu'il tourne, et que je m'attache de plus en plus à limiter mon empreinte carbone numérique. Sauf que le Raspberry 3 a une mémoire limitée, et que mon lifestream comprend quelques fichiers :

  • 2200 fichiers générés depuis Goodreads
  • 8400 fichiers générés depuis Shaarli
  • 1300 fichiers depuis Wordpress

Ca fait un bon paquet, et même en essayant d'optimiser les choses, je n'arrive pas à générer un site viable. Qu'est-ce que je peux faire maintenant ?

  • La solution la plus simple serait de changer de machine de génération : faire ça depuis un vrai ordinateur (comme par exemple celui depuis lequel j'écris cet article) avec une belle quantité de RAM me sortirait cette épine du pied
  • Une autre solution serait d'abandonner le site statique pour passer à un site dynamique ... mais ça m'embête beaucoup

Parce que l'un des prérequis de ce lifestream est d'être hébergé dans les pages perso de free.fr. Pourquoi ? Parce que c'est une solution performante :

C:\Users\nicolas-delsaux>hey http://nicolas.delsaux.free.fr/lifestream/

Summary:
  Total:        6.2935 secs
  Slowest:      4.1379 secs
  Fastest:      0.3488 secs
  Average:      1.0254 secs
  Requests/sec: 31.7790

  Total data:   6755645 bytes
  Size/request: 33778 bytes

Response time histogram:
  0.349 [1]     |
  0.728 [104]   |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  1.107 [38]    |■■■■■■■■■■■■■■■
  1.486 [22]    |■■■■■■■■
  1.864 [13]    |■■■■■
  2.243 [6]     |■■
  2.622 [6]     |■■
  3.001 [1]     |
  3.380 [2]     |■
  3.759 [4]     |■■
  4.138 [3]     |■

Vous pouvez faire le test de chez vous, vous aurez normalement d'assez bonnes performances. Malgré la lenteur des machines de free.fr. Et ça, c'est un des plus importants objectifs de ce projet.

Du coup, je pense que la prochaine étape devrait tout simplement être de déplacer la génération vers mon ordinateur de bureau, avec une quelconque solution de tâche planifiée pour Windows ... Je vais néanmoins ajouter l'écriture des fichiers dans un repository GitHub, pour faciliter la réutilisation, et travailler sur l'écriture dans un outil comme AsciiBlog. Ou alors tenter de générer le site dans GitHub Pages, ce qui pourrait aussi être chouette (même si ma 1/2 heure de génération JBake ne risque pas d'être compatible avec GitHub Actions). Bref, j'ai encore des idées...


C’est vrai que ces histoires de tab vs space, franchement, on n’en a strictement rien à foutre : n’importe quel 'éditeur moderne doit être capable de faire la conversion, et les interpréteurs/compilateurs y sont la plupart du temps insensibles.



https://twitter.com/Cap_x_Ace/status/1393212997452148739[Cappu qui dort mal sur Twitter : "On va revenir sur l’autre bunker spatial et son énième tweet qui pue la merde parce que ça me concerne personnellement et apparemment on en est à raconter des expériences personnelles, let’s go dans la fosse septique de twitter 👍 https://t.co/OGdBQTqVGu" / Twitter]

En ces fins de quinquennat de la start-up nation, quelques rappels utils


Un outil de mapping conceptuel. Ca a l’air intéressant. Mais est-ce plus intéressant que de simplement créer une carte graphviz ? (en tout cas, c’est sans doute plus facile à éditer)







Me voilà obligé de créer un fichier .mvn/jvm.config …​ Tout ça pour compiler du GWT. Ce serait drôle, si ça n’était pas triste!


Cette histoire des statistiques de contamination en extérieur par le coronavirus est intéressante, et traduit le problème de la traduction, et les défauts de la science sans recul.


https://fumbbl.com/p/games[FUMBBL

Online Blood Bowl League]

Le saviez-vous ? OpenJNLP est encore utilisé pour suivre les matches de BloodBowl en direct. C’est cool !



Deux choses frappantes dans cette analyse de texte formidable. 1. Il est clair que Darmanin applique aux musulmans ce que Napoléon appliquait aux juifs 2. Je découvre que la fondation d’Israël était appuyée par les antisémites


C’est marrant cet outil de sélection de police basé sur le "caractère" de la police



Attends, un moteur de blog utilisant Quarkus et Asciidoc ? Ca pourrait complètement changer ma vision de mon lifestream (au sujet duquel un article de blog serait peut-être utile)







Une ligne de commande d’accès à pas mal de bases de données relationnelles ou pas. Et même si la ligne de commande, j’aime généralement pas, c’est quand même cool dans un conteneur.


Je trouve l’histoire assez terrifiante. Pour ma part, mes sessions de pair ne durent jamais plus de deux heures. Et après, on repart bosser chacun de notre côté …​


Review

Dans ce roman, on suit les passagers d'un vaisseau générationnel - l'un de ces vaisseaux où les voyageurs vivent pendant plusieurs générations avant d'arriver à destination. Evidement, le roman commence quand le vaisseau approche de son objectif. Mais, parce qu'il y a un mais, la colonisation s'avère impossible (à cause d'un micro-organisme tueur). Ca va entraîner la division dans les colons, et certains vont prendre le chemin du retour vers la Terre. Et d'une façon inhabituelle, ce sont ces passagers que nous allons suivre.
J'ai trouvé ce roman très intéressant.
Bien sûr, je savais déjà que l'auteur était brillant, et que ce qu'il écrivait était souvent de la plus grande intelligence, même si il y avait parfois une certaine sècheresse dans le propos. Qui plus est, le fait que l'auteur choisisse comme personnage principale non pas l'ingénieure géniale, mais sa fille Kerya qui nous est présentée comme limitée, voire un peu bête par rapport à sa mère. Autant dire qu'à la fin du premier chapître, je me demandais vraiment où le roman s'en allait.
Mais la littérature est toujours pleine de surprises. En effet, l'approche de la planète Aurora, qui donne le titre au roman, permet à Kerya de révéler peu à peu une certaine forme d'intelligence relationnelle, qui fait d'elle, malgré ce qu'elle prétend, le leader des habitants de ce vaisseau.
Vaisseau qui est d'ailleurs la plus grande surprise de ce roman.
Parce qu'en le commençant, je pensais lire un récit de terraformation. Et au vu de sa trilogie martienne, c'aurait été un bon roman. Mais en fait, ce retour à la Terre donne l'occasion à l'auteur de développer dans une longue section centrale le rôle de ce vaisseau, qui n'est clairement pas qu'un véhicule, puisqu'on comprend rapidement qu'il est le narrateur de tous les chapitres, sauf le dernier. Et ce narrateur/vaisseau a une vie absolument extraordinaire, sans parler de ses évidentes capacités d'intelligence artificielle. Par conséquent, ce voyage retour, malgré l'horreur qu'il m'a inspiré quand les humains ont peu à peu détruit leur environnement, a été aussi un moment de rêve à partir du moment où les passagers ont été passé en hibernation.
Parce que les interrogations sur la conscience de cette IA sont fascinantes. Et son arrivée dans le système solaire est le genre de morceau de bravoure dont la SF est coutumière, mais qui ne cessent de me faire rêver.
Hélas, le dernier chapitre, faisant reprendre à Kerya contact avec la Terre mère, m'a paru particulièrement difficile à lire - malgré cinq dernières pages qui m'ont fait rêver.
Autrement dit, c'est un roman qui m'a laissé une impression très contrastée, avec parfois dans le même chapitre des pages incroyablement chouettes, et trois pages plus loin un moment aussi pénible que peu utile. Et ça, franchement, ça rend les choses difficiles pour le lecteur, et ça me rend cette lecture difficile à conseiller pour les gens qui ne sont pas absolument fans des vaisseaux spatiaux.



Vu la richesse du contest codingame du moment, il semble que s’inspirer des IA d’échecs puisse être une bonne idée



J’aime beaucoup l’abstract qui explique que les décisions algorithmiques doivent pouvoir être justifiables.


Review

Je n'ai pas lu de bouquin de jeu de rôle depuis des années, mais j'y retrouve toujours cette espèce de folie du world-building où les auteurs créent des règles permettant le jeu abstrait.
Et je trouve la proposition de Dungeon World, et du système Apocalypse, assez séduisante, puisque les actions y sont assez vagues pour éviter les phases de combat complexes des jeux de rôles du siècle dernier.
Par ailleurs, le lien entre les joueurs et le monde est spécialement bien travaillé, avec un maître de jeu qui perd sa liberté démiurgique au profit d'actions qui le laissent à peu près aussi libre, mais qui ont l'avantage de donner une taxonomie à ce que peut faire le maître.
Enfin, le fait que les scénarios soient co-construits à travers les fronts est vraiment très intéressante. Et typiquement, le scénario livré avec le jeu est extrêmement léger.
Mais surtout, j'ai lu ce livre pour pouvoir utiliser tous les hacks Apocalypse World qui pullulent littéralement sur le web.
C'est néanmoins une lecture à réserver aux amateurs de jeu de rôle (évidement). Mais dans ce cadre, une bonne lecture.



Un moteur de recherche qui essaye de retourner les résultats qui ne sont pas dans Google. C’est cpnceptuellement intéressant.


Donc c’est un jeu d’exploration de donjon …​ Dans un document PDF …​ Je suis surpris









Si vous utilisez un miroir maven en http, la mise à jour vers maven 3.8.1 va vous faire de la peine. Heureusement, il y a une solution !


Evidement, je ne parle pas de jouer moi-même au pacman, mais plutôt de celui auquel il faut jouer dans le spring challenge 2020. Parce que comme j'ai l'intention de concourir dès demain, en essayant autant que possible de faire du Rust, j'ai essayé de me remettre à niveau en reprenant le problème précédent, et en essayant d'améliorer la solution dont je disposais déja. Et, comme vous pouvez le voir dans cette simulation, ça ne marche pas si bien. Avant d'aller plus loin, on va d'abord voir rapidement ce que fait mon robot.

Donc, à chaque tour

  • D'abord, je découpe le terrain (autrement dit, je construis un pavage du plan) pour disposer pour chaque pac d'un terrain disjoint.
  • Et ensuite, pour chaque pac, je score chaque déplacement en fonction des pillules atteignables au 7 prochains tours.

Il y a un certain nombre de choses qui ne sont pas implémentées, et c'est normal : je ne gère pas les ennemis, ni les changements de couleur, ni même le boost. Bref, c'est pas le niveau argent ...

Cela dit, mon robot est bien plus mauvais que simplement parce qu'il n'implémente pas ces fonctionnalités. Ce qui le rend vraiment mauvais, c'est qu'il privilégie l'accessoire à l'essentiel. Parce que dans ce jeu, il y a deux choses essentielles :

  1. Survivre à l'adversaire
  2. Manger les grosses pilules

Et mon code n'essaye de faire aucun des deux ... Bon, c'est con. Et, pire que tout, il n'est même pas performant, sans doute parce que le pavage du plan est assez consommateur en temps. Bref, la prochaine fois que je voudrais m'y mettre, je pense que je suis bon pour ... supprimer tout le code existant et tout refaire, tout simplement. J'ai donc appris un certain nombre de choses. La plus importante étant que faire du code performant en Rust ... c'est pas facile du tout. Lisez donc tranquillement cet article Moves, copies and clones in Rust, et vous comprendrez que l'impact de la sécurité mémoire sur le code écrit est loin d'être négligeable. Et je trouve ce problème assez ... stimulant (même si ça me donne parfois l’impression d'avancer avec un boulet au pied).



Est-ce qu’on peut dire que c’est un poil gênant ? (et qu’en plus ça ressemble exactement à du matériel à usage principalement illégal)





Bon, je voulais installer vega-cli sous Windows, qui dépend de canvas. Mais là, je vais être brutal, mais allez bien vous faire foutre.



Suite à mon précédent article un poil critique sur la revue de code, j'ai eu droit à une question intéressante de la part de mon collègue Douglas

La première chose à noter dans cette question, c'est l'insistance sur le fait que les développeurs ne connaissent pas forcément le produit sur lequel ils travaillent. Et c'est parfaitement vrai.

Donc, ça veut dire quoi "concevoir un développement" ? Il s'agit tout simplement de jouer, pour un développement particulier, le rôle de l'architecte. Et là, je n'aide personne, puisque le rôle de l'architecte est particulièrement flou dans le monde du logiciel. Néanmoins, pour une fois, je pense que la définition de Grady Booch est appropriée :

Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.

Grady Booch - On design (voir aussi Software Architecture and Related Concerns)

Donc, quand on joue le rôle d'architecte pour un développement, c'est-à-dire qu'on le conçoit, on doit se poser les questions concernant les changements significatifs qu'on va apporter au système. Et pour revenir à la question de Douglas, c'est une excellente façon de découvrir le système et de le comprendre. Autrement dit, je propose d’utiliser ces phases de conception pour prendre le temps de découvrir ce qu'on va modifier.

Mais comment rendre cette connaissance partageable ? D'abord, via un support commun. Et si les issues des bugtrackers marchent bien pour discuter de petites modifications, je trouve que, pour les gros développements, il vaut parfois mieux créer un vrai document de conception qu'on mettra avec la documentation d'architecture - dans la section ADR. Sauf que j'aurais tendance à ne pas formaliser mon ADR aussi simplement que ce que proposent les différents modèles. Non, à titre personnel, j'aurais plutôt tendance à présenter le problème, puis la description de la solution en reprenant justement le plan de l'agile architecture documentation. Parce qu'il permet précisément de segmenter le gros problème en ses différentes facettes.

Typiquement, une grosse fonctionnalité, une qui requiert une documentation spécifique, va avoir des impacts sur différents éléments du logiciel : l'architecture, les donnée,s le déploiement. Et ce modèle de document couvre correctement ces différentes questions, comme je l'ai déjà écrit. Qui plus est, il permet facilement l'amélioration collaborative : un premier rédacteur peut lancer ses idées, et les voir améliorées par un second rédacteur.

Ce qui permet quelque chose que je trouve de plus en plus souhaitable, aussi bien organisationnellement que techniquement : remplacer le synchrone par l'asynchrone via un support permanent, et constamment amélioré.

Pour l'écrire autrement, ce que je propose est assez simple : quand vous lancez un nouveau développement, demandez à un nouvel arrivant d'en faire la conception en suivant le modèle de l'agile architecture documentation, en commençant par un simple commentaire dans le bug tracker puis, si il s'avère que la fonctionnalité est trop importante, dans un document que vous placerez dans vos ADR. Et relisez ce qu'il produit avant de lancer le développement.



Une page bien complète de ressources sur l’inaltérable BloodBowl (comme j’ai acheté l’édition 1987 la semaine dernière, ça peut servir)




De l’art …​ dans le domaine public ! Ca fait toujours plaisir !



J’ai un collègue à qui ça pourrait plaire …​ personnellement, bon, j’ai déja du mal avec GTA, et avec le vélo. Alors les deux ensemble …​





OK, donc l’éditeur mis en cause pour une série d’actes de harcèlement sexuel n’a pas trouvé meilleure défense que de nommer chaque témoin, validant ainsi leurs témoignages. C’est ignoble, et stupide. Mesdames, vous avez toutes mon soutien (pour ce qu’il vaut)


La semaine prochaine, c'est le spring challenge !

Et comme l'année dernière, je vais essayer de le faire en Rust (un poil poussé par des collègues).

Mais contrairement à l'année dernière, j'essaye de préparer ma participation histoire de ne pas me faire avoir. Donc, voici une checklist de quelques détails utiles

  • Créer le projet cargo avec cargo init --lib . (pour créer une bibliothèque plutôt qu'un binaire). Tout le code sera dans le fichier lib.rs parce que je n'ai pas encore trouvé la bonne façon d'utiliser include!(...) pour avoir plusieurs fichiers.
  • Dans le dossier tests, créer un fichier design_tests.rs et un fichier integration_tests.rs
  • Aller chercher dans target/debug/deps les exécutables qui doivent s'appeler design_tests_{un hash pourri}.exe et integration_tests{un autre hash pourri}.rs pour créer les configurations de debug de VSCode
  • Le code doit avoir à peu près la forme suivante
    • Je lis les entrées
    • Je calcule mes sorties
    • IMPORTANT j'appelle la méthode qui génère le code du test d'ntégration
    • Et enfin je retourne ma sorte

Et avec ça, je devrais pouvoir coder assez rapidement, même si ça n'est pas automatique que ce que j'avais en Java.


Pourquoi ? Parce que dans les sphères de pouvoir médiatico-politiques, écrire un livre reste considéré comme bien et important. Du coup, dénoncer un éditeur, ça reste coton.




On serait pas à deux doigts de pouvoir créer des applications natives Windows en pur Rust ? En tout cas, on peut accéder aux API Windows …​




Sandy Petersen, c’est pas n’importe qui. Et sa mise au point est utile.


Le "it is just to confuse the americans" de la fin est absolument parfait. (et vous trouverez l’explication de l’accent circonflexe dans les commentaires).


Une évaluation poussée de la production de CO² par les différents moyens de transport. C’est assez intéressant. Hélas, il manque l’avion …​