mardi 24 juillet 2012

Template aliases

Les "typedef de templates" est une fonctionnalité qui est souvent demandée, et C++11 la fournit! Plutôt que le mot-clé "typedef", c'est une syntaxe à base du mot-clé "using" qui est utilisée, mais l'idée est la même:

template<typename T1, typename T2, typename T3>
class A
{
};

template<typename T1, typename T3>
using A_int = A<T1, int, T3>;

template<typename T>
using A_same = A<T, T, T>;

Notons que la même fonctionnalité était disponible en C++03 en passant par une classe intermédiaire:

template<typename T1, typename T2, typename T3>
class A
{
};

template<typename T1, typename T3>
class A_int
{
  typedef A<T1, int, T3> TypeT;
};

template<typename T>
class A_same
{
  typedef A<T, T, T> TypeT;
};

L'on pouvait utiliser alors A_int::TypeT et A_same::TypeT, mais c'est quand même plus joli lorsque l'on peut écrire ses "using" directement. À noter que la syntaxe "using" permet également de renommer des types non templatés, exactement comme le typedef:

using MyInt = int;

Surtout du sucre syntaxique, donc, mais du sucre qui devrait rendre le code plus clair en évitant la multiplication de classes triviales ne servant qu'à renommer ses types.

jeudi 19 juillet 2012

Non-static data member initializers

Voici un petit changement dans C++11 qui semble tout droit venir de Java. L'idée est de permettre l'initialisation des membres non-statiques au niveau de leur déclaration. Voyons tout de suite ce à quoi cela peut ressembler:

#include <string>
#include <iostream>

class A
{
public:
  int a = 3;
  std::string b = "abc";
};

int main()
{
  A a;
  std::cout << a.a << ", " << a.b << std::endl;

  return 0;
}

