Измени код, нужно чтобы было 100 билетов в базе, они отображались все на странице. И 2 билета с призом 50 грн, остальные проигрышные.

<?php
// Подключение к базе данных
$host = 'localhost';
$db = 'moll324_loto2';
$user = 'moll324_loto2';
$pass = '111111';
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_PERSISTENT         => false,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
    throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

// Функция для логирования
function log_message($message) {
    file_put_contents('generation_log.txt', date('Y-m-d H:i:s') . ': ' . $message . PHP_EOL, FILE_APPEND);
}

// Функция для генерации билетов
function generate_tickets($pdo) {
    log_message("Начало генерации билетов");

    // Общее количество билетов
    $total_tickets = 1000000;

    // Призы и их количество согласно таблице
    $prizes_distribution = [
        100000 => 3,
        5000   => 50,
        1000   => 500,
        500    => 2000,
        100    => 5000,
        50     => 15000,
        20     => 159553,
        10     => 70894,
        0      => $total_tickets - (3 + 50 + 500 + 2000 + 5000 + 15000 + 159553 + 70894)
    ];

    // Проверка общего количества билетов
    $total_sum = array_sum($prizes_distribution);
    if ($total_sum !== $total_tickets) {
        throw new Exception("Общее количество билетов не равно 1 миллиону: $total_sum");
    }

    // Генерируем серийные номера
    $serial_numbers = [];
    for ($i = 1; $i <= $total_tickets; $i++) {
        $serial_numbers[] = '001-' . str_pad($i, 8, '0', STR_PAD_LEFT);
    }

    // Проверка уникальности серийных номеров
    $unique_serial_numbers = array_unique($serial_numbers);
    if (count($unique_serial_numbers) !== $total_tickets) {
        throw new Exception("Обнаружены дубликаты серийных номеров");
    }

    // Создаем массив билетов с призами
    $tickets = [];
    foreach ($prizes_distribution as $prize => $count) {
        for ($i = 0; $i < $count; $i++) {
            $tickets[] = $prize;
        }
    }

    // Перемешиваем серийные номера и билеты
    shuffle($serial_numbers);
    shuffle($tickets);

    // Возможные суммы выигрышей в полях
    $possible_field_prizes = [10, 20, 50, 100, 500, 1000, 5000, 100000];

    // Подготавливаем пакетную вставку
    $stmt = $pdo->prepare("INSERT INTO tickets (serial_number, fields, prize) VALUES (?, ?, ?)");

    $batch = [];
    $batchSize = 1000;

    $pdo->beginTransaction();
    try {
        for ($i = 0; $i < $total_tickets; $i++) {
            $serial_number = $serial_numbers[$i];
            $prize = $tickets[$i];
            $fields = [];

            if ($prize > 0) {
                $field_prizes = generate_field_prizes($prize, $possible_field_prizes, 9);
                if (!$field_prizes) {
                    $field_prizes = [$prize];
                }
                foreach ($field_prizes as $field_prize) {
                    $fields[] = [
                        'symbol' => '$',
                        'amount' => $field_prize
                    ];
                }
                $non_winning_fields = 9 - count($fields);
                for ($j = 0; $j < $non_winning_fields; $j++) {
                    $number = rand(1, 9);
                    $fake_amount = $possible_field_prizes[array_rand($possible_field_prizes)];
                    $fields[] = [
                        'symbol' => $number,
                        'amount' => $fake_amount
                    ];
                }
            } else {
                for ($j = 0; $j < 9; $j++) {
                    $number = rand(1, 9);
                    $fake_amount = $possible_field_prizes[array_rand($possible_field_prizes)];
                    $fields[] = [
                        'symbol' => $number,
                        'amount' => $fake_amount
                    ];
                }
            }

            shuffle($fields);

            $batch[] = [
                $serial_number,
                json_encode($fields, JSON_UNESCAPED_UNICODE),
                $prize
            ];

            if (count($batch) === $batchSize) {
                foreach ($batch as $item) {
                    $stmt->execute($item);
                }
                $batch = [];
            }
        }

        // Вставка оставшихся билетов
        if (!empty($batch)) {
            foreach ($batch as $item) {
                $stmt->execute($item);
            }
        }

        $pdo->commit();
    } catch (Exception $e) {
        $pdo->rollBack();
        log_message("Ошибка при генерации билетов: " . $e->getMessage());
        throw $e;
    }

    log_message("Завершение генерации билетов");

    // Проверка после генерации
    $stmt = $pdo->query("SELECT COUNT(*) as count FROM tickets");
    $count = $stmt->fetch()['count'];
    if ($count !== $total_tickets) {
        throw new Exception("Количество билетов в базе данных ($count) не соответствует ожидаемому ($total_tickets)");
    }
}

