No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Terminando de programar el juego

23/25
Recursos

Aportes 25

Preguntas 9

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Para los que no les funcione system(鈥渃ls鈥) pueden utilizar popen(鈥榗ls鈥, 鈥榳鈥);

隆Te reto a que ahora agregues a la personita para que tengamos un juego de ahorcado de verdad!
.
驴Tienes alguna idea de c贸mo podr铆amos hacerlo? 馃憖 Por su puesto que yo s铆, ac谩 te dejo mi soluci贸n a este reto:
.
Juego del ahorcado terminado
.
驴Qu茅 hay de ti? 驴C贸mo lo hiciste? 驴Pudiste agregar a la personita? 隆Comp谩rtenos tu soluci贸n ac谩! 馃憖馃憞

Queria compartirles el reto que me puse, correr el juego en el navegador:
Aun tengo que superar algunos bugs, pero ahi vamos, se esta logrando.
.

Reto terminado

Vistas



C贸digo

<?php

function clear() {

    if (PHP_OS === "WINNT")
        system("cls");
    else
        system("clear");

}

/* Solo agrega palabras */
$lista_palabras = ["programador", "gato", "comida", "desprolijo", "pensamiento", "satisfacci贸n", "dormir", "codear"];

// constantes
define("MAX_INTENTOS", 3);

// variables l贸gica
$palabra = $lista_palabras[rand(0, count($lista_palabras) -1)]; // resto porque los arrays comienzan en cero
$palabra = strtolower($palabra); // paso la palabra a minuscula para asegurar
$size_palabra = strlen($palabra);
$cadena_letras = str_pad("", 2*$size_palabra, "_ ");

// variables jugador
$vidas = 3;
$letra;
$gano = false; $econtro_letra = false;

// clear();
do{
    // inicio
    echo "\n\n\t隆Bienvenido al juego del ahorcado!\n\n\n";

    // va a variar
    echo "VIDAS = $vidas" . "\n\n";
    echo "\t\t" . $cadena_letras . "\n\n";
    $letra = readline("Ingrese una letra: ");
    $letra = strtolower($letra); // aseguramos que sea minuscula

    // busca coincidencia de la letra con la palabra, si es asi lo remplaza
    for ($i=0; $i < strlen($palabra) ; $i++) { 
        if( $letra == $palabra[$i]){
            // multiplico x2 a la posici贸n porque mi cadena es as铆 "_ _ _ _ _ _ _ _"
            $cadena_letras[2*$i] = $letra; $econtro_letra = true;
        }
    }

    // si no hubo por lo menos una coincidencia disminuye la vida
    if($econtro_letra == false){
        $vidas--;
    }
    $econtro_letra = false; // reiniciamos la variable

    // obtenemos la palabra encontrada, quitando espacios en blanco y guiones bajo
    $palabra_encontrada = preg_replace(array('/\s/', '/_/'), '', $cadena_letras);
    
    // termina el juego si econtro la palabra
    if($palabra == $palabra_encontrada){
        $gano = true; break;
    }
    
}while($vidas > 0 && $gano == false);

echo "\n\n\n\n";
if($gano == true){
    echo "\tFelicitaciones!!! 馃弳馃槉, econtraste la palabra";
    echo "\nPalabra m谩gica = " . $palabra;
}
else{
    echo "\tLo siento 馃槬, intentalo otra vez!!!馃槈";
    echo "\nPalabra m谩gica = " . $palabra;
    echo "\nEcontraste = " . $cadena_letras ;
}
echo "\n\nHecho por Keneth Lopez 馃挌\n\n\n";

?>

Para aquellos que les de este mensaje de error al ejecutar el juego
_ Fatal error: Uncaught Error: Call to undefined function str_contains()_
,se debe a la versi贸n del PHP. La soluci贸n es agregar un peque帽o polyfill.

if (!function_exists('str_contains')) {
  function str_contains(string $haystack, string $needle): bool
  {
      return '' === $needle || false !== strpos($haystack, $needle);
  }
}

es mejor poner siempre las llaves como por ejemplo en los if else, siento que para mi es una mejor pr谩ctica

Habra que implementar el mu帽equito pero de momento con el programa hecho en clase me pone feliz ver que la entend铆 la l贸gica del c贸digo solo que no sabia que exist铆an la mayor铆a de funciones jaja
Comparto el c贸digo como quedo (el de clase)
.

Hola, lo hice un poco diferente, y en ingles, no agregue la personita pero si algunas validaciones. Nota: no se como hacer para que me salga mi codigo aqui en el aporte como un screenshot tan bonito 馃槮 ayuda!

<code> 
<?php

$word_bank = ["immutable","interface","identifier","time","symfony","controller", "entity"];
define("MAX_ATTEMPS", 6);

