<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
<?xml-stylesheet type="text/css" href="http://awesom.eu/~cygal/styles/feed.css"?>


<title type="html">Random Thoughts</title>
<subtitle type="html">nouvelles, réactions échouées, whatever</subtitle>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal"/>
<link rel="self" type="application/atom+xml" href="http://awesom.eu/~cygal/atom.xml"/>
<updated>2010-05-20T10:22:01+02:00</updated>
<author>
<name>cygal</name>
<uri>http://awesom.eu/~cygal</uri>
</author>
<id>http://awesom.eu/~cygal/</id>
<generator uri="http://nanoblogger.sourceforge.net" version="3.4.1">
NanoBlogger
</generator>

<entry>
<title type="html">Fair votes now!</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/05/11/fair_votes_now/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/05/11/fair_votes_now/index.html</id>
<published>2010-05-11T00:11:45+02:00</published>
<updated>2010-05-11T00:11:45+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<strong>Mise à jour :</strong> une entente semble avoir été trouvée, ce sera bien un <a href="http://www.telegraph.co.uk/news/newstopics/politics/david-cameron/7714051/Coalition-Government-David-Cameron-and-Nick-Clegg-get-to-work-in-Downing-Street.html">hung parliament avec Cameron et Clegg</a>.
<br /><br />
<div style="float:right; margin:10px"><img src="http://awesom.eu/~cygal/images/fair_votes_now/parliament.jpg" alt="The Houses of Parliament, seen across Westminster Bridge. Wikeipedia" /></div>
<br /><br />
Si vous vous êtes intéressés de loin à l'actualité internationale de ce début de mois de mai 2010, vous avez peut-être entendu parler des élections tenues au Royaume-Uni et des nombreux débats qui ont suivi. Il faut d'abord comprendre le contexte de ces élections, ce que je vais commencer par rappeller brièvement, avant d'expliquer la raison du tumulte actuel.
<h4>First-past-the-post</h4>
<br /><br />
Les élections du 6 mai visent à renouveller le parlement et ses 650 sièges tenus par des "MP", "Member of Parliament". Chaque siège correspond à une constituency, une région délimitée géographiquement du Royaume-Uni. Pour gagner l'élection dans une "constituency", il suffit simplement de gagner au premier tour. Quels sont les avantages et inconvénients de ce système archaique ?
<br /><br />
<ul>
        <li>Avantages :
                <ul>
                        <li>Ce système avantage un pouvoir fort : les partis majoritaires ont plus de chance d'avoir un peu plus de voix et donc de gagner de nombreux sièges là où un deuxième tour les aurait fait perdre. Lorsqu'il n'y a pas trop de concurrence (avec principalement le parti au pouvoir et l'opposition), cela assure en général à un des partis d'avoir la majorité absolue, ce qui lui permet de faire passer un bon nombre de lois et d'avoir une politique efficace peu freinée par les négotiations potentiellement interminables avec les autres partis.</li>
                        <li>Les coûts sont plus faibles : en ajoutant un deuxième tour, on multiplie les coûts quasiment par deux, ce qui n'est pas négligeable étant donné le nombre de bulletins de votes</li>
                </ul>
        </li>
        <li>Inconvénients : 
		<ul>
			<li>Les votes ne sont simplement pas représentatifs. Le troisième parti du pays a eu 80% des voix du second mais seulement 20% des sièges. Un parti a eu près de 900 000 voix mais aucun siège, alors que certains partis ont environ 30 000 voix par siège. Certains électeurs demandent simplement que les sièges gagnés soient directement une traduction de leurs votes. En d'autres termes, ils demandent une <strong>représentation proportionnelle</strong>.</li>
			<li>Il est extrêmement difficile de produire des sondages représentatifs, les scores étant très serrés, cela peut fausser les résultats. Il est très difficile d'avoir une bonne idée à l'avance du nombre de sièges, et les résultats sont souvent surprenants (le PPDA local a commenté toute la nuit les résultats).</li>
		</ul>
	</li>
</ul>
<h4>Représentation proportionelle</h4>
<br /><br />
Il y a différentes solutions :
<ul>
        <li>ajouter un deuxième tour ;</li>
        <li>demander aux partis d'allouer eux-même les sièges (mais des constituencies auraient des MPs non représentatifs) ;</li>
        <li>garder un seul tour mais demander de classer par préférence les candidats ;</li>
        <li>lire <a href="http://en.wikipedia.org/wiki/Proportional_representation">l'article "Proportional representation" sur Wikipedia</a>.</li>
</ul>
<h4>Hung parliament</h4>
<br /><br />
C'est assez rare qu'un parti n'ait pas la majorité absolue et il peut alors choisir de former :
<ul>
	<li>un gourvenement minoritaire (ce qui limite sa marge de maneuvre),</li>
	<li>ou alors de former un "hung parliament" (gouvernement de coalition) avec d'autres partis disposant de sièges.</li>
