8768 sujets

Développement web côté serveur, CMS

Bonjour,

J'essaie de faire un jeu en php très fortement inspiré du jeu Motus de France 2. Et je bute sur l'affichage des caractères.
Imaginons que le mot à trouver soit TAPAGE

Si j'entre par exemple 3 fois la lettre A, par exemple ANANAS, dans ce cas précis, il va me trouver 3 fois la lettre A mal placée alors qu'il n'y a que 2 A dans le mot à trouver.

Voici ce que je fais :

for ($i = 0; $i< $_SESSION['longueur']; $i++){
					
					$trouve='$masolution[$i]';
					$position = strpos($_SESSION['motdujour'], $masolution[$i]);		// on cherche la position de la lettre entree dans le mot
					if ($position === false){											// la lettre n'est pas dans le mot
						echo "<div class='lettre_absente'>$masolution[$i]</div>";

					}

					if ($_SESSION['motdujour'][$i] == $masolution[$i]){					// la lettre est bien placee
						echo "<div class='lettre_placee'>$masolution[$i]</div>";
						$nb=$nb+1;
						if ($nb == $_SESSION['longueur']){							// le mot a été trouvé
							echo 'trouve';
							unset($_SESSION['motdujour']);
							}
					}

					if (($position !== false) && ($_SESSION['motdujour'][$i] != $masolution[$i])){ // la lettre est dans le mot mais mal placée
						echo "<div class='lettre_non_placee'>$masolution[$i]</div>";
					}
				}

En fait, ça cloche sur le 3ème choix. Si le nombre de lettres existantes dans le mot est égal au nombre de lettres mal placées de ma proposition, ca fonctionne. Sinon, le résultat est faux.
Quelqu'un peut m'aider svp ?
Modifié par Equinoxe58 (01 Feb 2023 - 11:18)
Salut,
Je pense que l'algo qui doit être mit en place est un peu plus complexe que ce tu as fais.


Je comprend pas cette ligne : $trouve='$masolution[$i]';
Bonjour,

Pour la ligne dont tu parles, c'est une ligne parasite lors de mes essais. Elle ne devrait pas se trouver là.
Pour mon problème, je suis d'accord avec toi que l'algo devrait être différent (Voire plus compliqué), et c'est bien là que je coince.
J'ai l'idée dans la tête mais je ne vois pas comment la coder.
Je pense que je dois analyser chaque lettre (bien placée, mal placée ou absente du mot) et à la fin de la boucle, la remplacer par un caractère interdit dans la saisie. Par exemple un tiret.
Ce qui fait que je ne retomberai pas sur le caractère testé. C'est ça la solution tu penses ?
Modérateur
Salut,

JENCAL a écrit :

Je pense que l'algo qui doit être mit en place est un peu plus complexe que ce tu as fais.

Au contraire, je pense qu'il est simple.[^1][^2]



<?php
    $founded = str_split('passant');
    $copy = array_slice($founded, 0);
        
    $tpl = '<span class="button %s">%s</span>';
    $output = '';

    if(!empty($_POST['search'])){
        $answer = str_split(strtolower(trim($_POST['search'])));
        if(count($founded) === count($answer)){
            foreach($answer as $k => $v){
                if($founded[$k] === $v){
                    $output .= sprintf($tpl, "success", $v);
                }else if(in_array($v, $copy)){
                    $index = array_search($v, $copy);
                    unset($copy[$index]);
                    $output .= sprintf($tpl, "warning", $v);
                }else{
                    $output .= sprintf($tpl, "secondary", $v);
                }
            }
        }
    }
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.5/dist/css/foundation.min.css" crossorigin="anonymous">
        <style>
            main{
                max-width: 600px;
                margin: 50px auto;
            }
            .button.secondary{
                color: #000;
                background-color: #fff;
            }
        </style>
    </head>
    <body>
    
        <main>
            <form action="<?= $_SERVER['PHP_SELF'] ?>" method="post" autocomplete="off">
                <div class="grid-container">
                    <div class="grid-x grid-padding-x">
                        <div class="medium-6 cell">
                            <label>
                                <input type="text" name="search" value="annanas" placeholder="mot à chercher">
                            </label>
                        </div>
                        <div class="medium-6 cell">
                            <button type="submit" class="button">envoyer</button>
                        </div>
                    </div>
                </div>
            </form>
            <p><?= $output ?></p>
        </main>
    </body>