while (true) {
    $word = $word_bank[rand(0, count($word_bank) - 1)];
    $word_length = strlen($word);
    $attemps = MAX_ATTEMPS;
    echo "Welcome to the game!!!\n";
    echo "The word you need to guess has " . $word_length . " letters" . " ..." . PHP_EOL;
    echo "Good luck!!!\n";
    $game = str_pad("", $word_length, "_");
    $discovered = false;

    do {
        echo "You have $attemps attemps available..." . PHP_EOL;
        echo $game . PHP_EOL .PHP_EOL;
        $letter = readline("Enter a letter:");
        $letter = strtolower($letter);

        if (strlen($letter) == 1) {
            if (str_contains($game, $letter)) {
                echo "Try a new letter.\n";
                cleanSreen();
                continue;
            }
        } else {
            echo "Yo can enter just 1 letter at a time.\n";
            cleanSreen();
            continue;
        }

        if (str_contains($word, $letter)) {
            $offset = 0;
            while (($position = strpos($word, $letter, $offset)) !== false) {
                $game[$position] = $letter;
                $offset = $position + 1;
            }
            echo "Good!";
            $discovered = ($game === $word);
        } else {
            $attemps--;
            echo "The letter is not in this word.\n";
        }
        cleanSreen();
    } while (($attemps > 0) && !$discovered);

    if ($discovered) {
        echo "Congratulations!!! the word is $game\n";
    } else {
        echo "I'm sorry. Game over.\n";
        echo "The word was $word.\n";
    }
    $continuePlaying = readline("Do you want to continue playing? Y/N \n");
    if (strtolower($continuePlaying) === 'n'){
        echo "Good bye!";
        cleanSreen();
        break;
    } else{
        cleanSreen();
    }
}

function cleanSreen() {
    sleep(2);
    if (PHP_OS === "WINNT") {
        system("cls");
    }
    else {
        system("clear");
    }
}

Esta es mi soluci贸n al reto:
1.- Se a帽ade el continuar jugando con un ciclo while
2.- Se coloca el mu帽eco de ahorcado con un arreglo que se imprime con un ciclo for que eval煤a el n煤mero de intentos
3.- Se corrige un error del programa cuando el usuario no introduce una letra, sino que presiona directamente enter generando una variable con contenido null.
Queda pendiente: un selector de temas con acceso a un arreglo asociativo.

<?php

function clear (){
    if (PHP_OS === "Linux"){
        system("clear");
    }
}

clear();

$hang_man = [
    "_____\n",
    "  |  \n  O \n",   //0
    " /",               //1
    "|",                //2
    "\\ \n",            //3
    " /",               //4
    " \\",              //5
];
$possible_words = ["Rat贸n", "Pantalla", "Asteroide", "Gallo", "Gato", "Bocina", "Bota", "Edificio", "Lluvia", "Estudiante"];
define("MAX_ATTEMPS",6);
$continue = 's';

echo "隆Juego del ahorcado! x_x \n\n";
//Inicializar juego
while ($continue == 's'){
    $choosen_word = $possible_words[rand(0,9)];
    $choosen_word =strtolower($choosen_word);
    $word_lenght = strlen($choosen_word);
    $discovered_letters = str_pad("_",$word_lenght,"_");
    $attemps = 0;
    sleep(2);
    
    do {
    clear();
    echo "Palabra de $word_lenght letras \n";
    echo $discovered_letters . "\n\n";
    for ($i=0;$i<=$attemps;$i++){
        echo $hang_man[$i];
    };
    echo "\n\n";
    
        //Pedimos al usuario que accese la letra
        $player_letter =  readline("Escribe una letra: ");
        if ($player_letter == null){
            continue;
        }
        else {
            $player_letter = strtolower($player_letter);
            
            if (str_contains($choosen_word, $player_letter)){
                $offset = 0;
                while (($letter_position = strpos($choosen_word,$player_letter,$offset)) !== false ){
                    $discovered_letters[$letter_position] = $player_letter;
                    $offset = $letter_position + 1;
                }
            }
            else {
        
                $attemps++;
                echo "\n Letra incorrecta >_<', te quedan " . (MAX_ATTEMPS - $attemps) . " intentos. \n";
                sleep(2); //pausa la ejecuci贸n en segundos
            }
        }
    } while( $attemps < MAX_ATTEMPS && $discovered_letters != $choosen_word );
    clear();
    if ($attemps < MAX_ATTEMPS)
        echo "隆Felicidades! Has adivinado la palabra. =) \n\n";
    else
        echo "Suerte para la pr贸xima, dude ;) \n\n";
    
    echo "La palabra es '$choosen_word' \n";
    echo "Descubriste las letras '$discovered_letters'";
    
    echo "\n\n";
    $continue = readline("Quieres seguir jugando? s/n: ");
    $continue = strtolower($continue);
}
echo "\n";

Para dibujar al hombrecito ahorcado, he creado esta funci贸n