</ul>
Un petit rigolo a identifié les <a href="http://www.cypherspace.org/coalition/">coalitions possibles</a> (avec un <a href="http://www.cypherspace.org/coalition/coalition.b">vrai programme en bc(1)</a>, la classe) et c'est assez intéressant pour comprendre la situation.
<h4>Liens et faits annexes</h4>
<br /><br />
<ul>
<li><a href="http://en.wikipedia.org/wiki/United_Kingdom_general_election,_2010">United Kingdom general election, 2010
</a></li>
<li><a href="http://www.reddit.com/r/worldnews/comments/c144h/lib_dems_get_80_the_number_of_votes_labour_have/">Lib Dems get 80% the number of votes Labour have, yet 20% the number of seats. Care about electoral reform? Let's do something about it.</a></li>
<li><a href="http://labs.38degrees.org.uk/wall/reform">Mend Our Voting System - 38 Degrees</a></li>
</ul>
<ul>
<li>Un <a href="http://en.wikipedia.org/wiki/United_Kingdom_Parliamentary_expenses_scandal">scandale concernant les dépenses des MPs</a> a ébranlé la confiance des citoyens envers leur représentants (qui auraient par ailleurs <a href="http://www.telegraph.co.uk/news/newstopics/mps-expenses/7696484/MPs-accused-of-Wikipedia-expenses-cover-up.html">essayé de censurer Wikipedia pour cacher leurs actes</a>).</li>
<li>La situation a tellement intéressé les électeurs que la participation a augmenté de trois points (de l'ordre des deux tiers des électeurs potentiels) et des centaines d'électeurs n'ont pas pu voter. Ils vont devoir porter plainte, mais ça va être long et tout.</li>
<li>Un gouvernement de coalition entre les Lib Dems et les Conservatories semble compliquée depuis que les derniers ont planifié l'adoption d'une politique anti-européenne alors que les Lib Dems sont fortement pro-Europe.</li>
</ul>
<p>Merci à amaury pour sa relecture avisée.</p>
</div>
</content>

</entry>
<entry>
<title type="html">FuzzyCLIPS Downloads</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/04/22/fuzzyclips_downloads/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/04/22/fuzzyclips_downloads/index.html</id>
<published>2010-04-22T23:17:46+02:00</published>
<updated>2010-04-22T23:17:46+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
Today I needed to use FuzzyCLIPS under Linux as part of my studies. Unfortunately, it is no longer maintained since a bit less than ten years, and the official website is down. I was lucky enough to find the last <a href="http://www.moscoso.org/pub/ai/fuzzyclips/">mirror</a> that kept a copy of FuzzyCLIPS, so I decided to mirror it too, hoping that it won't get lost in the void.
<br /><br />
In the Linux version are also included two 32-bit executables, fz_clips, and fz_xclips, the terminal and X versions of the software. Here are the files, for you to download:
<ul>
  <li><a href="http://awesom.eu/~cygal/FuzzyCLIPS/FuzzyCLIPS-6.10d-sources.tar.gz">FuzzyCLIPS 6.10 Sources and Executables (Linux 32 bit)</a></li>
  <li><a href="http://awesom.eu/~cygal/FuzzyCLIPS/fzdocs.pdf">FuzzyCLIPS Documentation</a></li>
  <li><a href="http://awesom.eu/~cygal/FuzzyCLIPS/fzclp610cWin.zip">FuzzyCLIPS Windows Version</a></li>
</ul>
<br /><br />
I've also setup a <a href="http://github.com/cygal/FuzzyCLIPS">github repository</a> as another way to make sure this does not get lost. Does anyone know of another good fuzzy expert system?
</div>
</content>

</entry>
<entry>
<title type="html">Pathfinding : au-delà d'A* (A star)</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/04/19/pathfinding__au-dela_da_a_star/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/04/19/pathfinding__au-dela_da_a_star/index.html</id>
<published>2010-04-19T11:57:50+02:00</published>
<updated>2010-04-19T11:57:50+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
Non, je ne suis pas mort, j'avais juste rien de particulier à poster. Cet article traitera de différentes techniques utiles si vous avez besoin de faire un peu de pathfinding ou si vous vous demandez comment ça se fait.
<br /><br />
<h4>Pré-requis</h4>
<br /><br />
L'algorithme de base pour faire une recherche d'un point à un autre est A*. En très gros, le principe est simple, on associe à chaque case un coût, et au lieu d'avoir une file ou une pile comme dans d'autres parcours, on a une liste et on prend l'élément de la liste qui semble être le plus proche de la solution. Il y a plein de tutos à ce sujet, le moins didactique étant de loin le tutoriel d'Haveo sur le site du zéro.
<br /><br />
<h4>Principe général</h4>
<br /><br />
Il existe de nombreux algorithmes qui permettent de chercher un chemin entre deux points dans un graphe. L'algorithme le plus efficace est A*. En fait, il est optimal, mais cela ne règle pas le problème, car
 son efficacité dépend de l'heuristique qu'on lui fournit. Cette heuristique permet à l'algorithme de choisir les points du graphe qui ont le plus de chance de venir à la solution. En général, on utilise la
distance de Manhattan, mais ça peut être n'importe laquelle du moment qu'elle est minorante.
<br /><br />
Une heuristique minorante sous-estimera toujours le coût du chemin le plus court, ce qui évitera à A* de ne pas envisager des sommets du graphe qui pourraient mener à la solution directement. En gros, ça veut dire qu'on peut pas avoir une carte avec possibilité de se téléporter : dans ce cas là, il sera impossible d'avoir une heuristique minorante et donc de faire fonctionner A* (j'imagine qu'il faudrait alors se rabattre sur d'<a href="http://www.siteduzero.com/tutoriel-3-117382-arbres.html#ss_part_3">autres parcours</a> du coup).
<br /><br />
<br /><br />
<h4>Espace de recherche</h4>
<br /><br />
On a donc l'algo qui parcourt un graphe, mais comment définir ce graphe ? Il y a différentes solutions suivant le type de jeu ou d'application.
<br /><br />
<ul>
        <li>Pour un bête jeu tile-based, il suffit que le graphe soit la matrice, avec des coûts donnés pour se déplacer (disons 14 en diagonale, 10 le reste du temps)</li>
        <li>Si l'espace parcouru est continu, on peut alors le diviser en polygones, les lier entre eux, ce qui nous donne notre graphe</li>
        <li>En 3D, on peut faire pareil, avec des polygones, et ajouter la composante z à la distance de Manhattan</li>
</ul>
<br /><br />
Ces "polygones" s'appellent dans le jargon des "navigation meshes". Lisez <a href="http://www.ai-blog.net/archives/000152.html">"Fixing pathfinding once and for all"</a> (et plus particulièrement l'annexe) si vous voulez l'implémenter. Tous les articles ne sont pas disponibles sur le web, certains réfèrent à l'excellente série des livres "AI Game Programming Wisdom" (seul le Tome 1 est disponible en aperçu sur <a href="http://books.google.com/books?id=dHXSvj_M__sC&amp;printsec=frontcover&amp;dq=ai+game+programming+wisdom&amp;hl=fr&amp;cd=1#v=onepage&amp;q&amp;f=false">Google Books</a>.
<br /><br />
Une fois que vous avez vos polygones, il suffit de faire une recherche dans le graphe. Vous avez donc un chemin qui traverse vos polygones. Comment produire un joli chemin pour vos personnages ?
<br /><br />
<h4>Funnel Algorithm</h4>
<br /><br />
C'est là qu'intervient l'algorithme qui en déduit un joli chemin à travers ces polygones. Ça se traduit littéralement par "algorithme de l'entonnoir". Jusqu'à il y a peu de temps il n'y avait pas grand chose sur le net pour faire ça, jusqu'à au post <a href="http://digestingduck.blogspot.com/2010/03/simple-stupid-funnel-algorithm.html">"Simple&amp;Stupid Funnel algorithm" par Mikko Mononen</a> qui présente une implémentation simple et rapide. Et path, le chemin. :)
<br /><br />
<h4>Optimisations haut niveau</h4>
<br /><br />
Quand le monde est très grand, qu'il y a beaucoup (beaucoup) d'agents et beaucoup (beaucoup) de polygones/tiles, le pathfinding peut devenir un facteur limitant de l'application. Si le monde est particulièrement grand, on peut utiliser du "Level of Detail". C'est principalement utilisé pour le rendu graphique : si ce qu'on veut afficher est loin, on n'affiche qu'une version peu coûteuse, ou on ne l'affiche pas du tout.
<br /><br />
Appliqué au pathfinding, cela veut dire qu'on divise le monde en sous-parties, et le coût pour passer de partie en partie est connu. Il suffit donc d'appliquer A* sur la grande représentation, puis sur chacune des parties pour pouvoir la traverser. On a ensuite le même genre de problèmes qu'avec les polygones : trouver un chemin "lisse". La recherche Google <a href="http://www.google.fr/search?hl=en&amp;q=hierarchical+pathfinding">"hierarchical pathfinding"</a> vous donnera un bon aperçu de la littérature sur le sujet.
<br /><br />
On peut aussi cacher les requêtes les plus courantes pour ne pas avoir à recalculer. Une autre technique intéressante, qu'il est possible de coupler au pathfinding "hiérarchique" est de d'abord calculer une première estimation du chemin, demander à l'unité de commencer à bouger, puis de rectifier ce chemin par la suite.
<br /><br />
<h4>Optimisations bas niveau</h4>
<br /><br />
"Bas niveau" ici signifie simplement une modification de l'implémentation de l'algorithme, pas de son utilisation. Il y a tout un article à ce sujet dans le premier "AI Game Programming Wisdom" qui décrit tout un nombre de possibilités crades (ils sont notamment tous fiers d'utiliser des templates 90% du temps et d'avoir la possibilité d'utiliser des fonctions virtuelles quand la recherche n'est pas une bête recherche de chemin).
<br /><br />
Ils évoquent par contre la notion de "cheap list" qui est intéressante. Dans A*, on a une liste "ouverte" qui contient la liste des noeuds à explorer. À chaque nouvelle case explorée, on insère dans cette liste les cases adjacentes (huit dans le cas classique), et à chaque nouvelle itération on doit récupérer la case qui est la plus proche du but. Il faut donc une structure de données qui permettre d'insérer rapidement (la liste est adaptée) mais aussi de sélectionner le plus rapidement possible le maximum de la liste.
<br /><br />
Maintenir la liste triée aurait été une solution, mais cela impose une insertion en O(n). Du coup, la liste est séparée en deux partie, la première disons de 15 éléments qui est triée, et l'autre qui ne l'est pas. À chaque insertion, si l'élément est plus petit que le minimum de la première liste, on le met dans l'autre, sinon on l'insère (c'est toujours du O(n) mais sur 15 éléments, donc du O(1) :). Si la première liste devient vide, il faut récupérer les quinze premiers éléments de la liste non triée, c'est du O(n), mais comme ça arrive pas souvent, pouf c'est (presque) amorti.
<br /><br />
<h4>Eviter des obstacles dynamiques</h4>
<br /><br />
Trouver un chemin d'un point A à un point B, c'est facile, on sait faire, on sait optimiser, tout ça. Mais comment faire lorsque de nombreux agents se croisent ? Si ils sont pas trop nombreux, on utilise ce qui s'appelle des "steering behaviors". Le principe est simple : si la ligne qu'on est en train de parcourir est bloquée par un obstacle, on tourne un peu pour l'éviter et revenir rapidement dessus en suite.
<br /><br />
Comment faire quand ces obstacles deviennent nombreux et dynamiques ? Différentes solutions existent. La <a href="http://grail.cs.washington.edu/projects/crowd-flows/">recherche à ce sujet</a> utilise des solveurs utilisant la "mécanique des fluides". Deux vidéos montrant deux RTS modernes qui arrivent à résoudre ce problème selon leurs vidéos :
<br /><br />
<ul>
	<li><a href="http://j.mp/8X2fBA">FlowField Pathfinding in Supreme Commander 2 (GameTrailers.com)</a></li>
	<li><a href="http://j.mp/cvaKSK">350+ Unit Zergling Swarm in StarCraft 2: Pathfinding Demo (YouTube.com)</a></li>
</ul>
<br /><br />
Un autre sujet de recherche à ce niveau est l'applicaton des <a href="http://en.wikipedia.org/wiki/Velocity_obstacle">Velocity obstacles</a> pour permettre aux personnages de s'éviter. Je vous conseille à nouveau le <a href="http://digestingduck.blogspot.com/">blog de Mikko Mokonen</a> pour en savoir plus à ce sujet et voir quelques démos.
<br /><br />
<ul>
	<li><a href="http://digestingduck.blogspot.com/2010/03/local-navigation-grids.html">Local navigation grids</a></li>
	<li><a href="http://digestingduck.blogspot.com/2010/03/geometric-vs-sampling.html">Geometric vs. Sampling</a></li>
</ul>
<br /><br />
Il y a toujours possibilité d'améliorer bien sûr, genre en cherchant à tourner de manière réaliste en prenant en compte le personnage (un tank se retourne pas facilement et ne peut pas coller un mur vu sa taille).
<br /><br />
Sinon, des <a href="http://buzzerl.iuwt.fr/web/link?id=192">questions</a> ?
</div>
</content>

</entry>
<entry>
<title type="html">This is the end?</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/02/09/this_is_the_end/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/02/09/this_is_the_end/index.html</id>
<published>2010-02-09T14:07:35+02:00</published>
<updated>2010-02-09T14:07:35+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
BZFlag est un jeu assez connu sous GNU/Linux du fait de son ancienneté, sa portabilité, sa stabilité, et son gameplay assez original. J'ai eu la chance de participer à son développement l'été dernier, pendant le Google Summer of Code, et je voulais en profiter pour parler de ce projet, de son fonctionnement interne, et des erreurs qui ont été commises quand à sa gestion. Je pensais avant d'écrire  que cette analyse pouvait être bénéfique aux contributeurs dans le libre de manière générale qui peuvent avoir envie d'apprendre des erreurs des autres. Finalement, pas tant que ça, les erreurs faites sont assez évidentes. Je ne prétend pas toute fois donner des leçons à bzflag. Ce billet est au plus une occasion de m'expliquer pourquoi j'ai arrêté de contribuer à ce projet qu'autre chose. Je ne suis pas là depuis si longtemps (environ un an), et je m'inquiète peut-être pour rien.
<br /><br />
Si l'histoire qui explique un peu ce qui s'est passé vous intéresse, c'est le parochaine partie. C'est a priori pas indispensable pour la courte suite. J'aimerais cette fois avoir des retours sur l'intérêt de ce billet : est-ce qu'une vue de l'intérieur d'un projet libre comme celle-là vous plaît ? Je continue avec d'autres projets que j'aurais pu observer ?
<br /><br />
<h3>L'histoire chiante</h3>
<br /><br />
Je vais commencer par quelques stats et quelques faits que je connaissais pas avant de rentrer dans l'équipe. Rien de précis, c'est pour donner une idée. BZFlag a environ 80 développeurs qui ont encore le droit de commit sur sourceforge, a commencé son développement il a environ 15 ans, a été libéré en 97. Ça a attiré beaucoup de gens, peut-être parce que c'était le seul jeu potable à l'époque, etc.
<br /><br />
Ce jeu est tout d'abord l'oeuvre de très peu de personnes différentes, finalement. Il y a moins d'une dizaine de "gros committeurs", leur influence a donc été primordiale et le parcours du projet peut s'expliquer en analysant leurs actions. Aujourd'hui, on peut compter environ trois contributeurs sans parler du Google Summer of Code : les étudiants y participant ne sont jamais devenus des contributeurs.
<br /><br />
Il y a le gars hyper productif qui te pond des features toutes les semaines sans savoir d'où il les sort. Il a ajouté un support lua sur le serveur, sur le client, a tout viré, a tout remis, le tout sans explications... Je sais plus trop où ça en est, a priori ce n'est que sur le serveur, pour une raison inconnue (probablement pour éviter la triche). Il est pas très gentil sur IRC mais ça va, il répond aux questions, et quand il voit que de ton côté tu fais des efforts il va regarder aussi de son côté, sinon il te demandera simplement si tu ne cherches qu'à lui faire perdre son temps.
<br /><br />
Il y a le "chef du projet", qui est arrivé au moment de la libération, code sous Windows, trolle beaucoup, est super agaçant quand il te répond, c'est le genre de gars convaincu qu'il sait tout parce qu'il est là depuis longtemps et fait de l'info depuis longtemps. Sa plus grande qualité c'est d'avoir été présent durant tout le Summer of Code pour répondre aux questions. Les trois autres mentors étaient souvent connectés, mais très rarement présents. Le nombre de fois où j'ai discuté avec lui se compte sur les doigts d'une main. A part ça, il envoie chier beaucoup de gens, principalement quand on lui demande quand la prochaine version va sortir. Il a aussi essayé d'implémenter des trucs pratiques, genre le dead-reckoning pour limiter les effets du lag, sauf que ça marche pas du tout, mais personne est capable ni d'enlever son code, ni de le corriger, et c'est très mauvais.
<br /><br />
On a aussi des paquets qui arrivent dans le bon sens et sont traités dans le mauvais, et personne ne sait pourquoi, par contre on sait que ça crée un tas de bugs. Ils se sont mis à paniquer devant le nombre de bugs que l'an dernier. Mais hey, personne n'a envie de les corriger, donc ils ont fini par accepter de mettre ce projet en premier pour le GSoC 2010 (aucun autre projet n'a touché au jeu en lui-même, mais des trucs autour, forcément, c'est tellement bugué qu'ajouter des features serait trop compliqué et compliquerait encore les choses).
<br /><br />
Je me suis occupé de ce projet, j'ai fait une liste de bugs que je comptais corriger (pris du bug tracker sur sf.net et du fichier BUGS). J'ai l'impression d'avoir corrigé les plus importants, mais cela restait au final des bugs mineurs quand on voit les deux gros bugs que j'ai montré au-dessus qui empêchent simplement toute forme de release avant qu'ils soient corrigés. Depuis septembre, il n'y a pas eu un seul commit.
<br /><br />
yno, si tu me lis, n'hésite pas à aller essayer de corriger les problèmes, ça te permettra d'apprendre comment faire ça proprement, c'est un sujet qui te passione, avoue. Et tu dois apprendre à regarder autre chose que du C. :) Enfin dans cette partie là du code le C++ ne fait pas grand chose, rassure-toi.
<br /><br />
<h3>Comment éviter ?</h3>
<br /><br />
Au final, les développeurs de BZFlag ont été piégés de manière débile, il faut le dire. Release Early, Release Often a du sens, et si on l'oublie, on se fait vite avoir. Les deux avantages de ce crédo sont simples :
        - Pour sortir une nouvelle version, elle doit fonctionner, donc on doit corriger les bugs que les utilisateurs voient.
        - Cela permet de garder la motivation de tout le monde (même si dans le cas de bzflag, les devs préfèrent visiblement développer dans leur coin et pas se faire embêter par les utilisateurs - c'est très sérieux, je me moque pas, et c'est potentiellement justifié).
<br /><br />
C'était aussi évitable en créant des branches pour les fonctionnalités expérimentales. Cela a d'ailleurs été fait pour une autre fonctionnalité (server-side shots pour éviter la tricherie), et c'était judicieux, parce que ça ne marche pas du tout non plus, ça évite d'avoir un énorme bug de plus.
<br /><br />
On ne maitrise pas la motivation d'un contributeur dans le libre, il peut très bien disparaître du jour au lendemain, donc c'est très mal d'accepter du code qui ne fonctionne pas dans SVN.
<br /><br />
<h3>Quel futur ?</h3>
<br /><br />
bzflag a besoin d'un ou quelques développeurs qui se motivent pour sauver ce jeu. On est bien là : sauver le jeu. Il n'y a pas eu de release depuis cinq ans, malgré quatre années consécutives de contributions via le Summer of Code dont les ressources ont étés incroyablement utilisées.
<br /><br />
Et il ne faut pas compter sur les utilisateurs de la version 2 de bzflag pour changer à la version buggée. Beaucoup de joueurs jouent très sérieusement, il y a de nombreuses ligues et équipes, et ne peuvent pas accepter qu'un coup bien tiré rate son adversaire, ou que la moitié des informations ne soit pas donnée sur l'écran d'un des joueurs parce que les paquets ont été mal traités.
<br /><br />
Est-il envisageable de forker depuis la version qui marchait ? Oui, mais la personne qui fera ça se retrouvera probalement seule longtemps, et aura de la difficulté à rester compatible avec le protocole bzflag dont la documentation n'est pas à jour. Si une personne décide de faire ça, elle ferait mieux de se casser la tête à corriger les deux bugs qui restent, et se faire entendre suffisament pour éviter d'autres problèmes de ce genre.
</div>
</content>

</entry>
<entry>
<title type="html">Décidable, oui, mais calculable ?</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/01/20/decidable_oui_mais_calculable/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/01/20/decidable_oui_mais_calculable/index.html</id>
<published>2010-01-20T18:44:06+02:00</published>
<updated>2010-01-20T18:44:06+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>Après une explication rapide sur les enjeux de la décidabilité, j'ai jugé intéressant de parler de quelques classes de complexité. La plupart d'entre vous a sûrement déjà entendu parler de "NP-complet", mais tout le monde ne sait pas forcément ce que c'est. Ce qu'il faut savoir :</p>

<h4>Classes de complexité</h4>

<ul>
<li>Les problèmes dits simples ont des solutions qui s'éxécutent en temps polynomial : ils appartiennent à la classe P. Cette classe regroupe la plus grande partie des problèmes traités aujourd'hui par l'informatique. Exemples :
        <ul>
        <li>Un produit de matrice se fait en O(n^x), x compris entre 2 et 3.</li>
        <li>Un tri rapide s'exécute en O(n log(n)).</li>
        <li>Les algorithmes les plus efficaces en terme de traduction se font en O(n^5) (à base de Tree-adjoining grammar).</li>
        </ul>
</li>

<li>Il existe des problèmes dit "exponentiels" : le meilleur algorithme existant possible est exponentiel. Rien à faire, dès que l'entrée dépasse une taille de 10, il n'est pas possible d'avoir un algorithme praticable en raison de l'explosion combinatoire. Exemple : IA d'un jeu d'échec, Go, etc.</li>
</ul>

<h4>Une classe particulière : la classe NP</h4>

<p>C'est entre ces deux classes de problèmes que se situe la classe NP. Les problèmes de cette classe ont tous la même caractéristique : il est possible de vérifier une solution donnée à un problème de la classe NP en temps polynomial. Par exemple, on peut vérifier facilement que le résultat d'un tri est correct : on regarde si notre tableau est trié (O(n)), donc P est inclus dans NP. Il existe cependant des problèmes qui sont dans NP mais dont on n'a pas prouvé l'appartenance à P. Ces problèmes sont les problèmes NP-complets.</p>

<h4>Problèmes NP-complets</h4>

<p>Les problèmes NP-complets sont concrètement les problèmes les plus durs de la classe NP, et sont tous équivalents. Il est possible de démontrer que le problème SAT est NP-complet (je sais pas faire), et de montrer son équivalence à d'autres problèmes (plus facile). Par exemple, 3-SAT est équivalent. On peut de la même manière réduire le problème 3-SAT à un problème de coloration de graphe, etc.</p>

Une rapide liste de problèmes équivalents :
<ul>
        <li>génération d'emploi du temps ;</li>
        <li>problème du voyageur de commerce ;</li>
        <li>problème du sac à dos ;</li>
        <li>problème de la clique (applicable aux réseaux sociaux)...</li>
</ul>

<p>L'astuce pour savoir si un problème donné est NP-complet est assez simple : si la seule possibilité c'est de tester toutes les possibilités, et de recenser les possibilités correctes, le problème est certainement NP-complet. (Il est assez facile de savoir si une possibilité est valide grâce à la propriété principale de la classe NP : elle se fait en temps polynomial.) On peut ensuite chercher une complexité plus précise, par exemple, générer un emploi du temps consiste à placer k cours dans n créneaux. La solution connue la plus efficace est exponentielle, mais on peut vérifier une solution en temps exponentiel : c'est ce qui fait du problème un problème NP-complet.</p>

<h4>P = NP ?</h4>

<p>Le problème « P = NP » peut être considéré comme le problème le plus important qui reste non résolu en informatique. On sait que P est inclus dans NP, mais on ne sait pas si NP est inclus dans la classe des problèmes exponentiels ou dans la classe des problèmes polynomiaux. Millenium propose un million de dollars à la personne qui saura résoudre ce problème. :)</p>

<p>Pour montrer P = NP, il suffit de montrer que les problèmes NP-complets sont polynomiaux : ce sont les plus durs de NP, donc si ils sont P, NP = P. Pour montrer que les problèmes NP-complets sont dans P, il suffit de montrer qu'un seul de ces problèmes a une solution polynomiale, étant donné qu'ils sont tous équivalents. Personne n'a réussi jusque là. :)</p>

<h4>Complexité en temps, en espace ?</h4>

<p>Le dernier point que vous pouvez vouloir retenir est que la complexité peut s'exprimer de deux manières : en temps, et en espace. Je n'ai parlé ici que de la complexité en temps, pour une raison simple : un problème qui a une complexité donnée en temps ne pourra pas avoir une complexité pire en espace. Intuitivement, dans un temps donné, on ne peut pas toucher à une infinité de cases mémoires.</p>

<p><em>Comme d'habitude, n'hésitez pas à réagir sur <a href="http://buzzerl.iuwt.fr/">Buzzerl</a>. :)</em> J'envisage de proposer à bluestorm d'ajouter au tutoriel d'algo sur le sdz une adapation de ce sujet, dans mon souvenir ce n'est pas dans le plan.</p>
</div>
</content>

