Bonjour à tous,

Je suis en train de créer un jeu de bingo, et je voulais vous soumettre l'algo pour voir ce que vous en pensez et j'ai aussi un petit problème dont je vous parlerez après.
Pour ceux qui ne connaissent pas les règles d'une grille de bingo, voilà les règles :

  • 90 numéros de 1 à 90
  • Une grille de 9 colonnes et 3 lignes
  • 5 numéros par ligne maxi
  • 1 ou 2 numéros par colonne maxi
  • Chaque colonne ne peut avoir des nombres de la même dizaine (colonne 1 => 1 à 9, 2 => 10 à 19, 3 => 20 à 29, etc. sauf la dernière qui est de 80 à 90.


Voilà le code, que vous pouvez éxecuter en console :

Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 
<?php
 
define('MAX_PER_GRID', 15);
define('MAX_PER_COLUMN', 2);
define('MAX_PER_LINE', 5);
 
// liste des nombres de 1 à 90, par colonnes
$numberList = [
            range(1,9),
            range(10,19),
            range(20,29),
            range(30,39),
            range(40,49),
            range(50,59),
            range(60,69),
            range(70,79),
            range(80,90),
        ];
 
// Création de la grille vide, 3 lignes de 9 colonnes
$grid = [];
for($line = 0; $line <= 2; $line++) {
    $grid[$line] = array_fill(0, 9, '');
}
 
$countByLine = array_fill(0, 3, 0);
$countByColumn = array_fill(0, 9, 0);
 
fillGrid($grid, $countByLine, $countByColumn, $numberList);
 
echo "----------------------------------------------\n";
 
foreach($grid as $line) {
    $line = vsprintf('| %02d | %02d | %02d | %02d | %02d | %02d | %02d | %02d | %02d |', $line);
    $line = str_replace('00', '  ', $line);
    echo $line . "\n";
}
 
echo "----------------------------------------------\n";
 
function fillGrid(array &$grid, array &$countByLine, array &$countByColumn, array &$numberList) {
    foreach($grid as $keyLine => &$cells) {
        //echo "Line " . $keyLine . "\n";
 
        if($countByLine[$keyLine] == MAX_PER_LINE) {
            //echo "    Already Filled!\n";
            continue;
        }
 
        foreach($cells as $keyCell => &$cell) {
            //echo "    Cell " . $keyCell . ": ";
            if($countByLine[$keyLine] == MAX_PER_LINE || $countByColumn[$keyCell] == MAX_PER_COLUMN) {
                //echo "SKIP CELL\n";
                continue;
            }
 
 
            // S'il y a déjà un nombre dans la cellule, suivant 
            if(!empty($cell)) {
                //echo "Already Filled => " . $cell . "\n";
                continue;
            }
 
            $fillCell = mt_rand(1, 2) == 1 ? true : false;
 
            // si c'est la dernière ligne de la grille,
            // traitement particulier pour trouver les 
            // trous à remplir obligatoirement
            if($keyLine == 2) {
                $cellsWithZero = array_keys($countByColumn, 0);
                if(!empty($cellsWithZero)) {
                    //echo "CELLS WITH ZERO: \n";
                    // print_r($cellsWithZero);
 
                    if(in_array($keyCell, $cellsWithZero)) {
                        //echo "FORCE FILL ZERO CELL\n";
                        $fillCell = true;
                    } else {
                        $fillCell = false;
                    }
                }  elseif(in_array($keyCell, $cellsWithZero)) {
                    //echo "FORCE FILL CELL\n";
                    $fillCell = true;
                }
            }
 
            if($fillCell) {
                shuffle($numberList[$keyCell]);
                $cell = array_shift($numberList[$keyCell]);
                ++$countByLine[$keyLine];
                ++$countByColumn[$keyCell];
                 //echo "\033[1m" . $cell . "\033[0m ";
            }
            //echo "\n";
        }
        //echo "\n";
    }
 
    // Il y a 15 nombres dans la grille, c'est complet !
    if(array_sum($countByLine) === MAX_PER_GRID) {
        return;
    }
 
    // La grille n'est pas complete, itération suivante
    fillGrid($grid, $countByLine, $countByColumn, $numberList);
}

et voilà une sortie possible du script :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
----------------------------------------------
| 07 |    | 26 | 30 | 46 |    | 69 |    |    |
|    | 10 | 29 | 35 |    | 53 | 67 |    |    |
| 05 | 16 |    |    | 40 |    |    | 70 | 84 |
----------------------------------------------
Après quelques génération de grille, je me suis rendu compte que parfois sur une même ligne j'ai une série de nombre de plus de 3 à la suite, par exemple :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
----------------------------------------------
|    |    | 20 | 39 | 45 | 57 | 68 |    |    |
|    | 10 | 28 | 33 | 41 |    | 66 |    |    |
| 04 | 19 |    |    |    | 55 |    | 79 | 81 |
----------------------------------------------
On voit bien qu'il y a 5 nombres à la suite sur la première ligne et 4 à la seconde.
A votre avis, comment je peux faire pour limiter à 3 chiffres maximum ?

Edit: La nuit porte conseil, j'ai résolu le problème en vérifiant les cellules n-1, n-2, n+1 et n+2 c'est p'etre pas top, mais ça fonctionne.