I am working on a Laravel project. I will explain the problem and I would be grateful if you help me. I want to add a feature to the project. First I want to explain the entities of the project:
User
,Car
,CarClass
, Box
.
each Car
has a CarClass
. User
can buy a Box
and open it.
When the user opens the box he bought, he can win a car from a certain CarClass
by chance. for example:
Red box: street 45%, sport 30%, muscle 30%, hyper 0%
Yellow box: street 20%, sport 50%, muscle 10%, hyper 20%
User who buys the Red box has a 45% chance to win a car with street class car, 30% chance to win a car with sport class and so on... .
And we have different boxes with different percentages.
Should there be one method for unboxing? Should a special design pattern be used?
Whether it is a complete answer or a clue that can help me, I would be grateful.
CodePudding user response:
Interfaces:
Item
# getName()
Box:
# getItem()
Concrete:
YellowBox(Box)
getItem()
RedBox(Box)
getItem()
Street(Item)
getName()
Sport(Item)
getName()
Muscle(Item)
getName()
Hyper(Item)
getName()
Additionally, getting random item is weighted probability. In the example below, I've assumed that all the chances always add up to 100%. Laravel code:
interface Item
{
function getName(): string;
}
interface Box
{
function getItem(): Item;
}
class Street implements Item
{
public function getName(): string
{
return get_class($this);
}
}
class Sport implements Item
{
public function getName(): string
{
return get_class($this);
}
}
class Muscle implements Item
{
public function getName(): string
{
return get_class($this);
}
}
class Hyper implements Item
{
public function getName(): string
{
return get_class($this);
}
}
abstract class BaseBox implements Box
{
abstract protected function chances(): Collection;
public function getItem(): Item
{
$sum = 0;
$choice = random_int(0, 100);
return app(
$this->chances()
->map(function ($value, $item) use (&$sum) {
$sum = $value;
return $sum;
})
->reduce(function ($result, $value, $key) use ($choice) {
if (is_string($result)) {
return $result;
}
if ($choice <= $value) {
return $key;
}
return $result $value;
}, 0)
);
}
}
class RedBox extends BaseBox
{
public function chances(): Collection
{
return collect([
Street::class => 45,
Sport::class => 30,
Muscle::class => 30,
]);
}
}
class YellowBox extends BaseBox
{
public function chances(): Collection
{
return collect([
Street::class => 20,
Sport::class => 50,
Muscle::class => 10,
Hyper::class => 20,
]);
}
}