</entry>
<entry>
<title type="html">Problème de l'arrêt : démonstration ?</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/01/19/probleme_de_larret__demonstration/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/01/19/probleme_de_larret__demonstration/index.html</id>
<published>2010-01-19T15:29:08+02:00</published>
<updated>2010-01-19T15:29:08+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<br /><br />
Le problème de l'arrêt est un problème classique en décidabilité. Il fait partie des problèmes qui n'ont pas de solution : il est impossible d'écrire un algorithme qui résoud ce problème. La plupart des autres problèmes indécidables reviennent à ce problème. On les montres d'ailleurs par diagonalisation : on montre qu'ils reviennent à résoudre le problème de l'arrêt, et donc qu'ils sont indécidables.
<br /><br />
Qu'est-ce qu'un problème décidable ? C'est un problème pour lequel, pour toute entrée, on peut répondre en temps fini au problème par oui ou par non : décider si l'entrée correspond.
<br /><br />
Le problème de l'arrêt consiste à prendre en entrée un algorithme, et déterminer si cet algorithme s'arrête ou non (pas de boucle infinie). Sa formalisation se fait dans les machines de Turing, mais le résultat vaut aussi dans un langage qui ne comporterait que des conditions, des boucles, et des affectations, et c'est équivalent à tous les langages que vous utilisez actuellement, nos machines n'étant pas grand chose de plus que de machines de Turing à n bandes.
<br /><br />
<h4>Démonstration</h4>
<br /><br />
Je vais donc programmer en C pour montrer que ce n'est pas possible d'écrire un programme qui résoud le problème de l'arrêt. On suppose que le problème est décidable. Il est donc possible d'écrire une fonction halt(), sans perte de généralité.
<br /><br />
<pre>
int zero()            int loop()
{                     {
  return 0;               while (true);
}                         return 0;
                      }
