Archives par mot-clé : dobble

Générer un jeu de Dobble

Lorsque j’ai découvert le jeu de Dobble, je me suis tout de suite demandé comment on pouvait générer un tel ensemble de cartes.

Après y avoir vainement réfléchi, j’ai trouvé quelques références ici et qui font appel à la géométrie projective.

L’idée m’est alors venue de générer un jeu personnalisé avec des images ayant un thème commun (des visages familiers, des lieux de vacances, etc.)

Le projet :

  1. Trouver une façon de générer les combinaisons de cartes et symboles
  2. Générer les combinaisons et les stocker dans fichier texte
  3. Faire un script qui génère les images de chacune des cartes avec ImageMagick
  4. Faire imprimer les images sur un support se rapprochant d’une carte à jouer

Les points 1 à 3 étant techniquement réglés, j’en partage ici les différentes étapes. Le dernier point est encore en projet…

1. Trouver l’algorithme

Après avoir parcouru liens mentionnés plus haut, il me restait à en faire l’implémentation. Après quelques tâtonnements, je suis tombé sur ce post de stackoverflow qui propose quelques implémentations.

2. Générer les cartes

J’en ai choisi une qui est sous-optimale (elle génère 58 symboles plutôt que 57). Le jeu reste cependant tout à fait valide et le bout de code implémentait aussi une fonction de vérification du jeu généré. J’ai légèrement modifié la sortie pour avoir un fichier texte facile à lire pour la suite.

Le fichier source est ici : mainDobble.cpp

Le résultat du programme est un fichier texte de la forme suivante où chaque ligne représente une carte composée de 8 symboles, eux-même représentés par un entier.

wilhelm@beluga:~/code/dobble$ head -5 dobble.txt
0 1 2 3 4 5 6 50
7 8 9 10 11 12 13 50
14 15 16 17 18 19 20 50
21 22 23 24 25 26 27 50
28 29 30 31 32 33 34 50
wilhelm@beluga:~/code/dobble$
Le format du fichier texte contenant les cartes de Dobble

Fichier des cartes résultant : dobble.txt

On peut aussi générer des jeux avec 4, 6 ou même 12 symboles par carte. Par exemple:

3. Le script de rendu

Pour créer le rendu des cartes, un petit script bash: card.sh.

Syntaxe

Premier argument: le fichier texte en entrée. Second argument: le chemin du répertoire où sont les images. Les cartes sont générées dans un répertoire output

wilhelm@beluga:~/code/dobble$ ./card.sh dobble.txt ~/picture/dobble
Commande pour lancer le rendu des cartes.

On notera la double utilisation de shuf. L’algorithme de génération des cartes est assez ordonné. Un double brassage s’impose. Le premier, c’est pour réarranger l’ordre des cartes (le shuf de la boucle for). Le second (encapsulé dans une fonction Shuffle pour ventiler les éléments d’une ligne plutôt que des lignes), est plus important. Il s’agit de ventiler la position des symboles sur les cartes. Sinon, les mêmes symboles ont tendance à se retrouver aux mêmes positions et ça enlève un peu du piment au jeu.

La boucle principale appelle ImageMagick pour créer un montage à partir d’images stockée dans le répertoire passé en argument et du fichier texte mentionné plus haut.

#!/bin/bash

Shuffle()
{
echo $* | tr " " "\n" | shuf | tr -d " "
}

##############################################
# Main
##############################################
INPUT=$1
DIR=$2
OUTDIR=ouput

BAK_IFS=${IFS}
IFS=$'\r\n'
Image=($(ls $DIR))
IFS=${BAK_IFS}

mkdir -p ${OUTDIR}
export i=0
export SMSIZE=500
export BIGSIZE=600
export FULLSIZE=1600
shuf ${INPUT} | while read a b c d e f g h; do
sa=( $( Shuffle ${a} ${b} ${c} ${d} ${e} ${f} ${g} ${h} ) )
im=( \
"${DIR}/${Image[ ${sa[0]} ]}"\
"${DIR}/${Image[ ${sa[1]} ]}"\
"${DIR}/${Image[ ${sa[2]} ]}"\
"${DIR}/${Image[ ${sa[3]} ]}"\
"${DIR}/${Image[ ${sa[4]} ]}"\
"${DIR}/${Image[ ${sa[5]} ]}"\
"${DIR}/${Image[ ${sa[6]} ]}"\
"${DIR}/${Image[ ${sa[7]} ]}" )

OUTPUT=${OUTDIR}/card_${i}.jpeg
echo ${OUTPUT}
((i ))

convert -size "${FULLSIZE}x${FULLSIZE}" xc:white \
-gravity Center \
\( "${im[0]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate -45 -repage 0 0 \) \
\( "${im[1]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate 45 -repage 1000 0 \) \
\( "${im[2]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate 0 -repage 0 600 \) \
\( "${im[3]}" -resize "${BIGSIZE}x${BIGSIZE}" -gravity Center -rotate 60 -repage 400 400 \) \
\( "${im[4]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate 180 -repage 1200 500 \) \
\( "${im[5]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate -135 -repage 0 1100 \) \
\( "${im[6]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate 180 -repage 800 1100 \) \
\( "${im[7]}" -resize "${SMSIZE}x${SMSIZE}" -gravity Center -rotate 135 -repage 1100 1100 \) \
-compose Multiply -layers flatten tiff:- | convert - -mattecolor DarkOrange4 -frame 20x20 0 0 \
${OUTPUT}
done
Script pour le rendu des images de carte

Ci-dessous, un exemple du rendu de quelques cartes générées. Il ne reste plus qu’à ajuster un peu les dimensions en fonction des proportions des cartes à imprimer. Mais pour ça, il faut trouver un fournisseur/site web, qui propose d’imprimer 57 cartes différentes pour un prix raisonnable. C’est la fameuse étape 4, qui est encore en suspend…