</html>


[^1]: Ma pirouette pour détourner le comportement de la réponse ne doit pas être pris en compte. Il me fallait un jeu de couleurs. Alors, j'ai pris ce que propose la class button de zurb. Refaire du php, ouch ! str_split m'a fait mal à la tête....(str_split VS explode / count VS str_len / etc.) En Python, c'est tellement plus simple....
[^2] Liste de tous les mots de 7 lettres
Modifié par niuxe (01 Feb 2023 - 11:56)
niuxe a écrit :
Salut,


Au contraire, je pense qu'il est simple.[^1]



bah d'après ce que j'ai compris il souhaite savoir si une lettre est bien placé, mal placé, peu importe le nombre de lettre, je dis ça car je vois dans ton code
if(count($founded) === count($answer))

Et en plus il faut pas traiter les doublons de lettre
si on compare
PASSANT et MARCHER

il faut que le A de marcher soit en retour "bien placé" mais pas traité pour le deuxième A de PASSANT.
Donc je pense que c'est plus complexe
Modifié par JENCAL (01 Feb 2023 - 12:00)
Modérateur
JENCAL a écrit :


...
if(count($founded) === count($answer))

Dans Motus, tu dois avoir le même nombre de cars. Smiley cligne

JENCAL a écrit :

Et en plus il faut pas traiter les doublons de lettre
si on compare
PASSANT et MARCHER

il faut que le A de marcher soit en retour "bien placé" mais pas traité pour le deuxieme A de PASSANT.
Donc je pense que c'est plus complexe

test mon code Smiley cligne

oups, je viens de m'apercevoir d'avoir fait une faute ... found et non founded Smiley confused
Modifié par niuxe (01 Feb 2023 - 12:01)
Salut,

Je suis d'accord, je pense que cela va être plus compliqué ^^'

