Question

I am trying to do something similar to hangman where when you guess a letter, it replaces an underscore with what the letter is. I have come up with a way, but it seems very inefficient and I am wondering if there is a better way. Here is what I have -

<?
$word = 'ball';
$lettersGuessed = array('b','a');

echo str_replace( $lettersGuessed , '_' , $word ); // __ll

echo '<br>';

$wordArray = str_split ( $word );

foreach ( $wordArray as $letterCheck )
{

    if ( in_array( $letterCheck, $lettersGuessed ) )
    {
        $finalWord .= $letterCheck;
    } else {
        $finalWord .= '_';
    }

}

echo $finalWord; // ba__
?>

str_replace does the opposite of what I want. I want what the value of $finalWord is without having to go through a loop to get the result I desire.

Was it helpful?

Solution

If I am following you right you want to do the opposite of the first line:

echo str_replace( $lettersGuessed , '_' , $word ); // __ll

Why not create an array of $opposite = range('a', 'z'); and then use array_diff () against $lettersGuessed, which will give you an array of unguessed letters. It would certainly save a few lines of code. Such as:

$all_letters = range('a', 'z');
$unguessed = array_diff ($all_letters, $lettersGuessed);
echo str_replace( $unguessed , '_' , $word ); // ba__

OTHER TIPS

It's an array, foreach is what you're suppose to be doing, it's lightning fast anyways, I think you are obsessing over something that's not even a problem.

You want to use an array becuase you can easily tell which indexes in the array are the ones that contain the letter, which directly correlates to which place in the string the _ should become a letter.

Your foreach loop is a fine way to do it. It won't be slow because your words will never be huge.

You can also create a regex pattern with the guessed letters to replace everything except those letters. Like this:

$word = 'ball';
$lettersGuessed = array('b','a');
$pattern = '/[^' . implode('', $lettersGuessed) . ']/';   // results in '/[^ba]/
$maskedWord = preg_replace($pattern, '_', $word);
echo $maskedWord;

Another way would be to access the string as an array, e.g.

$word = 'ball';
$length = strlen($word);
$mask = str_pad('', $length, '_');
$guessed = 'l';

for($i = 0; $i < $length; $i++) {
    if($word[$i] === $guessed) {
        $mask[$i] = $guessed;
    }
}
echo $mask; // __ll
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top