function ahorcado($intentos){
    switch ($intentos) {
        case 1:
            echo "   ____\n  |    |\n  |    O\n  |\n  | \n  |\n-----\n";
            break;
        case 2:
            echo "   ____\n  |    |\n  |    O\n  |    | \n  |\n  |\n-----\n";
            break;
        case 3:
            echo "   ____\n  |    |\n  |    O\n  |   /| \n  |\n  |\n-----\n";
            break;
        case 4:
            echo "   ____\n  |    |\n  |    O\n  |   /|\ \n  |\n  |\n-----\n";
            break;
        case 5:
            echo "   ____\n  |    |\n  |    O\n  |   /|\ \n  |   /\n  |\n-----\n";
            break;
        case 6:
            echo "   ____\n  |    |\n  |    O\n  |   /|\ \n  |   / \ \n  |\n-----\n";
            break;
        default:
            echo "   ____\n  |    |\n  |\n  |\n  |\n  |\n-----\n";
            break;
    }

}

Y lo llamas dentro del ciclo do-while.

Complet茅 las Ideas a mejorar (retos) del juego

  • Que al terminar el juego ganado diga cuantos intentos le qued贸.
  • Que al terminar pregunte si quiere jugar de nuevo y reinicie el juego.

https://github.com/marcossarlo/juego-ahorcado-php

Estimados, comparto mi solucion. Es una adaptacion del mismo script que realice en el curso de python.
El archivo del require contiene el dibujo del ahorcado que lo tome de este git

<?php
    require('ascii_hangman.php');

    define('HEARTS', 7);
    // Lista de palabras
    $dictionary = ["Bebida", "Prisma", "Ala", "Dolor", "Piloto", "Baldosa", "Terremoto", "Asteroide", "Gallo", "Platzi"];

    // Obtener palabra del diccionario
    $selected_word = strtolower($dictionary[rand(0, count($dictionary)-1)]);
    $word_array = str_split($selected_word);
    $typed_letter = '';
    $offsets = array();

    $game_info = array(
        "word" => $word_array,
        "placeholder" => array_fill(0, count($word_array), '_'),
        "hearts" => HEARTS,
        "remaining_hearts" => HEARTS,
        "won_game" => false,
        "typed_letters" => []
    );

    while($game_info["remaining_hearts"] > 0 && !$game_info["won_game"]) {
        render($game_info, $hangman);

        if($game_info["word"] == $game_info["placeholder"]) {
            $game_info["won_game"] = true;
            break;
        }
        else {
            $typed_letter = readline("Escribe una letra: ");
            // Validar si es una letra
            if(ctype_alpha($typed_letter)) {
                $game_info["typed_letters"][] = $typed_letter;
                // Validar si la letra esta en la palabra
                if(in_array($typed_letter, $game_info["word"])) {
                    // Obtiene la posicion de la letra en la palabra
                    $offsets = array_keys($game_info["word"], $typed_letter);
                    foreach($offsets as $key) {
                        $game_info['placeholder'][$key] = $typed_letter;
                    }
                }
                // La letra no existe en la palagra, descontar una vida
                else {
                    $game_info['remaining_hearts']--;
                }
            }
            // No es una letra, descontar una vida
            else {
                $game_info['remaining_hearts']--;
            }
        }
    }

    if($game_info['won_game']) {
        echo PHP_EOL . "馃コ馃コ馃コ Felicidades, has ganado el juego 馃コ馃コ馃コ" . PHP_EOL . PHP_EOL;
    }
    else {
        render($game_info, $hangman);
        echo PHP_EOL . "馃槶馃槶馃槶 Lo siento, has perdido 馃槶馃槶馃槶" . PHP_EOL;
        echo PHP_EOL . "La palabra era: $selected_word" . PHP_EOL . PHP_EOL;
    }


    function render( array $game_info, array $hangman = []) {
        // Limpiar pantalla
        system('clear');
        $interface = array(
            "+==================================+" . PHP_EOL,
            "+++      Juego del ahorcado      +++" . PHP_EOL,
            "                                    " . PHP_EOL,
            "" . PHP_EOL,
            "                                    " . PHP_EOL,
            "Vidas   " .str_repeat("馃挅  ", $game_info["remaining_hearts"]) . PHP_EOL,
            "+==================================+" . PHP_EOL,
        );
        $interface[3] = implode(' ',$game_info['placeholder']) . PHP_EOL;
        // Imprime imagen del ahorcado junto con la interface
        for($i = 0, $size = count($interface); $i < $size; $i++) {
            $index = $game_info["hearts"] - $game_info["remaining_hearts"];
            echo $hangman[$index][$i] . '      ' . $interface[$i];
        }
    }

Profe lo unico que pude ver que falto es verificar que el jugador no digite ninguna letra, creo que una simple verificacion despues de que el usuario coloque su letra seria suficiente.

Grande ProfRetax

Ya se que es buena practica poner las palabras en ingles, pero durante el curso no lo tendria que hacer, porque para la gente como yo que no sabe me re limito entender el codigo y tengo que andar traduciendo que dice -.-

Reto mostrar al personaje comentado 馃槃

<?php

/*
1er reto: Refactorizar el codigo para que se vea mejor.
2do reto: Hacer el mu帽eco de ahorcado y que dependiendo de los intentos fallidos se vaya completando.
*/

//Con esta funcion limpiamos la consola.
function clear() {
    if(PHP_OS === "WINNT"){
        system("cls");
    } else{
        system("clear");
    }
}


//Aqui se hace un array con los estados por los que pasa el personaje.
$mu帽eco_ahorcado = [
    " +---+
      |   |
          |
          |
          |
          |
    =========",
     "
      +---+
      |   |
      O   |
          |
          |
          |
    =========", "
      +---+
      |   |
      O   |
      |   |
          |
          |
    =========", "
      +---+
      |   |
      O   |
     /|   |
          |
          |
    =========", "
      +---+
      |   |
      O   |
     /|\  |
          |
          |
    =========", "
      +---+
      |   |
      O   |
     /|\  |
     /    |
          |
    =========", "
      +---+
      |   |
      O   |
     /|\  |
     / \  |
          |
    ========="
];

$palabras_posibles = ["Gato", "Perro", "Pantera", "Tiburon", "Mosquito", "Hipopotamo", "Tigre", "Aguila", "Halcon", "Condor", "Tortuga"];

define("MAX_INTENTOS", 6);

echo "馃獪 隆JUEGO DEL AHORCADO!\n\n";

//Se inicializa el juego
$palabra_elegida = $palabras_posibles[rand(0, count($palabras_posibles) - 1)];
$palabra_elegida = strtolower($palabra_elegida);
$cantidad_palabras = strlen($palabra_elegida);
$descubre_letras = str_pad("", $cantidad_palabras, "_");
$intentos = 0;

do{

    echo "Palabra de $cantidad_palabras letras \n\n";
    echo $descubre_letras . "\n\n";

    // Pedimos al usuario que digite
    $letra_jugador = readline("Escribe una letra: " . "\n\n");
    $letra_jugador = strtolower($letra_jugador);

    if(str_contains($palabra_elegida, $letra_jugador)){
        
        // Verificar todas las ocurrencias de esta letra para remplazarla
        $offset = 0;
        while(
            ($posicion_letra = strpos($palabra_elegida, $letra_jugador, $offset)) 
            !== false
        ){
            
            $descubre_letras[$posicion_letra] = $letra_jugador;
            $offset = $posicion_letra + 1;
        }

    } else{

        clear();
        $intentos++;
        echo "Letra incorrecta 馃挃. Te quedan " . (MAX_INTENTOS - $intentos) . " intentos" . "\n\n";
        
        //Aqui hacemos un switch validando en que intento se encuentra el usuario en base a eso muestra al personaje que le corresponde.
        switch ($intentos) {
            case 0:
                echo $mu帽eco_ahorcado[0];
                break;
            case 1:
                echo $mu帽eco_ahorcado[1];
                break;
            case 2:
                echo $mu帽eco_ahorcado[2];
                break;
            case 3:
                echo $mu帽eco_ahorcado[3];
                break;
            case 4:
                echo $mu帽eco_ahorcado[4];
                break;
            case 5:
                echo $mu帽eco_ahorcado[5];
                break;
            case 6:
                echo $mu帽eco_ahorcado[6];
                break;
            default:
                echo "No se encontro mu帽eco";
                break;
        }
        sleep(2);

    }

    clear();

} while($intentos < MAX_INTENTOS && $descubre_letras != $palabra_elegida);

clear();

if($intentos < MAX_INTENTOS)
    echo "!FELICIDADES隆, HAS ADIVINADO LA PALABRA 馃槃 \n\n";
else
    echo "SUERTE A LA PROXIMA 馃挃 \n\n";

echo "La palabra es: $palabra_elegida \n\n";
echo "Tu descubriste $descubre_letras \n\n";

echo "\n";
<?php

function clear() {

    if (PHP_OS === "WINNT") {
        system("cls");
    }
    else {
        system("clear");
    }

}

$possible_words = ["Bebida", "Prisma", "Ala", "Dolor", "Piloto", "Baldosa", "Terremoto", "Asteroide", "Gallo", "Platzi"];

define("MAX_ATTEMPS", 6);

echo "馃樇 隆Juego del ahorcado! \n\n";

// Inicializamos el juegos
$choosen_word = $possible_words[ rand(0, 9) ];
$choosen_word = strtolower($choosen_word);
$word_length = strlen($choosen_word);
$discovered_letters = str_pad("", $word_length, "_");
$attempts = 0;