// Функция для разбиения общей суммы приза на суммы полей
function generate_field_prizes($total_prize, $possible_field_prizes, $max_fields) {
    $result = [];
    $remaining_prize = $total_prize;
    rsort($possible_field_prizes);

    while ($remaining_prize > 0) {
        $possible_choices = array_filter($possible_field_prizes, function($prize) use ($remaining_prize) {
            return $prize <= $remaining_prize;
        });
        if (empty($possible_choices)) {
            return false;
        }
        $choice = $possible_choices[array_rand($possible_choices)];
        $result[] = $choice;
        $remaining_prize -= $choice;
        if (count($result) > $max_fields) {
            return false;
        }
    }

    if ($remaining_prize == 0 && count($result) <= $max_fields) {
        return $result;
    } else {
        return false;
    }
}

// Проверяем, есть ли билеты в базе, иначе генерируем их
$stmt = $pdo->query("SELECT COUNT(*) as count FROM tickets");
$count = $stmt->fetch()['count'];
if ($count < 1000000) {
    set_time_limit(0); // Снимаем ограничение по времени выполнения скрипта
    // Очищаем таблицу билетов перед генерацией
    $pdo->exec("TRUNCATE TABLE tickets");
    // Генерируем билеты
    generate_tickets($pdo);
}

// Обработка AJAX-запроса на покупку билета
if (isset($_POST['action']) && $_POST['action'] == 'buy_ticket') {
    $ticket_id = $_POST['ticket_id'];
    $stmt = $pdo->prepare("SELECT * FROM tickets WHERE id = ? AND is_bought = 0");
    $stmt->execute([$ticket_id]);
    $ticket = $stmt->fetch();
    if (!$ticket) {
        echo json_encode(['error' => 'Билет не найден или уже куплен.']);
        exit();
    }
    $stmt = $pdo->prepare("UPDATE tickets SET is_bought = 1 WHERE id = ?");
    $stmt->execute([$ticket_id]);
    $fields = json_decode($ticket['fields'], true);
    if (!is_array($fields)) {
        $fields = [];
    }

    // Получаем обновленную статистику
    $stmt = $pdo->query("SELECT COUNT(*) as remaining_prizes, SUM(prize) as remaining_amount FROM tickets WHERE is_bought = 0 AND prize > 0");
    $stats = $stmt->fetch();
    $stmt = $pdo->query("SELECT COUNT(*) as won_tickets, SUM(prize) as won_amount FROM tickets WHERE is_bought = 1 AND prize > 0");
    $won_stats = $stmt->fetch();
    $stmt = $pdo->query("SELECT COUNT(*) as total_remaining FROM tickets WHERE is_bought = 0");
    $total_remaining = $stmt->fetch()['total_remaining'];

    echo json_encode([
        'fields' => $fields,
        'serial_number' => $ticket['serial_number'],
        'prize' => $ticket['prize'],
        'stats' => [
            'total_remaining' => $total_remaining,
            'remaining_prizes' => $stats['remaining_prizes'],
            'remaining_amount' => $stats['remaining_amount'],
            'won_tickets' => $won_stats['won_tickets'],
            'won_amount' => $won_stats['won_amount']
        ]
    ]);
    exit();
}

// Получаем 20 случайных билетов, которые не были куплены
$stmt = $pdo->query("SELECT * FROM tickets WHERE is_bought = 0 ORDER BY RAND() LIMIT 20");
$tickets = $stmt->fetchAll();

// Получаем статистику
$stmt = $pdo->query("SELECT COUNT(*) as remaining_prizes, SUM(prize) as remaining_amount FROM tickets WHERE is_bought = 0 AND prize > 0");
$stats = $stmt->fetch();
$stmt = $pdo->query("SELECT COUNT(*) as won_tickets, SUM(prize) as won_amount FROM tickets WHERE is_bought = 1 AND prize > 0");
$won_stats = $stmt->fetch();
$stmt = $pdo->query("SELECT COUNT(*) as total_remaining FROM tickets WHERE is_bought = 0");
$total_remaining = $stmt->fetch()['total_remaining'];
?>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Щаслива Готівка</title>
    <style>
    /* Стили страницы */
    body {
        background-color: #e8f5e9;
        font-family: Arial, sans-serif;
    }
    h1 {
        text-align: center;
        color: #4cae4c;
    }
    .tickets {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
    }
    .ticket-card {
        width: 320px;
        margin: 10px;
        padding: 10px;
        background: #4cae4c;
        color: #fff;
        border-radius: 5px;
        text-align: center;
        position: relative;
    }
    .ticket-card button {
        margin-top: 10px;
        padding: 5px 10px;
        background: #fff;
        color: #4cae4c;
        border: none;
        border-radius: 3px;
        cursor: pointer;
    }
    .stats {
        margin: 20px;
        text-align: center;
    }
    /* Стили билета после покупки */
    .fields {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        margin: 20px 0;
    }
    .field {
        position: relative;
        width: 70px;
        height: 100px;
        background-color: #fff;
        border: 2px solid #4cae4c;
        border-radius: 5px;
        overflow: hidden;
        cursor: pointer;
        margin: 5px;
    }
    .field .content {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        color: #000;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    .field.scratched .overlay {
        display: none;
    }
    .overlay {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: #c0c0c0;
    }
    /* Стили для символов */
    .symbol {
        font-size: 24px;
        font-weight: bold;
    }
    .field.scratched .symbol.dollar {
        color: red;
        font-size: 32px;
    }
    .amount {
        font-size: 12px;
    }
    .scratch-all-btn {
        margin-top: 10px;
        padding: 5px 10px;
        background: #fff;
        color: #4cae4c;
        border: none;
        border-radius: 3px;
        cursor: pointer;
    }
    </style>
