Создайте «Секретный Санта» генератор с использованием MySQL и Stack Overflow

Я пытаюсь создать систему Secret Santa, используя страницу PHP и базу данных MySQL для хранения деталей, поэтому, если кто-то забудет о своем совпадении, он может запросить его повторно.

Шаг 1: Я создал генератор случайных чисел на основе количества людей в списке в базе данных.

Функция подсчета:

$maxSQL = "SELECT COUNT(id) as total FROM secretsanta";
$maxRS = mysqli_query($conn, $maxSQL);
$maxQuery = mysqli_fetch_array($maxRS);
$maxpersons = $maxQuery['total'];

Тогда генератор случайных чисел:

$assigned = rand(1,$maxpersons);

Шаг 2: Проверьте, совпадает ли случайное число с собственным идентификатором человека, и создайте новое число, если оно истинно.

do {
$assigned = rand(1,$maxpersons);
} while ($assigned==$id);

Шаг 3: Запишите парный идентификатор в запись базы данных лиц.

$assignSQL = "UPDATE secretsanta SET assigned = '".$assigned."' WHERE secretsanta.id = ".$id;
if (mysqli_query($conn, $assignSQL)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_error($conn);
}

Эта проблема: Теперь мне нужно убедиться, что другие люди не назначены этому человеку, иначе некоторые могут пропустить, а другие получат больше, чем другие.

Я попытался реализовать функцию, которая содержала запрос для проверки каждой записи, чтобы увидеть, существует ли уже этот номер, и надеялся добавить его в качестве условия для оператора while или do while?

if (!function_exists('checkRandom')){
function checkRandom($funcid){
$Check_SQL = "SELECT assigned FROM secretsanta ORDER BY id ASC";
$Check_RES = mysqli_query($conn, $Check_SQL);
if (Check_RES) {
while ($CheckArray = mysqli_fetch_array($Check_RES, MYSQLI_ASSOC)) {
$CheckAsgn = $CheckArray['assigned'];
if ($funcid==$CheckAsgn) {return true;}else{return false;}
}
}
}
}

Затем внедрите его в оператор do while:

do {
$assigned = rand(1,$maxpersons);
} while ($assigned==$id||checkRandom($assigned));

Пока не повезло … ПОМОГИТЕ! .. пожалуйста 🙂

Постскриптум Я знаю, что есть сайты, которые уже делают это, но я просто не доверяю им, чтобы они указывали мой и семейный адрес электронной почты, если я сам смогу создать свою личную версию.

0

Решение

Используя ваш метод, первые несколько назначений будут выполнены без проблем, но представьте себе последнюю неназначенную запись и сколько раз она будет пытаться использовать случайное число только для того, чтобы найти человека с таким идентификатором.

Я собираюсь дать вам другой подход к вашей проблеме: для каждого пользователя, которому вы хотите назначить Санта, создайте новый оператор SELECT с предложением WHERE, который позволяет вам выбирать только тех пользователей, которые еще не назначены.
проверьте мой код и посмотрите, поможет ли это вам. Я просто напечатал это и не проверял это, чтобы могли быть некоторые ошибки.

// load all unassigned users into an array
$unassignedUsers = [];
$query = "SELECT id, assigned FROM secretsanta WHERE assigned is NULL";
$res = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($res){
$unassignedUsers[] = $row;
}

if(count($unassignedUsers) == 1){
echo 'There is only 1 unassigned user. Therefore he cannot be matched';
} else {
// for loop for each user in DB that is not assigned yet
//for ($i = 1;$i <= count($unassignedUsers); $i++){
$i = 0;
foreach($unassignedUsers as $user)
// if its the second-to-last iterations of the for-loop, check for legality of the last one
if(count($unassignedUsers) - $i == 1){
$lastUserID = $unassignedUsers[count($unassignedUsers)-1]['id'];
$query = "SELECT id FROM secretsanta WHERE assigned is NULL AND id = ".$lastUserID;
$res = mysqli_query($conn, $query);
$rowcount = mysqli_num_rows($res);
if ($rowcount){
// last user is still unassigned
$query = "UPDATE secretsanta SET assigned = '".$lastUserID."' WHERE id = ".$user['id'];
if(mysqli_query($conn, $query)){
echo "Record with id ".$user['id']." updated successfully";
} else {
echo "Error updating record: ".mysqli_error($conn);
}
}
} else {
// select all unassigned users
$unassignedIDs = [];
$query = "SELECT id FROM secretsanta WHERE assigned is NULL AND id <> ".$user['id'];
$res = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($res){
$unassignedIDs[] = $row['id'];
}

// get a random id from $unassignedIDs
$randomIndex = rand(0, count($unassignedIDs)-1);
$randomID = $unassignedIDs[$randomIndex];

// assign $randomID to user
$query = "UPDATE secretsanta SET assigned = '".$randomID."' WHERE id = ".$user['id'];
if(mysqli_query($conn, $query)){
echo "Record with id ".$user['id']." updated successfully";
} else {
echo "Error updating record: ".mysqli_error($conn);
}
}
$i++;
}
}

Последнее редактирование: реорганизовал весь код, чтобы его можно было запускать несколько раз и назначать только новых пользователей, которые еще не назначены.

1

Другие решения

Шаг 1 зависит от наличия непрерывного набора идентификаторов для людей. Подумайте, что произойдет, если «3» покинет компанию, и она заменит их на 6 человек… 1,2,4,5,6 ($ maxpersons = 5)

«Теперь мне нужно проверить» — нет, вы все еще пытаетесь решить проблему, угадывая, а затем проверяя, сработала ли ваша догадка. Используйте алгоритм, который всегда будет возвращать правильный результат. Приведенный ниже метод требует добавления временного поля ‘sequence’ типа float.

mysqli_query($conn,"UPDATE secretsanta SET sequence=RAND()");
$first=false;
$prev=false;
$all=mysqli_query($conn, "SELECT * FROM secretsanta ORDER BY sequence, id");
while ($r=mysqli_fetch_assoc($all)) {
if (false===$first) {
$first=$r['id'];
} else {
save_pair($prev, $r['id']);
}
$prev=$r['id'];
}
save_pair($prev, $first);

(но с лучшей проверкой ошибок)

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector