Jump to content

Word game function


jshc86

Recommended Posts

I have an interesting dilemma. I am writing a script for a game called Jotto. If you haven't heard of it, a challenger selects a five letter word and people try to guess what the word is by choosing other five letter words; at that point, the challenger tells the guesser how many letters their word has in common with the challenger's word. Using logic, you can eventually deduce what the word is by eliminating letters of the alphabet.

 

As an example, say the challenger's word is "class". A typical game would look something like this. Note: I'm including which letters are in common for demonstrative purposes...I wouldn't actually do that if a game is going on.

 

Guessed word[/td]Letters in common

slimy2 (l and s)

saucy3 (a, c and s)

sassy3 (a and s twice)

class[td]5 (winner)

 

You'll notice for "sassy", their are three letters in common, two of which come from the double "s". BUT, the extra "s" in "sassy" does not count because the challenge word only contains the letter "s" twice. Anyways, I am writing a script to take a guessed word and compare it to the challenger's word. Here's the original script I tried which DOESN'T work:

 

<?php

$guessed_word = "sassy";
$challenge_word = "class";

// Break up each word into its letters
$g_array = str_split($guessed_word);
$c_array = str_split($challenge_word);

// Check for letters in common
$common = array_intersect($g_array, $c_array);
echo count($common); // Returns 4 and NOT 3

?>

 

Now I'm aware that switching the order of the arguments in the array_intersect part of my code WILL return a value of 3 like I wanted, but if you fiddle around with it enough, you'll see that the array_intersect function won't do. So, I decided to write a custom function instead. The method behind the function is: break up the two words into their letters, run a while loop for the guessed word while array_shift returns true, check if the letter from array_shift is found in the challenge word array, if it is found remove the letter from the challenge word array, add 1 to my counter variable and repeat. Here's what that looks like:

 

<?php

function jots($word1, $word2) {

	// The guessed word
	$g_word = str_split($word1);

	// The challenger's word
	$c_word = str_split($word2);

	// Initialize counter
	$i = 0;

	if($c_word == $g_word) {
		echo 6; // This is if the person gets the word correct...6 is my indicator for a winning game
	}
	else {
		while($letter = array_shift($g_word)) {
			if($key = array_search($letter, $c_word)) {
                                        
                                        // Remove the found letter from the challenge word array
				unset($c_word[$key]);
			        $i++;
			}
		}
		echo "The word has {$i} letters in common";
	}
}
?>

 

Theoretically this should work. However it still gives me problems. See the code below to see what I mean.

 

<?php

jots("linus", "linux");
// Returns "The word has 3 letters in common" when really it's 4

jots("light", "right");
// Returns "The word has 4 letters in common", which is correct...but it's similar to the above example where only 1 letter is different. GRRR!!
?>

 

This is pretty frustrating. Does anyone have any ideas?

Link to comment
Share on other sites

How abouts we make it a really simple function instead :)

function jotts($answer, $guess) {
    $out = array_diff(str_split($answer), str_split($guess));
    return strlen($answer) - count($out);
}

echo jotts('linus', 'linux');

Link to comment
Share on other sites

How about this instead - I finally guessed what it was the game did

function jotts($answer, $guess) {
    $count = 0;
    $a = str_split($answer);
    $g = str_split($guess);
    foreach($g as $v) {
        $key = array_search($v, $a);
        if($key !== FALSE) {
            unset($a[$key]);
            $count++;
        }
    }
    
    echo 'Total jotts for <strong>'.$guess.'</strong> in word <strong>'.$answer.'</strong> is <strong>'.$count.'</strong><br />';
}

jotts('class', 'slimy');
jotts('class', 'saucy');
jotts('class', 'sassy');
jotts('class', 'class');
jotts('linus', 'linux');
jotts('light', 'right');

This returns

Total jotts for slimy in word class is 2
Total jotts for saucy in word class is 3
Total jotts for sassy in word class is 3
Total jotts for class in word class is 5
Total jotts for linux in word linus is 4
Total jotts for right in word light is 4

Link to comment
Share on other sites

Thanks JAY for your help. Right after I posted I actually thought that the foreach loop would work. I'm curious as to why array_shift gives unpredictable results though?

 

To clarify, there are multiple versions of Jotto that are played. In my case, the exact placement of the letters is not important. So if the challenge word was "tenet", and my guess was "atlas", it would still count for 1 even though the "t" is not in the correct place. However, if exact placement DID matter, my guess of "atlas" would yield zero because none of the letters are in the correct place.

Link to comment
Share on other sites

The problem is that you have the assigning of array_search() to $key in an if() statement. The first pass of this won't work simply because 0 is equivalent to false, meaning that the unset will never happen for the first character (at key 0). This is visible if you do some debugging. Just add

echo "LETTER: $letter - KEY: $key - i: $i<br />";

at the very end of the while loop just before the } and you get the following output

LETTER: l - KEY: 0 - i: 0
LETTER: i - KEY: 1 - i: 1
LETTER: n - KEY: 2 - i: 2
LETTER: u - KEY: 3 - i: 3
LETTER: s - KEY: - i: 3

It becomes more apparent with this, as you see the $key is matched as 0 with the l, but $i does not increase when it should. Changing your code to

function jots($word1, $word2)
{

    // The guessed word
    $g_word = str_split($word1);
    // The challenger's word
    $c_word = str_split($word2);
    // Initialize counter
    $i = 0;
    if ($c_word == $g_word) {
        echo 6; // This is if the person gets the word correct...6 is my indicator for a winning game
    } else {
        while ($letter = array_shift($g_word)) {
            $key = array_search($letter, $c_word);
            if ($key !== FALSE) {
                // Remove the found letter from the challenge word array
                unset($c_word[$key]);
                $i++;
            }
        }
        echo "The word has {$i} letters in common";
    }
}

Hope that clears up the reasoning :)

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.