do {

    echo "Palabra de $word_length letras \n\n";
    echo $discovered_letters . "\n\n";

    // Pedimos al usuario que escriba
    $player_letter = readline("Escribe una letra: ");
    $player_letter = strtolower($player_letter);

    if ( str_contains($choosen_word, $player_letter) ) {

        // Verificamos todas las ocurrencias de esta letra para reemplazarla
        $offset = 0;
        while(
            ($letter_position = strpos($choosen_word, $player_letter, $offset)) !== false
        ) {

            $discovered_letters[$letter_position] = $player_letter;
            $offset = $letter_position + 1;

        }

    }
    else {

        clear();
        $attempts++;
        echo "Letra incorrecta 馃樉. Te quedan " . (MAX_ATTEMPS - $attempts) . " intentos.";
        sleep(2);

    }

    clear();

} while( $attempts < MAX_ATTEMPS && $discovered_letters != $choosen_word );

clear();

if ($attempts < MAX_ATTEMPS)
    echo "隆Felicidades! Has adivinado la palabra. 馃檧 \n\n";
else
    echo "Suerte para la pr贸xima, amigo. 馃樉 \n\n";

echo "La palabra es: $choosen_word\n";
echo "T煤 descubriste $discovered_letters";

echo "\n";

Los michis son chidos jajaja

<?php
//Hangman Game

function clear_console()
{
    if (PHP_OS !== "WINNT") {
        popen("clear", "w");
    } else {
        popen("cls", "w");
    }
}
$possible_words = ["Dog", "Hot", "one", "Twenty", "Friday", "Cat", "parallelepiped", "yellow", "blank"];
echo "Welcome 馃Ε Start the HANGMAN GAME! \n\n";
$word_chooser = strtolower($possible_words[rand(0, count($possible_words) - 1)]);
$word_length = strlen($word_chooser);
$discovered_letters = str_pad("", $word_length, "_");
$attempts = 0;
$lives = 6;
echo "Word of $word_length letters \n\n$discovered_letters\n\n";
do {
    $player_letter = strtolower(readline("Write a letter: "));
    if (str_contains($word_chooser, $player_letter) && $player_letter !== "") {
        $offset = 0;
        while (($letter_position = strpos($word_chooser, $player_letter, $offset)) !== false) {
            $discovered_letters[$letter_position] = "$player_letter";
            $offset = $letter_position + 1;
        }
        $attempts++;
        clear_console();
        echo "$discovered_letters \n\n";
        if ($discovered_letters === $word_chooser) {
            return print_r("Congratulations 馃コ It was $attempts attempts !!! \n\n");
        }
    } else {
        $attempts++;
        $lives--;
        clear_console();
        echo "Wrong letter 馃槥 You have $lives lives and you have $attempts attempts \n\n";
        echo "$discovered_letters \n\n";

        if ($lives == 0) {
            return print_r("GAME OVER! 馃く 馃拃 \n The word was $word_chooser \n");
        }
    }
} while ($discovered_letters !== $word_chooser || !$lives < 1);

A los que no les funciona el clear pueden intentar con:

popen('cls', 'w');

Les muestro otra alternativa para hacer el mismo juego.

<?php
$words = array('javier', 'platzi');

$word = str_split($words[array_rand($words)]);
$newWord = array_fill(0, count($word), '_');
echo implode(' ', $newWord) . "\n";

for ($i = 3; $i > 0; $i-- ) {
  echo "tienes $i / 3 oportunidades. \nIngresa una letra:";
  $letter = readline();
  $valid = false;
  foreach ($newWord as $key => $value) {
    if ($word[$key] === strtolower(substr($letter, 0, 1))) {
      $newWord[$key] = $word[$key];
      $valid = true;
    }
  };
  echo implode(' ', $newWord) . "\n";
  if ($valid) $i++;
  if ($word == $newWord) {
    echo "Ganaste \n";
    break;
  }
  if ($i === 1) echo "Perdiste";
}

Un saludo.
La funcion str_contains esta implementada en PHP para la version 8.0 en adelante.
Se debe instalar instalar PHP 8.0.19.

Con laragon, puede tener varias versiones y es muy facil de pasarlas, segun la necesidad.

Un abrazo virtual

Les comparto mi ejercicio

<?php