Compilons (remarquons au passage que si l'on ne spécifie pas l'option "--std=c++11", l'on a un petit warning du type "init.cpp:7:11: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]"). Comme prévu, le programme affiche "3, abc".

Remarquons également qu'il est possible d'utiliser des fonctions libres, ou encore des méthodes, pour initialiser ses variables, et qu'il est également possible d'utiliser les listes d'initialisation, soit avec le "=" réglementaire, soit en accolant les {} directement après la variable.

class A
{
public:
  int a = 3;
  std::string b = thestring();
  std::vector<int> c = {1, 2, 3, 4, 5};
  std::vector<double> d{1, 2, 3, 4, 5};

  std::string thestring()
  {
    return "abc";
  }
};

Il est possible de forcer la valeur dans un constructeur, ce qui permet d'implémenter une valeur par défaut: dans l'exemple suivant, _batchSize vaut soit 1000 pour le constructeur par défaut, soit la valeur passée en paramètre pour l'autre constructeur.

class A
{
public:
  A()
  {
  }
  
  A(int batchSize):
  _batchSize(batchSize)
  {
  }
  
  int _batchSize = 1000;
};

Alors, utile? Certainement. Un des gros avantages de ce type de notation est de réduire la duplication de code lorsqu'une classe a beaucoup de constructeurs qui initialisent tous certaines variables à la même valeur, réduisant le risque d'erreurs (pensez à une variable "isRunning" par exemple). En revanche, et c'est mon souci principal, cela augmente le nombre d'endroits où les initialisations sont effectuées, rendant le code plus difficile à lire: il n'est pas suffisant de regarder son constructeur, il faut également aller dans le fichier d'en-tête pour voir à quoi seront initialisées les autres valeurs. Pour cette raison, il sera probablement sage de limiter cette fonctionnalité aux classes relativement simples, ou à certains membres bien définis (typiquement, les variables changent peu, liées à l'état de la classe, comme les batchSize, isRunning, objectName...). Mais dans des classes très complexes, c'est risquer de rendre le code bien moins compréhensible.

mardi 17 juillet 2012

Bientôt un client Steam sous Linux

Cela vient d'être confirmé par Valve, via une entrée sur un tout nouveau blog: une équipe a été formée pour créer et maintenir un client Steam et pour porter des jeux nativement sous Linux.

L'équipe Valve Linux se concentre sur le moment sur Ubuntu (12.04), mais le support d'autres distributions est prévu.

L'annonce indique que pour l'instant, l'équipe a porté Steam avec la plus grande partie de ses fonctionnalités, ainsi qu'une version non optimisée de Left For Dead 2. Le travail va donc consister d'une part à passer Steam en bêta-test, et d'autre part à continer le travail d'optimisation sur leur moteur. L'on peut espérer que d'icic à un certain temps, la plupart des nouveaux jeux Valve aient un port Linux. Ajoutés aux "humble bundles" qui sont pour la plupart jouables en natif, c'est une ludothèque limitée, mais tout à fait intéressante, qui pourrait voir le jour. À terme, d'autres éditeurs pourraient s'engouffrer dans la brêche. La fin du monopole de Windows sur les jeux?

Et quid de la rumeur persistante qui dit que Linux est la première étape vers une console de salon estampillée Valve?

dimanche 15 juillet 2012

g++ 4.7 dans Wheezy

Bonne surprise lors de ma mise à jour de ce week-end, g++4.7 est arrivé dans Debian Wheezy. C'est l'occasion de se pencher sur les nouvelles fonctionnalités de c++11 intégrées dans cette version. D'après la page récapitulative, les nouveautés sont les suivantes:

  • Non-static data member initializers
  • Template aliases
  • Delegating constructors
  • User-defined literals
  • Extended friend declarations
  • Explicit virtual overrides

L'on sent que l'on arrive aux tréfonds du standard: beaucoup de ces fonctionnalités sont à la limite du sucre syntactique ou renforcent la sécurité du langage, mais il n'y a pas de révolutions.

Si l'on regarde du côté de ce qui manque encore, l'on trouve surtout des fonctionnalités de parallélisation, qui ne sont probablement pas la priorité de l'équipe gcc.

Néanmoins, nous reverrons en détail ces nouvelles fonctionnalités dans les posts qui viennent.

jeudi 12 juillet 2012

Ces jeux qui m'ont marqué - Settlers I et II

Et un saut dans la modernité, avec ces jeux apparus sur PC respectivement en 1994 et en 1996. Suffisamment similaires pour que j'aie du mal à les distinguer après toutes ces années, je parlerai surtout du deuxième opus, mais les fondements sont les mêmes.

Settlers est un jeu de stratégie qui vous met à la tête d'un royaume qu'il faut faire prospérer en construisant une économie efficace. Au fur et à mesure de son extension, l'on rencontrera des royaumes ennemis qu'il faudra abattre.

Jusque là, rien de très original, mais c'est dans la complexité du système économique que Settlers I et surtout le II fait toute la différence. En effet, il faut construire divers bâtiments pour construire des circuits de production permettant d'alimenter son expansion. Par exemple, la ferme produit du blé, qu'il faut envoyer au moulin pour faire du pain, lequel servira à nourrir les mineurs, lesquels génèrent du fer et du charbon, lesquels sont utilisés pour construire des épées et des boucliers, lesquels servent à équiper ses soldats. Il faut produire de la pierre et du bois pour construire de nouveaux bâtiments, de l'or et de la bière pour renforcer ses soldats, et ainsi de suite.

En plus de construire des bâtiments, il faut les relier par des routes jalonnées de drapeaux. Un passeur prendra place entre deux drapeaux, et passera les ressources d'un drapeau à un autre. Il faut donc faire très attention à la manière dont on positionne ses bâtiments pour s'assurer que les marchandises sont transférées le plus rapidement possible, sans causer de bouchons.

Ce qui caractérise Settlers en comparaison des autres ténors du genre est son rythme beaucoup plus lent: puisqu'il faut attendre patiemment que chaque ressource fasse sont chemin à travers chaque circuit, l'on a beaucoup plus de temps pour placer judicieusement les prochains bâtiments, ou retravailler une route trop encombrée. Mais attention à ne pas se laisser hypnotiser, car il est facile de passer des heures à contempler ses petits géologues sauter de joie quand ils trouvent un filon, ses bouchers découper les cochons en tranches, ses passeurs faire des boules de chewing-gum quand ils n'ont rien à faire... Les animations très soignées rendent le jeu absolument magnifique à contempler.

Stratégiquement, c'est également tout à fait intéressant: l'on peut soit partir à la conquête du plus grand nombre de territoires dès le début, et essayer d'étrangler son adversaire, ou le coincer petit à petit, ou encore tenter de conquérir ses centres névralgiques en coupant son terrain en morceaux. Dans les niveaux les plus avancés, l'AI ne se défend pas mal du tout, donnant un challenge tout à fait intéressant.

Les derniers Settlers (de 3 à 7 ou 8) ont perdu, je trouve, ce côté nonchalant et mignon des deux premiers épisodes, pour se rapprocher des standards du jeu de stratégie en temps réel. Il demeurent intéressants, mais pour moi, pas de Settlers sans petits drapeaux!

vendredi 6 juillet 2012

Ces jeux qui m'ont marqué - Wizball

Encore une antiquité avec Wizball, jeu d'arcade paru en 1987. Le joueur incarne un magicien transformé en une boule verte, qui doit redonner leurs couleurs à une série de niveaux. Au début, le joueur n'a qu'un contrôle très limité de sa boule, mais au fur et à mesure qu'il détruit les mines ennemies et collecte des bulles, il va pouvoir améliorer sa maniabilité, puis appeler son chat (une autre boule verte plus petite, qu'il peut contrôler partiellement), puis obtenir des pouvoirs plus destructeurs.

Régulièrement, des boules de couleur traversent l'écran. En tirant dessus, elles tombent en gouttes, qui peuvent être récoltées par le chat (mais attention aux gouttes blanches, qui rendent le chat saoul, et aux gouttes noires, qui "éteignent la lumière"). Une fois suffisamment de couleurs récupérées, l'on part pour le laboratoire où le magicien mélange les couleurs, et colore une partie du niveau. Au bout de trois colorations, le niveau est complet, et un nouveau niveau s'ouvre.

Le jeu est plutôt ardu, les décors complètement gothiques au début deviennent franchement psychédéliques quand ils ont été colorés. Un gros point fort est la possibilité de jouer à deux en coopératif, l'un des joueurs prenant le rôle du chat.

Enfin, Wizball, c'est la musique. Chaque plateforme, C64, Atari et Amiga, maintiennent avoir la meilleure musique. Moi, c'était l'Atari, et cette musique, elle ne m'a plus lâché!