int weird()
{
  if (halt(weird)
    return loop();
  else
    return zero();
}
</pre>
<br /><br />
<ul>
<li>Si halt(weird) retourne vrai alors weird() retourne loop() (contradiction)</li>
<li>Si halt(weird) retourne faux alors weird() retourne zero() (contradiction)</li>
</ul>
<br /><br />
Donc on ne peut pas écrire une fonction halt(), donc le problème de l'arrêt est bien indécidable.
<br /><br />
<h4>Théorème de Rice</h4>
<br /><br />
On peut généraliser ce problème au théorème de Rice qui dit qu'il n'est pas possible de déterminer une propriété non triviale d'un algorithme. Une propriété est une caractéristique d'un algorithme. Exemples : "Il calcule la racine carrée de son entrée", "Il ne s'arrête pas". Elle doit être non triviale : ne pas être vraie pour tous les algorithmes, ou fausse pour tous les algorithmes.
<br /><br />
Je reprendrai ici la preuve (la non formelle) présente sur wikipedia. On suppose qu'on a un algorithme qui examine un programme quelconque, et qui sait dire si ce problème calcule bien le carré de son entrée. Voici un exemple de programme de calcul de carré :
<br /><br />
int carre(n) {
  a(i);
  return n*n;
}
<br /><br />
a et i sont une fonction et une entrée quelconque. a peut s'arrêter sur i, ou pas. carre est donc seulement une fonction qui calcule le carré d'une fonction si a ne s'arrête pas. Si on pouvait savoir ça, on saurait résoudre le problème de l'arrêt.
<br /><br />
Donc, il est impossible d'obtenir une propriété sur un algorithme. En particulier, on ne peut pas :
<ul>
  <li>Savoir si ce programme s'arrête</li>
  <li>Savoir si c'est un virus (il est donc impossible d'écrire un antivirus infaillible)</li>
