I am trying to make a browser game in Laravel, and having some trouble with understanding the documentation for factories.
So this is the situation, each hero has possible 5 skills. But the hero will be only assigned randomly 3 of the 5 skills.
1,2,3
1,2,4
1,2,5
2,3,4
2,3,5
3,4,5
Instead of duplicating the factory 6 times is there a way for it to create these unique combos?
Hero::factory()->create([
'hero_class' => 'Warrior',
'attribute_health' => 100,
'attribute_attack' => 35,
'attribute_armor' => 75,
'attribute_speed' => 22,
'attribute_crit' => 15,
'skill_1' => 1,
'skill_2' => 1,
'skill_3' => 1,
]);
I saw in docs you can do sequences
$users = User::factory()
->count(10)
->state(new Sequence(
['admin' => 'Y'],
['admin' => 'N'],
))
->create();
However, is there some more dynamic way in case I have more skill combos and don't want to manually type out 50 arrays?
To do the simple combos I had to do this
Hero::factory(5)
->state(new Sequence(
[ 'skill_1' => 1, 'skill_2' => 2, 'skill_3' => 3, ],
[ 'skill_1' => 1, 'skill_2' => 2, 'skill_3' => 4, ],
[ 'skill_1' => 1, 'skill_2' => 2, 'skill_3' => 5, ],
[ 'skill_1' => 2, 'skill_2' => 3, 'skill_3' => 4, ],
[ 'skill_1' => 2, 'skill_2' => 3, 'skill_3' => 5, ],
[ 'skill_1' => 3, 'skill_2' => 4, 'skill_3' => 5, ],
))
->create([
'hero_class' => 'Warrior',
'attribute_health' => 100,
'attribute_attack' => 35,
'attribute_armor' => 75,
'attribute_speed' => 22,
'attribute_crit' => 15,
]);
Any insight on how to go about this is much appreciated ;)
What you could do, is first create some random, unique combinations of skills in an array:
$skills = [];
do {
$randomSkillSet = [
'skill_1' => rand(1, 5),
'skill_2' => rand(1, 5),
'skill_3' => rand(1, 5)
];
if (!in_array($randomSkillSet, $skills)) {
$skills[] = $randomSkillSet;
}
} while (count($skills) < 50);
// We make sure 50 is less than 5^3 = 125
Now you can use this array with unique skillsets in your Sequence, by taking each item from the $skills
array in a Sequence closure, like this:
use Illuminate\Database\Eloquent\Factories\Sequence;
Hero::factory(50)
->state(new Sequence(
function ($sequence) use ($skills) {
return $skills[$sequence->index];
}
))
->create([
'hero_class' => 'Warrior',
'attribute_health' => 100,
'attribute_attack' => 35,
'attribute_armor' => 75,
'attribute_speed' => 22,
'attribute_crit' => 15,
]);
This is possible because we can use the index property of the sequence instance that is injected into the closure.