function clear ()
{
   if (PHP_OS === "WINNT") {
       system ("cls");
   }
   else {
       system ("clear");
   }
}
function dibujar ($attempts)
{
    $intento = $attempts;
    switch ($intento) {
        case 1:
            $Panchito = "*******\n***O***\n*******\n*******\n*******\n\n";
            break;
 
        case 2:
            $Panchito = "*******\n***O***\n***|***\n*******\n*******\n\n";
            break;

        case 3:
            $Panchito = "*******\n***O***\n*--|***\n*******\n*******\n\n";
            break;
     
        case 4:
            $Panchito = "*******\n***O***\n*--|--*\n*******\n*******\n\n";
            break;

        case 5:
            $Panchito = "*******\n***O***\n*--|--*\n**/****\n*******\n\n";
            break;
     
        case 6:
            $Panchito = "*******\n***O***\n**-|-**\n**/ \**\n*******\n\n";
            break;

        default:
        $Panchito = "*******\n*******\n*******\n*******\n*******\n\n";
            break;
    }
    return $Panchito;
}
$possible_words = ["Bebida", "Prisma", "Ala", "Dolor", "Piloto", "Baldosa", "Terremoto", "Asteroide", "Gallo", "Platzi"];
define ("MAX_ATTEMPS", 6);
// Inicializamos el juego
$choosen_word = $possible_words [ rand(0, 9)];
$choosen_word = strtolower ($choosen_word);
$word_length = strlen ($choosen_word);
$discovered_letters = str_pad ("", $word_length, "_");
$attempts= 0;
$panchito= "";

do{
    echo "隆Juego del Ahorcado! \n\n";
    echo dibujar($attempts);
    echo "Palabra de $word_length letras \n\n";
    echo $discovered_letters . "\n\n";

    //Pedimos al usuario que escriba
    $player_letter =readline ("Escribe una letra: ");
    $player_letter = strtolower($player_letter);

    if (str_contains($choosen_word, $player_letter)){
        //verificamos todas las ocurrencias de esta letra para reemplazarla
        $offset = 0;
        while(
            ($letter_position = strpos($choosen_word, $player_letter, $offset)) !== false )
            {
                $discovered_letters [$letter_position] = $player_letter;
                $offset = $letter_position + 1;
            }
    } else {
        clear();
        $attempts++;
        echo "letra incorrecta :c. te quedan " . (MAX_ATTEMPS - $attempts) . " intentos.";
        sleep(1);
    }
    clear();
}while ($attempts < MAX_ATTEMPS && $discovered_letters != $choosen_word);

clear();

if ($attempts < MAX_ATTEMPS) {
    echo dibujar($attempts);
    echo "\n\n";
    echo "隆Felicidades! has adivinado la palabra \n\n";
}
else{
    echo dibujar($attempts);
    echo "\n";
    echo "隆Suerte para la pr贸xima, amigo. \n\n";
}

echo "La palabra es $choosen_word \n";
echo "Tu descubriste $discovered_letters \n";

echo  "\n";

si ven que hay algo que optimizar, estoy abierto a sugerencias

<?php

// una funcion que nos ayude a limpiar la pantalla
function clear(){

// php tiene una constante pre definida que se llama PHP_OS, esto de aca me dice en cual sistema operativo mi programa me esta ejecutando 
// WINNT =  windows 
if(PHP_OS === "WINNT"){

    // ejecutaria una funcion llamada system que me permite ejecutar comandos del sistema (comandos del sistema operativo) y decirle que el comando que yo quiero ejecutar es (cls) que en windows es para limpiar la pantalla 
    system("cls");
} else {
    // en caso de que sea linux o mack sirve el comando clear 
    system("clear");
}

}

// Bienvenido al juego Ahorcado