Pour le code de niuxe, a priori cela ne fonctionne pas avec 'ananass' (j'ai rajouté un s pour avoir le même nombre de lettre) : cela m'indique que les 2 premiers 'a' sont mal placés et cela n'indique pas que le 3e a est bien placé. Je crois que cela devrait indiqué le 3e a bien placé et un seul a mal placé.

Perso j'aurai tendance à séparé l'algo d'un coté et l'affichage du résultat d'un autre.
A priori pour pouvoir faire ça j'aurai tendance à faire une "structure" (classe ou tableau associatif je sais pas trop) qui permettrais de stocker l'état de chaque lettre (aussi bien pour le mot saisie que pour le mot que l'on recherche (et pour celui la il doit falloir le doubler pour avoir un qui sert sur la comparaison en cours et l'autre pour un genre d'historique des lettres déjà trouvés) : la lettre , la position dans le mot, et son état (un truc du genre "inconnu" au départ puis au choix / bien placé / mal placé / absent)

De base je dirais qu'il faudrait faire ça en deux phases :
- les lettres bien placés qui sont facile à traiter en comparant lettre à lettre sans réfléchir
- les lettres mal placés (et uniquement celles la, on dégage les biens placés de ce traitement dans les 2 mots) qui sont un poil plus compliqué : est ce qu'elles sont présente dans les lettres restantes du mot ou pas.
Bon du coup mini test de faire code qui m'a l'air ok je crois (c'est sans doute un peu crade j'ai fais au fur et à mesure que les idées venaient puis j'ai vaguement adapté pour faire marché les cases comme niuxe)


    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.5/dist/css/foundation.min.css" crossorigin="anonymous">
        <style>
            main{
                max-width: 600px;
                margin: 50px auto;
            }
            .button.secondary{
                color: #000;
                background-color: #fff;
            }
        </style>
    </head>

<?php

class lettre {
public $lettre;
public $position;
public $valide  = "secondary";

function __construct($k , $v) {
        $this->lettre = $v;
        $this->position = $k;
    }
}

$MDJ = "PASSANT";
$tab_MDJ= [];
$MS = "ANANASS";
$tab_MS= [];

$chars = str_split($MDJ);
foreach($chars as $k => $v){
    $tab_MDJ[]=new lettre($k , $v);
} 

$chars = str_split($MS);
foreach($chars as $k => $v){
    $tab_MS[]=new lettre($k, $v);
}
//1 : on compare 1 par 1 et on marque les valides :
for($i=0; $i < strlen($MDJ); $i++)
{
  if($tab_MS[$i]->lettre == $tab_MDJ[$i]->lettre)
  {
    $tab_MS[$i]->valide = $tab_MDJ[$i]->valide = "success";
  }
} 

//2 : on ne travail plus que sur ceux qui sont inconnus :
/*
function inconnu($var)
{
    return ($var->valide=="Inconnu");
}

$tab_MS2  = array_filter($tab_MS, "inconnu");
$tab_MDJ2  = array_filter($tab_MDJ, "inconnu");

//var_dump($tab_MDJ2);print "<br><br>";var_dump($tab_MS2);
*/

for($i=0; $i < strlen($MDJ); $i++)
{
  if($tab_MS[$i]->valide == "success")
  {
    continue;
  }

  for($j=0; $j < strlen($MDJ); $j++)
  {
    if($tab_MDJ[$j]->valide == "success") 
    {
      continue;
    }

//    print("Compare i:$i et j:$j ".$tab_MS[$i]->lettre." et ".$tab_MDJ[$j]->lettre."<br>");

    if($tab_MS[$i]->lettre == $tab_MDJ[$j]->lettre and $tab_MDJ[$j]->valide =="secondary")
    {
      $tab_MS[$i]->valide = $tab_MDJ[$j]->valide = "warning";
      break;
    }

  }
}

//var_dump($tab_MDJ);print "<br><br>";var_dump($tab_MS);
$tpl = '<span class="button %s">%s</span>';
$output = '';

for($i=0; $i < strlen($MDJ); $i++)
{
    $output .= sprintf($tpl, $tab_MDJ[$i]->valide, $tab_MDJ[$i]->lettre);
}
$output.="<br>";
for($i=0; $i < strlen($MDJ); $i++)
{
    $output .= sprintf($tpl, $tab_MS[$i]->valide, $tab_MS[$i]->lettre);
}

print($output);


?>

Modérateur
oui, tout à l'heure, j'ai vu un bug. Je viens de corriger :


<?php
    $found = str_split('passant');
    $copy = array_slice($found, 0);
    $result = [];
    $tpl = '<span class="button %s">%s</span>';
    $output = '';

    if(!empty($_POST['search'])){
        $answer = str_split(strtolower(trim($_POST['search'])));
        if(count($found) === count($answer)){
            foreach($answer as $k => $v){
                $is_found = $found[$k] === $v;
                $result[$k] = [
                    'char' => $v,
                    'cls' => $is_found? "success" : "secondary",
                ];
                if($is_found){
                    unset($copy[$k]);
                }
            }
            
            foreach($result as $k => $v){
                if($v['cls'] === "secondary" && in_array($v['char'], $copy)){
                    $result[$k]['cls'] = "warning";
                    $index = array_search($v['char'], $copy);
                    unset($copy[$index]);
                }
            }

            foreach($result as $k => $v){
                $output .= sprintf($tpl, $v['cls'], $v['char']);
            }
        }
    }
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.5/dist/css/foundation.min.css" crossorigin="anonymous">
        <style>
            main{
                max-width: 600px;
                margin: 50px auto;
            }
            .button.secondary{
                color: #000;
                background-color: #fff;
            }
        </style>
    </head>
    <body>
    
        <main>
            <form action="<?= $_SERVER['PHP_SELF'] ?>" method="post" autocomplete="off">
                <div class="grid-container">
                    <div class="grid-x grid-padding-x">
                        <div class="medium-6 cell">
                            <label>
                                <input type="text" name="search" value="annanas" placeholder="mot à chercher">
                            </label>
                        </div>
                        <div class="medium-6 cell">
                            <button type="submit" class="button">envoyer</button>
                        </div>
                    </div>
                </div>
            </form>
            <p><?= $output ?></p>
        </main>
    </body>
</html>

Modifié par niuxe (01 Feb 2023 - 23:20)
Meilleure solution
Bonsoir,
Je vous remercie pour votre aide.
Je vais essayer les diverses solutions et surtout essayer d'adapter à ce que j'ai déjà fait.
Bonsoir,
J'ai testé la solution de Niuxe et elle fonctionne parfaitement.
Je vous remercie énormément pour votre aide.
Modifié par Equinoxe58 (02 Feb 2023 - 18:48)