Php - robot name - cannot pass last test - name has to be unique

Hi,

I’m supposed to create a robot name and that works. I can also replace it by a new one.
But, the name has to be unique. To do so, I’ve created an array and I push the new name into the array after I’ve checked it doesn’t exist there already with in_array().
It works in test 5 and I can see the count of the array growing as new names are added. I does not work however in test 6 and I can see that the count of the array remains 1, new names are not added, the array seems to be recreated each time functions are called.
I don’t know why. I’m quite new to classes and I don’t find the info I need. Maybe a good link would help me?

Here’ s the code:

class Robot
{    
    function __construct() {
        $this->allNames = array();
        $this->name = $this->setName();
    }
    private function createName()  {
        $robotName = $this->createRandomChar() ;
        $robotName .= $this->createRandomChar();
        $robotName .= rand(100, 999);
        $result = $this->compareToAllNames($robotName);
        return ($result) ? $this->createName() : $robotName;        
    }
    private function setName() : string {
        $this->name = $this->createName();
        $this->setAllNames($this->name);
        return $this->name;
    }
    public function getName(): string {
        return $this->name;
    }
    private function setAllNames($newName) {
        array_push($this->allNames, $newName);            
        echo "count allNames: " . count($this->allNames) . "\n";
        return $this->allNames;
    }
    private function compareToAllNames($name) : bool {
        return in_array($name, $this->allNames); 
    }
    private function createRandomChar() : string {
        return chr(rand(65, 90));
    }    
    public function reset(): void {
        $robotName = $this->getName();
        $robotName = $this->setName();
    }
}

Here is test 5 that I’m passing :


Test 5 : Name aren't recycled

$names = [];

for ($i = 0; $i < 10000; $i++) {
    $name = $this->robot->getName();
    $this->assertFalse(isset($names[$name]), sprintf('Name %s reissued after Reset.', $name));
    $names[$name] = true;
    $this->robot->reset();
}

### Your Output

count allNames: 1 
count allNames: 2 
count allNames: 3 
count allNames: 4 
count allNames: 5 
count allNames: 6 
count allNames: 7 
count allNames: 8 
count allNames: 9 
count allNames: 10

And the last one I’m not passing :

Test 6 : Name uniqueness many robots

Code Run

$names = [];

for ($i = 0; $i < 10000; $i++) {
    $name = (new Robot())->getName();
    $this->assertFalse(isset($names[$name]), sprintf('Name %s reissued after %d robots', $name, $i));
    $names[$name] = true;
}

Test Failure

RobotNameTest::testNameUniquenessManyRobots
Name JA754 reissued after 1404 robots
Failed asserting that true is false.

RobotNameTest.php:111

Your Output

count allNames: 1
count allNames: 1
count allNames: 1
count allNames: 1
count allNames: 1
count allNames: 1
count allNames: 1

The tests go on for 10000 names.
I’m out of my depth.
Can you help me?

Thank you,
Karin

The problem is that the allNames array has to remember the names for every robot. The way it’s defined:

means that each robot gets a different allNames array.

I suggest you do some reading in the PHP docs:

I read your suggestions and solved it with the static keyword and then referred to the array with self::array in the functions below.

I had a question but I can discuss that with my mentor so I’m good here. I’m leaving the code for others who might be struggling with the same problem.

class Robot
{    
    public static $allRobotNames = array();
    
    function __construct() {
        $this->name = $this->setName();
    }
    private function createName()  {
        $robotName = $this->createRandomChar() ;
        $robotName .= $this->createRandomChar();
        $robotName .= rand(100, 999);
        $result = $this->compareToAllNames($robotName);
        return ($result) ? $this->createName() : $robotName;        
    }
    private function setName() : string {
        $this->name = $this->createName();
        $this->setAllNames($this->name);
        return $this->name;
    }
    public function getName(): string {
        return $this->name;
    }
    private function setAllNames($newName) {
        array_push(self::$allRobotNames, $newName);            
    }
    private function compareToAllNames($name) : bool {
        return in_array($name, self::$allRobotNames); 
    }
    private function createRandomChar() : string {
        return chr(rand(65, 90));
    }    
    public function reset(): void {
        $robotName = $this->getName();
        $robotName = $this->setName();
    }
}

Thanks for helping out!
Greets,
Karin