Utilisation du type de variables « Decimal »

« Decimal » a été créé pour avoir une précision plus grande, mais dans une plage de valeurs plus restreinte.

Il est préconisé dans les applications monétaires, tandis que les autres types à virgules flottantes (double, single) sont destinés aux calcules scientifiques (et ils ont une vitesse de traitement plus rapide).

Fait amusant :

Decimal numerateur = 1m;
Decimal denominateur = 3m;
Console.WriteLine(numerateur / denominateur * denominateur);

Le résultat sera 0.999999… Ceci parce que Decimal est justement trop précis !

L’utilisation de Round permettra de profiter de la précision de Decimal, tout en faisant les arrondis nécessaires. Comme cité dans cette ressource : « Le type Decimal n’élimine pas la nécessité d’arrondir. Il réduit plutôt des erreurs en raison de l’arrondi ».

Console.WriteLine(Math.Round(numerateur / denominateur * denominateur, 2));

Ceci retournera 1.00.

L’utilisation des autres flottants n’est pas conseillé. Car les erreurs d’arrondis vont plus faciement s’accumuler à fur et à mesure des calculs.

Cet exemple ci-dessous ne doit pas fausser l’opinion des développeurs :

Double numerateur = 1f;
Double denominateur = 3f;
Console.WriteLine(numerateur / denominateur * denominateur);

Le résultat sera de 1 ! Mais cela reflète simplement un manque de précision de la division avec ce type de flottants : numerateur / denominateur = 0.3333343

 

Snake7 : Algorithme du mouvement du serpent

Voici comment j’ai développé le mouvement du serpent dans Snake7. Pour rappel, le serpent va dans toutes les directions de manière fluide (à l’inverse du serpent classique qui va de « carré en carré » dans 4 directions).

[youtube=http://www.youtube.com/watch?v=CbzXohlMvMc]

Situation de base : Le serpent est constitué de plusieurs tronçons et de la tête. Le joueur contrôle uniquement le déplacement de la tête, et les tronçons doivent suivre.

Problématiques : 

  • Un tronçon ne connait que le tronçon qui le précède. Il n’y a pas d’intérêt à ce qu’il connaisse la position ou le comportement de la tête.
  • Pas question non plus qu’un tronçon suive exactement le même chemin que le tronçon précédent (A l’instant t, la position du tronçon x ne sera pas la position du tronçon x-1 à l’instant t-1) : Cela donnerai un mouvement trop rigide !

Solution : A chaque instant, un tronçon doit toujours se trouver la même distance du tronçon précédent. Si le tronçon précédent s’éloigne, le tronçon doit s’en approcher par le chemin le plus court.

Voici un schéma de la structure du serpent , ici composé de 4 tronçons :

… où tous les segments rouges sont de la même longueur.

Scénario 

Prenons 2 tronçons A et B, séparés de la longueur « d ». B se déplace, A doit suivre et venir se « coller » à B en gardant la même distance « d » :

Comment déterminer le chemin que doit prendre A ? Schématisons un peu mieux la situation :

d, x1 et y1 sont connus ! Reste à connaitre x2 et y2 (déplacement horizontal et vertical de A)

Et bien pour cela, on ressort nos bons vieux théorèmes de Pythagore et Thalès !

Snake7

MAJ septembre 2011 : MAJ pour Mango.

Depuis le 1er juin, mon nouveau jeu « Snake7 » est disponible sur le MarketPlace WP7 !

Il a reçu de très bonnes critiques des joueurs (après un début difficile à cause du contrôle au « joystick »).

C’est un jeu de serpent classique (dans le principe), mais moderne (dans le contrôle et les mouvements du serpent).

Je voulais vraiment changer du déplacement classique « haut, bas, gauche, droite » linéaire. Au lieu de cela, le serpent bouge dans tous les sens. Toutes les 15 secondes, une alarme retentit, et voilà les murs mouvants qui arrivent. Il faut alors attraper toutes les pommes bonus pour avoir des points.

Nouveauté de développement : les points sont enregistrés en ligne, ce qui permet d’avoir un classement des joueurs mondial.

ASP.NET : Renvoyer un ContentType différent (excel, CSV, doc…)

ASP.NET : Renvoyer un ContentType différent (C#)

Quelques conseils quand une page renvoie un flux différent que du  "text/html" :

  • Préciser l’encoding : Response.ContentEncoding = System.Text.Encoding.Default;
  • Générer le contenu dans le Page_Load, et finir par : Response.End();
  • Exemple :

 protected void Page_Load(object sender, EventArgs e)
{

Response.Clear();

// Type de contenu de la réponse
Response.ContentEncoding = System.Text.Encoding.Default;
Response.Charset = "iso-8859-1";
Response.ContentType = "text/csv";

// Entête
Response.AddHeader("Pragma", "no-cache");

        // Force le navigateur à faire un "enregistrer sous..."
Response.AddHeader("Content-Disposition", "attachment; filename="fichier.csv"");

// Corp de la réponse
Response.Write("bla bla bla");

// Pas de cache
Response.CacheControl = "no-cache";
Response.Expires = -1;
Response.End();

}

NB : Dans le corps de la réponse, pour faire des retours à la ligne « propres », il faut utiliser : System.Environment.NewLine