У меня проблема: я не могу заставить свой сценарий работать со штрафами , но я заставил его работать с бонусами.
Запуск: двумерный массив пользователей, каждый из которых имеет идентификатор, имя, начальную позицию и модификатор (если модификатор <0 - его бонус; если модификатор> 0 - его штраф).
Как работают модификаторы: например, я есть очередь пользователей Test1, Test2, Test3. Если я дам пользователю Test3 бонус 1, он поменяется местами с пользователем Test 2, и окончательная очередь будет Test1, Test3, Test2. Если я дам ему 2, то он будет первым в очереди.
Наказания работают наоборот. Если я дам пользователю Test1 штраф 1, он будет вторым в очереди. Если я дам ему штраф 3, он будет перемещен в конец очереди.
Это мой рабочий код для бонусов:
<?
$new = array(); $orders = array();
$new[111]['position'] = 1; $new[111]['user'] = 'Test1'; $orders[1] = 111; $new[111]['shift'] = 0;
$new[222]['position'] = 2; $new[222]['user'] = 'Test2'; $orders[2] = 222; $new[222]['shift'] = 0;
$new[333]['position'] = 3; $new[333]['user'] = 'Test3'; $orders[3] = 333; $new[333]['shift'] = 0;
$new[444]['position'] = 4; $new[444]['user'] = 'Test4'; $orders[4] = 444; $new[444]['shift'] = 0;
$new[555]['position'] = 5; $new[555]['user'] = 'Test5'; $orders[5] = 555; $new[555]['shift'] = 0;
$new[666]['position'] = 6; $new[666]['user'] = 'Test6'; $orders[6] = 666; $new[666]['shift'] = 0;
$new[777]['position'] = 7; $new[777]['user'] = 'Test7'; $orders[7] = 777; $new[777]['shift'] = 0;
$new[888]['position'] = 8; $new[888]['user'] = 'Test8'; $orders[8] = 888; $new[888]['shift'] = 0;
//shift function
function bonus($start, $bonus)
{
global $new, $orders;
//for bonuses, shift to start, $bonus is negative number
if ($bonus < 0)
{
for ($i = $start; $i > ($start - abs($bonus)); $i--)
{
$order_id = intval($orders[$i]);
$prev = intval($orders[$i - 1]);
if ($prev != 0)
{
$temp = $new[$order_id]['position'];
$new[$order_id]['position'] = $new[$prev]['position'];
$new[$prev]['position'] = $temp;
$orders[$i] = $prev;
$orders[$i - 1] = $order_id;
}
}
}
//end for bonuses
}
// Now I set modificator (bonus negative, penalty positive)
$new[555]['shift'] = -2;
// sort by bonuses
$i = 1;
foreach($new as $value)
{
$order_id = $orders[$i];
bonus($new[$order_id]['position'], $new[$order_id]['shift']);
$i++;
}
// sort 2d array with field position
usort($new, function($a, $b){
return $a['position'] <=> $b['position'];
});
//DATA OUTPUT
$i = 1;
foreach($new as $value)
{
echo $i . '. ' . $value['user'] . ' ; shift: ' . $value['shift'];
echo '<br>';
$i++;
}
?>
На этот код я установил бонус с: $ new [555] ['shift'] = -2;
Таким образом, штраф будет таким: $ new [444] ['shift'] = 3;
Код для штрафов, я думаю должно быть что-то вроде этого:
//for penalty, shift to the end, $bonus positive number
if ($bonus > 0)
{
$total_new = count($new);
for ($i = $start; $i < ($start + $bonus); $i++)
{
$order_id = intval($orders[$i]);
$next = intval($orders[$i + 1]);
if ($next < $total_new)
{
$temp = $new[$order_id]['position'];
$new[$order_id]['position'] = $new[$next]['position'];
$new[$next]['position'] = $temp;
$orders[$i] = $next;
$orders[$i + 1] = $order_id;
}
}
}
//end code for penalty
Вот что-то не так с $ orders. Я пробовал много разных типов кода в течение всего дня, включая перечисление массива в порядке asc / des c, но это не сработало корректно ...
PS Я знаю о array_multisort, но мне не нужно Я должен поменять элементы друг с другом.
Опять же: бонус 2 означает, что пользователь должен поменяться местами с предыдущим номером 2 раза. Наказание 3 означает, что пользователь должен поменяться местами со следующим пользователем 3 раза.