views:

97

answers:

5

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 php loop to get the result I desire.

+2  A: 

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.

TravisO
so what do you recommend as the solution?
scott
+2  A: 

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__
Meep3D
+1  A: 

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;
Scott Saunders
A: 

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
Gordon
A: 

You can use this piece of code build a string containing the letters that are correctly guessed.

$word = 'ball';
$guessed = array('b','a');
$out = "";

foreach (str_split($word) as $char)
{
  if in_array($char, $guessed)
    $out += $char;
  else
    $out += "_";
}

echo $out; // ba__
Veger