// aca definimos las palabras que tendra nuestro juego, esto lo hacemos mediante un arreglo
$possible_words = [鈥淏ebida鈥, 鈥淧risma鈥,鈥淎la鈥, 鈥淒olor鈥,鈥淧iloto鈥,
鈥淏aldisa鈥, 鈥淭erremoto鈥, 鈥淎steroide鈥,鈥淕allo鈥,鈥淧latzi鈥漖;

// podemos definir una constante y se hace con define
// aca declaramos el maximo intentos por jugador
define(鈥淢AX_ATTEMPS鈥,6);

echo 鈥淏ienvenido al juego del ahorcado \n\n鈥;

                                // Incializamos el juego 

// yo deberia de ejegir de forma aleatoria algunas de estas palabras que estan en el array possible_words
$choosen_word = $possible_words[rand(0, 9)];
// convertimos todas las palabras a minuscula
$choosen_word = strtolower($choosen_word);
// necesitamos saber cuanto mide o cuantas letras tiene la palabra que me convirtio (vamos a calcular cuanto mide eso)
$word_length = strlen($choosen_word);
// normalmente en el juego ahorcado ahi unos _ o unos scor indicando que es
// un espacio que todavia no hemos adivinado en este caso tambien debemos de
// mostrasrselo al usuario y para eso yo lo voy a guardar en una nueva
// variable que se va a llamar $discovered_letters, por ultimo lo que tenemos que hacer
// es generar esos guines _ para eso podemos usar una funcion se php llamada str_pad
// esta funcion lo que hace es rellenar de lo que yo le indique un string, en este caso
// quiero rellenar un string de meros guiones bajos(),
// esta funcion recibe de primeras un string cual es el string que quiero rellenar un string vacio
// por que quiero generar un string de la nada, luego me pide cual va a hacer el largo de lo que yo quiero rellenar
// tamabien me pide cual va a hacer el string con el cual yo lo quiero rellenar
$discovered_letters = str_pad("", $word_length, "
");

                // vamos a empoezar a generar la interaccion con el usuario 

// vamos a generar una varibale que me va a decir cuantos intentos fallidos ha tenido mi usuarios
// con esto esta inicalizado el juego tambien
$attemps = 0;
do{

                        // iniciemos el juego 

// vamos a decir al usuario cuanto mide esta palabra 
echo "palabra de $word_length letras \n\n";
// tambien le vamos a dar otro mensaje y le vamos a decir cuantas letras a descubierto
echo $discovered_letters . "\n\n";

// pedimos al usario que escriba 
$player_letter = readline("escribe una letra: ");
$player_letter = strtolower($player_letter);

// esta funcion me dice si una letra existe en algun string, devulve true o false 
// dependiendo si una letra existe o no en un string 
// lo primero que me pide es que le diga por ejemplo cual es la palabra que yo quiero usar para buscar en este caso seria $choosen_word
// yo quiero buscar la letra que mi usuario ingreso $player_letter 
if(str_contains($choosen_word, $player_letter)){

// vamos a verificar basicamente en donde o cuantas veces aparece esa letra dentro de la palabra y tambien en donde aparece

                    // verificamos todas las ocurrencias de esta letra para reemplazarla 
    //esta variable $letter_position no influye nada en mi ciclo, gracias a la presedencia de php crea esta variable con el resultado de strpos()
    $offset = 0;
    while(($letter_position = strpos($choosen_word, $player_letter, $offset)) !== false ){

        $discovered_letters[$letter_position] = $player_letter;
        $offset = $letter_position + 1;
    }


} else {
    // en el caso en el que no exista, es aumentarle su numero en intentos en uno 
    clear();
    $attemps++;
    echo "Letra Inconrrecta. Te quedan " . (MAX_ATTEMPS - $attemps) . " intentos";
    // vamos a decirle a mi programa de que antes que se vuelva a repetir que me de chance de leer el error 
    sleep(2); //2 segundos
}
clear();
// si mi numero de intentos es menor que MAX_ATTEMPS, mientras yo todavia tenga intentos disponibles quiero que esto se siga repitiendo y que discovered_letters sea diferente a $choosen_word

} while ( $attemps < MAX_ATTEMPS && $discovered_letters != $choosen_word);

clear();
// vamos a informarle a mi usuarios si gano o perdio 
if($attemps < MAX_ATTEMPS){
    echo "Felicidades has adivinado la palabra.  \n\n";
} else {
    echo " Suerte para la proxima amigo \n\n";
}

echo "La paralabra es: $choosen_word \n\n";
// estas son las letras que descubrio mi usuario 
echo "Tu descubriste $discovered_letters";

echo 鈥淺n鈥;

Sufr铆 m谩s de la cuenta con el while por no poner bien los parentesis de la validaci贸n. Pero fue un hit el reto

隆Hola! Ac谩 les dejo mi ejercicio. Espero se puedan ver bien los caracteres Unicode en sus terminales, en mi terminal de Visual Studio Code parec铆a verse bien.

<?php

function showAhorcado($remainAttempts)
{
    switch ($remainAttempts) {
        case 0:
            echo "馃槃 JUEGO DEL AHORCADO 馃槃\n\n";
            echo "\u{250C}\n";
            echo "\u{2502}\n";
            echo "\u{2502}\n";
            echo "\u{2502}\n";
            echo "\u{2502}\n";
            echo "\u{2502}\n";
            echo "\u{2502}\n";
            echo "\u{2502}\n";
            echo "\u{2534}\u{2500}\u{2500}\n";
            echo "\n\n\n";
            break;
        case 1:
            echo "馃槂 JUEGO DEL AHORCADO 馃槂\n\n";
            echo "\u{250F}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{253B}\u{2501}\u{2501}\n";
            echo "\n\n\n";
            break;
        case 2:
            echo "馃槓 JUEGO DEL AHORCADO 馃槓\n\n";
            echo "\u{250F}\u{2501}\u{2501}\u{2501}\u{2501}\u{2513}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{253B}\u{2501}\u{2501}\n";
            echo "\n\n\n";
            break;
        case 3:
            echo "馃槦 JUEGO DEL AHORCADO 馃槦\n\n";
            echo "\u{250F}\u{2501}\u{2501}\u{2501}\u{2501}\u{2513}\n";
            echo "\u{2503}   \u{256D}\u{2538}\u{256E}\n";
            echo "\u{2503}   \u{2570}\u{2500}\u{256F}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{253B}\u{2501}\u{2501}\n";
            echo "\n\n\n";
            break;
        case 4:
            echo "馃槥 JUEGO DEL AHORCADO 馃槥\n\n";
            echo "\u{250F}\u{2501}\u{2501}\u{2501}\u{2501}\u{2513}\n";
            echo "\u{2503}   \u{256D}\u{2538}\u{256E}\n";
            echo "\u{2503}   \u{2570}\u{2530}\u{256F}\n";
            echo "\u{2503}    \u{2503}\n";
            echo "\u{2503}    \u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{253B}\u{2501}\u{2501}\n";
            echo "\n\n\n";
            break;
        case 5:
            echo "馃槰 JUEGO DEL AHORCADO 馃槰\n\n";
            echo "\u{250F}\u{2501}\u{2501}\u{2501}\u{2501}\u{2513}\n";
            echo "\u{2503}   \u{256D}\u{2538}\u{256E}\n";
            echo "\u{2503}   \u{2570}\u{2530}\u{256F}\n";
            echo "\u{2503}  \u{2501}\u{2501}\u{254B}\u{2501}\u{2501}\n";
            echo "\u{2503}    \u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{253B}\u{2501}\u{2501}\n";
            echo "\n\n\n";
            break;
        case 6:
            echo "馃槶 JUEGO DEL AHORCADO 馃槶\n\n";
            echo "\u{250F}\u{2501}\u{2501}\u{2501}\u{2501}\u{2513} \u{1F480}\n";
            echo "\u{2503}   \u{256D}\u{2538}\u{256E}\n";
            echo "\u{2503}   \u{2570}\u{2530}\u{256F}\n";
            echo "\u{2503}  \u{2501}\u{2501}\u{254B}\u{2501}\u{2501}\n";
            echo "\u{2503}    \u{2503}\n";
            echo "\u{2503}   \u{250F}\u{253B}\u{2513}\n";
            echo "\u{2503}   \u{2503} \u{2503}\n";
            echo "\u{2503}\n";
            echo "\u{253B}\u{2501}\u{2501}\n";
            break;
    }
}

// Inicializamos el juego
$possibleWords = [
    'BEBIDA', 'PRISMA', 'ALA', 'DOLOR', 'PILOTO', 'BALDOSA', 'NUEVO', 'TERREMOTO', 'ASTEROIDE', 'GALLO', 'PLATZI', 'ERIZO', 'RED', 'TARRO', 'PARA', 'COMIDA', 'MICHI', 'GATOS', 'ARTE', 'GLOSARIO', 'DESARROLLO', 'FILOSOFIA', 'AEROPUERTO', 'CARPA', 'QUINQUE', 'ALARIDO', 'RIZAR', 'GUERRA', 'AGUA', 'AZAFATA', 'SOMETIDO', 'GUIRNALDA', 'GRANDE', 'TRAPECIO', 'TELEFONO', 'PIZCA', 'CIRROSIS', 'ARENA',
];
define('MAX_ATTEMPTS', 6);

do {
    $choosenWord       = $possibleWords[rand(0, count($possibleWords) - 1)];
    $choosenWord       = strtoupper($choosenWord);
    $wordLength        = strlen($choosenWord);
    $discoveredLetters = str_pad('', $wordLength, '_');
    $attempts          = 0;
    do {
        echo PHP_OS === 'WINNT' ? `cls` : `clear`;
        showAhorcado($attempts);

        echo "Adivina la palabra de $wordLength letras.\n\n";
        echo 'Te quedan '.MAX_ATTEMPTS - $attempts." intentos.\t";
        echo $discoveredLetters."\n\n";

        $playerLetter = readline('Escribe una letra: ');
        $playerLetter = substr($playerLetter, 0, 1);
        $playerLetter = strtoupper($playerLetter);

        if (str_contains($choosenWord, $playerLetter)) {
            $offset = 0;
            // Verificar ocurrencias de la letra para reemplazarla
            while (($letterPosition = strpos($choosenWord, $playerLetter, $offset)) !== false) {
                echo $letterPosition."\n";
                $discoveredLetters[$letterPosition] = $playerLetter;
                $offset                             = $letterPosition + 1;
            }
        } else {
            $attempts++;
        }
    }
    while ($attempts < 6 && str_contains($discoveredLetters, '_'));

    echo PHP_OS === 'WINNT' ? `cls` : `clear`;
    showAhorcado($attempts);
    if ($attempts == 6) {
        echo "\n\nYa no tienes intentos restantes.\n";
        echo 'La palabra por encontrar era '.$choosenWord;
    } else {
        echo "\n隆Ganaste! (Intentos restantes: ".MAX_ATTEMPTS - $attempts.")\n";
        echo 'Hallaste la palabra, es: '.$choosenWord;
    }
    echo "\n\n";

    do {
        $continueGame = readLine('Deseas jugar de nuevo (S/N)?: ');
        $continueGame = strtoupper($continueGame);
    } while (!($continueGame === 'S' || $continueGame === 'N'));
} while ($continueGame === 'S');

echo "\n\n";