</ul>
<br /><br />
<h4>Un peu plus de formalisation ?</h4>
<br /><br />
Ces résultats peuvent être démontrés formellement en utilisant les machines de Turing universelles. Le principe est d'utiliser un codage sous forme de 0 et de 1 pour coder un algorithme et son entrée. On écrit ensuite une machine de Turing qui sait lire ce codage, et on peut raisonner dessus. 
<br /><br />
Wikipedia (plutôt la version anglaise) dispose d'articles qui montrent ça bien. Je peux vous passer les slides que j'ai eu en cours si vous voulez, aussi.
</div>
</content>

</entry>
<entry>
<title type="html">Du web en Java ?</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/01/08/du_web_en_java/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/01/08/du_web_en_java/index.html</id>
<published>2010-01-08T19:33:41+02:00</published>
<updated>2010-01-08T19:33:41+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<br /><br />
Ce billet est là pour raconter rapidement comment on peut faire du web en Java. Je ne recommande ça à personne, c'est simplement que j'aurais été curieux de savoir comment ça marchait avant. C'est quelque chose qui est apparement pas mal utilisé en entreprise tout ça.
<br /><br />
L'avantage principal que ces entreprises doivent justement y voir, c'est le fait qu'à chaque livrable, il suffit de donner au client un simple fichier (un .war) qui contient tout le code du site, les librairies utiles, etc. Le client n'a plus qu'à déployer le fichier .war chez lui, et paf, tout marche comme par magie, donc il est content. Le fournisseur n'a pas besoin de montrer les sources ni de s'occuper de l'installation, donc il est content. Et voilà, tout le monde est content, et on obtient un truc qui est pas mal utilisé.
<br /><br />
Le client et le développeur n'ont qu'à avoir un conteneur Java EE, "Tomcat" par exemple, qui s'occupe des détails. Dans la pratique, un .war c'est simplement des dossiers agencés selon une organisation particulière, et le tout zippé.
<br /><br />
Au niveau de code, de base quand une requête est envoyée, le conteneur la redirige vers le bon projet puis vers la bonne "servlet". Concrètement une servlet c'est un controlleur : c'est là que sont envoyées les requêtes, il faut <a href="http://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServlet.html">implémenter doGet(request, response) et doPost(request, response)</a> pour jouer avec. On peut ensuite coder en Java pur, en écrivant la réponse directement depuis le Java, ou alors en passant par une vue.
<br /><br />
Au fur et à mesure des versions (comme d'habitude en Java) ont été greffés par dessus le tout des nouveaux trucs pour que des <a href="http://java.sun.com/developer/technicalArticles/javaserverpages/faster/">non codeurs puissent mettre des boucles dans les vues</a> (un langage de template particulièrement verbeux en XML), puis des nouveaux frameworks sont nés, Spring, Roo, tous plus <a href="http://www.jroller.com/desmax/entry/roo">géniaux les uns que les autres.</a>
<br /><br />
Aucun intérêt à en faire tout seul ceci dit.
</div>
</content>

</entry>
<entry>
<title type="html">Le pattern frigo. </title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/01/06/le_pattern_frigo/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/01/06/le_pattern_frigo/index.html</id>
<published>2010-01-06T11:25:53+02:00</published>
<updated>2010-01-06T11:25:53+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<em>Désolé pour le ton un peu con, ceci est un recyclage d'un mail auquel on ne m'a jamais répondu. :)</em>
<br /><br />
Imaginez deux programmeurs affamés, assoifés, luisant de sueur, ayant
fini leur dernier paquet de Duo Keks. Il est 2h30 du matin, ils
viennent de se réveiller, la nuit va être longue. Pour survivre à
cette épreuve, ils décident de lever une assemblée générale !
<br /><br />
Ils ont un problème à résoudre, et ne peuvent le résoudre qu'ensemble.
L'un est expert en droites, l'autre en assemblage de traits. Ils se retrouvent donc
devant un frigo, armés de l'instrument le plus adéquat qui soit : un
marqueur, et ont besoin de dessiner un carré. Ils se retrouvent obligés de collaborer pour réussir, tout ça.
<br /><br />
Ils viennent d'inventer le pattern frigo ! Dans la littérature ça
s'appelle une "blackboard architecture". Le principe est d'avoir un
certain nombre d'entités travailler sur un même espace de travaille.
La plupart des entités voient des demandes, regardent comment elles
peuvent découper le travail, puis écrivent d'autres demandes sur
l'espace de travail. 
<br /><br />
Par exemple, vous pouvez avoir dix soldats, deux chefs d'équipes, un
colonel. Chacune de ces entités est experte dans son domaine, et
résoud les problèmes qu'on lui donne efficacement (tuer, communiquer,
trouver une stratégie). Les chefs d'équipes vont suivre la stratégie
du colonel, et les soldats vont écouter leur chef d'équipe. Dans un
jeu vidéo, on a différents sous-systèmes, l'intelligence
artificielle, le système de navigation, le moteur physique, etc.
Chaque système va demander des choses sous formes d'assertions, et les
autres vont remplacer par d'autres assertions jusqu'à répondre.
<br /><br />
Attention, ce n'est pas de la logique des prédicats avec résolution
SLD (enfin du prolog quoi) ! C'est beaucoup plus extensible et
permissif (et moins formel aussi). Les experts peuvent être des threads indépendants qui
vivent leur vie avant d'aller voir l'espace de travail, on peut aller
en avant, en arrière, et on peut avoir plusieurs stratégies possibles
en même temps. C'est suffisament intéressant et extensible pour jouer avec dans un certain nombre de situations.
</div>
</content>

