Pendant mes vacances chez un ami, on a pas mal joué à Risk. Ce qui est marrant dans risk, c’est à quel point c’est tordu de calculer les chances de gagner (en tout cas pour moi…). C’est pour ça que j’ai fait tourner mon processeur pour calculer toutes les permutations possibles (c’est quand même vachement plus simple non ?
). J’ai commencé par calculer les % de chances de gagner aux dés :
| Dés att VS déf |
Victoire: Attaquant |
Victoire: Défenseur |
Égalité |
| 1vs1 |
42% (15/36) |
58% (21/36) |
0% |
| 1vs2 |
25% (55/216) |
75% (161/216) |
0% |
| 2vs1 |
58% (125/216) |
42% (91/216) |
0% |
| 2vs2 |
22% (295/1296) |
45% (581/1296) |
32% (420/1296) |
| 3vs1 |
66% (855/1296) |
34% (441/1296) |
0% |
| 3vs2 |
37% (2890/7776) |
29% (2275/7776) |
34% (2611/7776) |
Une fois la tâche accomplie, j’ai créé un programme qui donne les possibilité de score final dans un combat :
–> Calculateur de chances de victoire
Mon calculateur n’est pas très rapide pour un grand nombre d’attaquants, mais au moins je suis content par ce que ça fonctionne 
July 24, 2007
Quand on a voulu faire des téléchargements directs sur TGS, nous avons été obligé d’utiliser free comme hébergeur, car je n’ai pas assez de bande passante ni de place sur mon serveur pour héberger de la musique. Mais on s’est heurté à divers obstacles :
- Free est plutôt limité dans la liberté de configuration du serveur et les possibilités de PHP
- Des serveurs se retrouvent hors ligne on ne sait pas bien pourquoi
- Des sites hotlinkent nos fichiers (ils font des liens vers nos fichiers en faisant comme si ils venaient de leur site)
La solution pour le 2eme problème était de faire une gestion décentralisée des téléchargements : au lieu qu’un fichier ne soit que sur un seul serveur, on le met sur plusieurs serveurs, comme ça si un des serveurs plante les autres serveurs peuvent continuer à proposer le fichier. Le rôle de UD est de scanner les différents serveurs pour trouver le fichier quelquepart et générer un lien de téléchargement valide.
Pour le 3eme problème, la solution aurait facile si je n’avait pas eu le 1er problème. Malheureusement je l’avait… J’ai commencé par essayer de détourner les erreurs 404, mais pour diverses raisons ça n’était pas très stable et puis la plupart des firewalls empêchaient le système de fonctionner comme il faut. La parade a été de faire en sorte que le nom du dossier qui contient les fichiers change assez fréquement, de manière à ce que faire un lien permanant soit impossible. On envoi donc l’utilisateur sur une page qui verrifie que l’utilisateur vient du bon site, puis qui scanne tout les serveurs pour trouver les fichiers et ensuite créé un lien pour télécharger sur un des serveurs.
Ça n’est évidament pas une protection ultime, puisque même un codeur moyen pourra facilement faire sauter ce genre de protection, cependant ça reste une bonne arme contre la majorité des hotlinks : les blogs et tout les sites qui ne demandent aucune connaissance technique, car leurs webmasters n’ont justement aucune connaissance technique…
Comme mon blog est là pour faire profiter à ceux qui le veulent de mon code, voici les sources de ce gestionnaire de téléchargements, que j’espère suffisament documenté (en anglais). En cas de questions, n’hésitez pas à m’envoyer un mail
.
–> Télécharger uncentralizedDownloader : 7zip – Bzip2 – Zip
–> La classe sur PHP Classes
July 23, 2007
Voici un très intéressant article qui donne le code source d’une classe qui effectue un pivot de Gauss (résolution d’un système d’équations linéaire) en PHP.
–> Lire
June 15, 2007
Vous pourrez trouver la nouvelle version de phpSerial, ma classe pour lire/écrire sur le port série depuis linux ou windows (sauf que windows gère pas la lecture) en PHP sur le site PHP Classes.
June 1, 2007
Leçon du jour : les expressions et leurs valeurs en PHP. Commençons par les conditions:
<?php
// Roulette russe
if (rand(1,6) == 3) {
print ("Tu est mort !");
}
?>
Le principe est simple, dans un if (<expression>), l’expression est évaluée et si il s’avère être équivalente à true alors la condition est validée. En PHP, tout (à l’exception des opérateurs) a pour but de retourner une valeur : une fonction retournera une valeur, ou une variable retournera une valeur (sans parler des valeurs elles mêmes…). Donc la première chose que fait PHP (ce n’est pas tout à fait exact, mais on reviendra sur ce point plus tard) dans l’évaluation de ces expressions, c’est de chercher les valeurs. Dans l’exemple précédent, on admettra que rand(1,6) retourne la valeur 3. Le if de l’exemple ressemble donc maintenant pour le moteur PHP à
if (3 == 3) {
Maintenant intervienne les opérateurs : l’opérateur == demande la comparaison des valeurs qui lui sont à sa droite et à sa gauche pour savoir si elles sont équivalentes (c’est à dire que si les deux valeurs ne sont pas du même type elles sont converties dans le même type puis comparées), et si c’est effectivement le cas il retournera le true que le if attend pour considérer que la condition soit vraie.
Mais les opérateurs de comparaison ne sont pas les seuls opérateurs existants. À commencer par les parenthèses : si une expression se trouve entre parenthèses, alors elle est d’abord évaluée puis sa valeur est retournée. Par exemple on peut avoir (on suppose toujours que rand(1,6) retourne la valeur 3):
<?php
// Roulette russe
if (($num = rand(1,6)) == (1+2)) {
print ("Tu est mort !");
}
else {
print ("T'as du bol d'être tombé sur le numéro " . $num);
}
?>
Ici encore on se retrouvera avec un
if (3 == 3) {
Viennent ensuite les opérateurs logiques, et ce sont eux qui me font mentir sur la première partie : les opérateurs logiques (and, or, xor, not, ils sont détaillés dans le manuel) interviennent dans l’ordre des opérations. En effet, si deux expressions sont de part et d’autre d’un or, par définition il suffit que l’une seule d’entre elles soit vérifiée pour que la condition soit vraie. Donc si la première expression retourne une valeur équivalente à true, PHP n’a pas besoin d’évaluer la seconde puique la condition est validée. En revance pour and et xor les deux expressions sont évaluées puisque PHP a besoin de connaître les deux valeurs.
Vous devez maintenant penser que ces système de valeurs ne marchent que dans des conditions ou autre structures de contrôle (elseif, while, for, etc). Eh bien pas du tout : ça marche n’importe où dans le code. De cette manière on peut avoir quelquechose qui ressemble à
<?php
$a = ($b = 3);
// Affiche 3
echo $a;
?>
(il faut avouer que ceci ne sert à rien), on peut aussi faire (plus utile cette fois)
<?php
/*
* Ici on regarde les valeurs d'un formulaire qui peut être
* envoyé soit par POST soit par GET
*/
$actif = ($_POST["actif"] or $_GET["actif"]);
?>
ou encore (là c’est réélement utile)
<?
/*
* Dans cet exemple, la fonction maFonction() est une fonction quelconque
* qui retourne <i>true</i> ou <i>false</i> selon qu'elle réussisse ou non.
*/
// Par la méthode classique
if (!maFonction()) {
trigger_error("Erreur lors de l'éxecution de ma fonction !", E_USER_WARNING);
}
// Et en utilisant or
maFonction() or trigger_error("Erreur lors de l'éxecution de ma fonction !", E_USER_WARNING);
?>
Petite explication sur ce dernier : PHP évalue d’abord maFonction(), qui retourne soit true soit false. Si maFonction() retourne true alors PHP n’a pas besoin d’évaluer ce qui se trouve après le or, en revanche si maFonction() retoure false PHP doit évaluer la 2ème expression.
Et tant qu’on est sur les valeurs, on pourra signaler que l’on peut forcer le type d’une valeur lors d’un assignement en spécifiant simplement le type entre parenthèses juste après l’opérateur d’assignation. Par exemple :
<?php
/* On récupère l'âge depuis un formulaire, mais il est
* de type string, or on le veut de type int.
*/
$age = (int) $_POST["age"];
?>
Je concluerai sur une dernière précision à propos de la sécurité : faites très attention à utiliser l’opérateur d’égalité (===) le plus possible au profit de l’opérateur d’équivalence (==) qui entraîne la conversion des types, ce qui peut mener à des abérations de logique ou des failles de sécurité (par exemple une faille de phpBB utilisait la conversion implicite des types pour devenir administrateur en modifiant simplement son identifiant de session…)
Voici donc un petit tour des valeurs en PHP, en espérant avoir été assez clair…
March 3, 2007
Allez… #1 et #2, on y croit 
[réponse le 1 avril normalement... non c'est pas une blague]
EDIT : ça y est c’est fini. Je suis 2eme pour PHP Serial et dernier pour la classe de contrôle de l’afficheur (avec 0 votes ^^”)
Content
March 1, 2007
Sait-on jamais, ça pourrai servir… Deux petites fonctions pour lister un répertoire, ou lister un répertoire récursivement
function ls($dir, $with_prefix = false) {
if (substr($dir, -1) !== "/") $dir .= "/";
unset($dirs); $dirs = array();
unset($files); $files = array();
if (@is_readable($dir) and @is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if (@is_readable($dir.$file)) {
if (is_dir($dir.$file)) $dirs[] = ($with_prefix) ? $dir.$file : $file;
else $files[] = ($with_prefix) ? $dir.$file : $file;
}
}
closedir($dh);
}
}
else return false;
unset($dirs[0]);
unset($dirs[1]);
return array($dirs, $files);
}
function recursive_ls ($dir, $with_prefix = false) {
if (substr($dir, -1) !== "/") $dir .= "/";
if (($map_elements = ls ($dir, false)) !== false) {
unset ($map); $map = array();
if (!empty($map_elements[0])) {
foreach ($map_elements[0] as $dirname) {
$map[($with_prefix) ? $dir.$dirname : $dirname] = recursive_ls($dir.$dirname, $with_prefix);
}
}
if ($with_prefix and !empty($map_elements[1])) {
foreach ($map_elements[1] as $id => $value) {
$map_elements[1][$id] = $dir . $value;
}
}
return array_merge ($map, array_flip ($map_elements[1]));
}
return false;
}
January 27, 2007
Voici une classe PHP capable d’effectuer un ping sous Windows et sous Linux. Requiert Pear (n’importe quelle version devrait faire l’affaire). (attention: je n’ai pas testé cette classe très largement, il se peut qu’il faille l’adapter à votre système)
Télécharger la classe
January 10, 2007
J’ai récupéré un afficheur de caisse Citizen C2202, que j’ai programmé pour pouvoir afficher une fortune, lire mes mails et pinger mes serveur. En gros ça sert à rien, mais en tout cas c’était marrant à programmer ^^. Voici donc le code écrit à l’occasion (vous pourrez constater une classe de contrôle du port série), qui ne fonctionne que sous linux (ou peut être certains unix, mais j’ai pas testé).
Télécharger les fichiers
Vous remarquerez que la classe de contrôle de l’afficheur hérite de la classe de contrôle du port série, donc ne comptez pas utiliser l’une sans l’autre. Toutes les fonctions de l’afficheur ne sont pas implémentées (pour la simple raison que j’ai rien compris à certaines), et je ne converti pas non plus le charset vers quelquechose que l’afficheur pourrait comprendre (trop la flemme pour ça).
Et voici la documentation que le constructeur m’a fourni : Citizen C2202-PDUME
January 9, 2007