</head>
<body>
<h1>Лотерея "Щаслива Готівка"</h1>
<div class="stats">
    <p>Залишилось білетів всього: <?php echo $total_remaining; ?></p>
    <p>Залишилось виграшних білетів: <?php echo $stats['remaining_prizes']; ?></p>
    <p>Загальна сума виграшів, що залишилась: <?php echo $stats['remaining_amount'] ? $stats['remaining_amount'] : 0; ?> грн</p>
    <p>Вже виграно білетів: <?php echo $won_stats['won_tickets']; ?></p>
    <p>Сума вже виграних білетів: <?php echo $won_stats['won_amount'] ? $won_stats['won_amount'] : 0; ?> грн</p>
</div>
<div class="tickets">
    <?php foreach ($tickets as $ticket): ?>
    <div class="ticket-card" data-ticket-id="<?php echo $ticket['id']; ?>">
        <h2>Щасливі Гроші</h2>
        <p>Серія: <?php echo htmlspecialchars($ticket['serial_number']); ?></p>
                <button class="buy-button">Купити</button>
    </div>
    <?php endforeach; ?>
</div>
<form method="post">
    <button type="submit" name="refresh">Показати ще 20 білетів</button>
</form>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function(){
    $('.buy-button').click(function(){
        var ticketCard = $(this).closest('.ticket-card');
        var ticketId = ticketCard.data('ticket-id');
        $.ajax({
            type: 'POST',
            url: 'index.php',
            data: { action: 'buy_ticket', ticket_id: ticketId },
            success: function(response) {
                var data;
                try {
                    data = JSON.parse(response);
                } catch (e) {
                    alert('Сталася помилка при обробці відповіді сервера.');
                    return;
                }
                if (data.error) {
                    alert(data.error);
                    return;
                }
                if (!data.fields) {
                    alert('Не вдалося отримати дані білета.');
                    return;
                }
                
                // Обновляем статистику
                $('.stats p:nth-child(1)').text('Залишилось білетів всього: ' + data.stats.total_remaining);
                $('.stats p:nth-child(2)').text('Залишилось виграшних білетів: ' + data.stats.remaining_prizes);
                $('.stats p:nth-child(3)').text('Загальна сума виграшів, що залишилась: ' + (data.stats.remaining_amount || 0) + ' грн');
                $('.stats p:nth-child(4)').text('Вже виграно білетів: ' + data.stats.won_tickets);
                $('.stats p:nth-child(5)').text('Сума вже виграних білетів: ' + (data.stats.won_amount || 0) + ' грн');

                // Удаляем кнопку покупки
                ticketCard.find('.buy-button').remove();
                
                // Отображаем билет
                var fieldsHtml = '<div class="fields">';
                data.fields.forEach(function(field, index){
                    fieldsHtml += '<div class="field" data-index="'+index+'">';
                    fieldsHtml += '<div class="content">';
                    var symbol = field.symbol;
                    var symbolClass = '';
                    if (symbol === '$') {
                        symbolClass = 'dollar';
                        symbol = '&#36;'; // HTML код символа $
                    }
                    fieldsHtml += '<div class="symbol '+symbolClass+'">'+symbol+'</div>';
                    fieldsHtml += '<div class="amount">'+field.amount+' грн</div>';
                    fieldsHtml += '</div>';
                    fieldsHtml += '<div class="overlay"></div>';
                    fieldsHtml += '</div>';
                });
                fieldsHtml += '</div>';
                fieldsHtml += '<button class="scratch-all-btn">Стерти всі</button>';
                fieldsHtml += '<p>Ви виграли: '+data.prize+' грн</p>';
                ticketCard.append(fieldsHtml);
                
                // Добавляем обработчик для стирания полей
                ticketCard.find('.field').click(function(){
                    $(this).addClass('scratched');
                });
                
                // Обработчик для кнопки "Стерти всі"
                ticketCard.find('.scratch-all-btn').click(function(){
                    ticketCard.find('.field').addClass('scratched');
                });
            },
            error: function(xhr, status, error) {
                alert('Виникла помилка при покупці білета. Спробуйте ще раз.');
            }
        });
    });
});
</script>
</body>
</html>