</entry>
<entry>
<title type="html">L'intelligence ? </title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/01/06/lintelligence/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/01/06/lintelligence/index.html</id>
<published>2010-01-06T01:43:33+02:00</published>
<updated>2010-01-06T01:43:33+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
Cette réaction ne traite qu'une petite partie d'une <a href="http://www.vetta.org/publications">thèse qui concerne la définition de l'intelligence</a>. L'intelligence est historiquement divisée en un certain nombre d'aspects. Ça peut être la compréhension du langage naturelle, l'aisance avec une langue, la mémoire associative, le raisonnement abstrait, etc. Il existe même un modèle qui sépare l'intelligence en 120 parties différentes. Il parait cependant difficile d'évaluer chacune de ces parties.
<br /><br />
L'auteur continue ensuite en traitant spécifiquement l'intelligence humaine en citant un certain nombre de définitions et aboutit à une définition que je vais essayer de traduire : « L'intelligence mesure la capacité qu'a un agent de réaliser ses objectifs dans un grand nombre d'environnements ». En continuant plus loin, j'ai eu l'impression de retrouver deux grandes définitions (un peu plus satisfaisantes) de l'intelligence :
<ol>
<li>La capacité à résoudre des problèmes.</li>
<li>La capacité à apprendre.</li>
</ol>
Ces mots sont les miens et ne recouvrent pas toutes les nuances apportées par le papier. Cependant, ça permet d'avoir une idée, et de savoir si vous avez envie de lire ce papier.
<br /><br />
L'avantage de la première définition, c'est qu'elle est mesurable facilement, et c'est d'ailleurs ce qui est fait dans tous les tests de QI existants : on donne beaucoup de problèmes à quelqu'un, et on regarde le nombre de problèmes qu'il est capable de résoudre. Le plus gros problème de cette définition est que quelqu'un qui a déjà vu le test, ou à qui on a appris des méthodes pour résoudre les problèmes donnés sera plus intelligent. Est-ce que les notes données à l'école permettent de montrer une certaine intelligence ? Certainement pas, et pourtant c'est le raisonnement implicite qui est fait.
<br /><br />
La seconde définition est là pour pallier à ce problème. Elle considère que quelqu'un qui peut apprendre à apprendre, qui est capable d'être capable est intelligent. C'est beaucoup plus satisfaisant. L'intelligence n'est plus une fonction du travail, mais est aussi quelque chose que l'on ne peut pas finalement palper, visualiser. C'est aussi très rassurant, et c'est un discours que j'ai beaucoup entendu : c'est pas parce que d'autres ont des meilleurs notes que toi ou réussisent mieux que toi qu'ils sont plus intelligents. Peut-on pour autant considérer un enfant très prometteur comme plus intelligent qu'un adulte qui a développé un certain nombre de compétences au fil des années ? Ne doit-on pas aussi attacher de l'importance à la capacité à résoudre des problèmes tout de suite ? La première définition a alors du sens.
<br /><br />
"Intelligence is what is measured by intelligence tests." Boring (1923)
<br /><br />
Cette définition facétieuse en apparence exprime le fait que l'intelligence, ce n'est rien de particulier, mais une capacité abstraite qui affecte les performances d'un grand nombre de tâches, ce qui est là où les tests d'intelligences prennent du sens lorsqu'ils sont bien conçus. Cette définition met aussi en évidence que l'intelligence et la mesure de l'intelligence sont liées.
<br /><br />
En ce qui concerne les machines, on considère ici les machines de Turing simplement. Il faut greffer aux problèmes vu au-dessus la question de la performance. Il est inutile d'avoir une machine qui a besoin d'une mémoire infinie et d'un temps infini. L'auteur, en tant que bon chercheur, précise cependant qu'il ne faut pas trop se focaliser sur les performances, des fois qu'on changerait de modèle de machine (pour passer de Turing à l'ordinateur quantique par exemple).
<br /><br />
N'hésitez pas à aller voir la thèse en question pour plus d'approfondissement, c'est assez facile à lire, au moins au début. :)
</div>
</content>

</entry>
<entry>
<title type="html">Les métaphores de navigation choisies par Gnome</title>
<author>
<name>cygal</name>
</author>
<link rel="alternate" type="text/html" href="http://awesom.eu/~cygal/archives/2010/01/06/les_metaphores_de_navigation_choisies_par_gnome/index.html"/>

<id>http://awesom.eu/~cygal/archives/2010/01/06/les_metaphores_de_navigation_choisies_par_gnome/index.html</id>
<published>2010-01-06T01:39:00+02:00</published>
<updated>2010-01-06T01:39:00+02:00</updated>

<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
Si vous avez déjà utilisé un "Vanilla" Gnome, vous aviez peut-être remarqué que Nautilus ouvre une nouvelle fenêtre à chaque fois que vous voulez ouvrir un nouveau dossier. C'est quelque chose de complètement horrible à utiliser mais cependant justifié d'un point de vue ergonomique.
<br /><br />
C'est en fait la bataille entre deux "métaphores" utilisés pour de telles GUIs. La première, la métaphore orienté objet, consiste à considérer chaque fichier, chaque dossier, chaque élément comme un objet au sens de la POO, avec ses caractéristiques et des informations telles que sa position sur l'écran, sa taille, etc. stoqués entre les différents affichages de cet élément. Si vous ouvrez un paper que vous aviez fermé il y a deux semaines, il se retrouvera au même endroit, avec la même taille, à la même page, etc.
<br /><br />
L'inconvénient de cette méthode exercée à l'abus c'est que vous vous retrouverez avec un nombre incalculable de fenêtres dès que vous voulez fouiller un peu dans vos dossiers.
<br /><br />
Récemment, nautilus a renoncé à activer cette fonctionnalité par défaut. La raison principale, c'est le Gnome Shell. C'est la nouvelle façon de penser le bureau pour Gnome 3.0. C'est d'ailleurs assez intéressant, je vous invite à lire <a href="http://live.gnome.org/GnomeShell">la page dédíée au Gnome Shell</a>, et plus particulièrement le design document si ça vous intéresse. Ça propose un moyen plus simple d'accéder à ses fenêtres qui sont regroupées par activité, ça centralise les événements (réception d'un nouveau message, demande d'une application) pour les gérer au niveau du bureau. Si vous êtes occupés, vous pouvez filtrer une partie des messages, et les applications pourront limiter le nombre de popups qu'elles vous jettent à la figure. Le tout saupoudré de pas mal de recherche sur l'ergonomie, ça donne plutôt envie d'essayer.
<br /><br />
Du coup donc, la principale manière d'accéder à ses fichiers ne sera plus Nautilus mais un autre machin, ce qui a permi à Nautilus de revenir à la métaphore de navigation, où on ne crée notamment pas de nouvelle fenêtre. L'autre raison, c'est que personne n'utilisait ça de toute façon. :)
<br /><br />
Plus d'infos sur <a href="http://www.bytebot.net/geekdocs/spatial-nautilus.html">http://www.bytebot.net/geekdocs/spatial-nautilus.html</a> qui lie vers tous les liens qui vont bien. Have fun.
</div>
</content>

</entry>

</feed>
