wladeg Posted July 9, 2018 Share Posted July 9, 2018 (edited) Its tarot website http://tarovartai.lt where u pick 3 tarot cards from 21card desk, cards cant repeat but they repeat sometimes, please help <div id="cards-list"> <?php $numbers = range(1, 21); shuffle($numbers); foreach ($numbers as $number) { ?> <div id="card" class="card<?php echo $number; ?>" name="<?php echo $number; ?>"></div> <?php } ?> </div> <div id="picked-cards"> <div id="picked-period"></div> <?php $cls = 0; $date = date('Y-m-d'); $query = mysqli_query($conn, "SELECT * FROM history WHERE USERID = '$loggedin' AND DATE = '$date'"); $count = mysqli_num_rows($query); if($count > 0) { while($row = mysqli_fetch_assoc($query)) { $cardID = $row['CARD']; $queryCard = mysqli_query($conn, "SELECT * FROM cards WHERE ID = '$cardID'"); $row2 = mysqli_fetch_assoc($queryCard); ?> <div id="picked-card-desc"> <table> <tr> <td id="forS" class="for"> <?php if($cls == 0){ echo "Veiksmas, situacija"; }elseif($cls == 1){ echo "Ko saugotis ir vengti"; }else{ echo "Rezultatas"; } ?> </td> </tr> <tr> <td class="img"><img src="/images/cards/<?php echo $row2['IMG']; ?>"></td> </tr> <tr> <td class="name"><?php echo $row2['NAME']; ?></td> </tr> <tr> <td class="desc"><div class="scroll"><?php echo $row2['TEXT']; ?></div></td> </tr> </table> </div> <?php $cls++; } } ?> </div> Edited July 9, 2018 by Barand Code tags added Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/ Share on other sites More sharing options...
Barand Posted July 9, 2018 Share Posted July 9, 2018 I see nothing in the code that selects 3 cards and nothing to ensure uniqueness. It just seem to display cards from the history table (and in a very inefficient manner) Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/#findComment-1559495 Share on other sites More sharing options...
wladeg Posted July 9, 2018 Author Share Posted July 9, 2018 Any quick fix ? Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/#findComment-1559496 Share on other sites More sharing options...
mac_gyver Posted July 9, 2018 Share Posted July 9, 2018 the fix is to define what you want, then write and test the code to do it. the history table appears to be where the card state is remembered? when a new game is started, i would insert 21 rows, with card ids 1-21, with the userid/date, into the history table, with a column that indicates if the card id is 'used' a 0 = not used, a 1 = used. to generate a set of three new cards, retrieve the card ids from the history table that have not been used. if the number of unused card ids is zero, the game is over. store the unused card ids into an array, shuffle them, and pick three ids. update the history rows to set the 'used' column to a 1 for the three ids that were picked and display the cards that correspond to the three ids. when retrieving the card information for the card ids, run one query that gets the data you want in the order that you want it (don't run SELECT queries inside of loops.) you should also not put 'dynamic' data values directly into the sql query statement. we don't know where the $loggedin value comes from, but if it could have come from user supplied data, it could be used to inject sql. you should use a prepared query when supplying potentially unsafe data to an sql query statement. Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/#findComment-1559497 Share on other sites More sharing options...
WebStyles Posted July 9, 2018 Share Posted July 9, 2018 You could use something like "Select * from `cards` order by rand() limit 21" to select 21 distinct cards from the database in a random order. It would make your code much simpler. Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/#findComment-1559498 Share on other sites More sharing options...
Barand Posted July 9, 2018 Share Posted July 9, 2018 Something like this will give you 3 random cards each day and prevent duplicates in the same week. Run once per day. INSERT INTO tarot_history (date, card_id) SELECT CURDATE() , c.card_id FROM tarot_card c LEFT JOIN tarot_history h ON c.card_id = h.card_id AND WEEK(date) = WEEK(CURDATE()) WHERE h.card_id IS NULL ORDER BY RAND() LIMIT 3; Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/#findComment-1559499 Share on other sites More sharing options...
Barand Posted July 10, 2018 Share Posted July 10, 2018 After which you need only a single query (not your while loops with two queries) to get today's cards SELECT * FROM tarot_history ORDER BY WEEK(date), card_id; +------------+---------+ | date | card_id | +------------+---------+ | 2018-06-07 | 1 | -- last week | 2018-06-07 | 5 | -- last week | 2018-06-07 | 9 | -- last week | 2018-07-09 | 1 | | 2018-07-08 | 2 | | 2018-07-08 | 6 | | 2018-07-09 | 8 | | 2018-07-10 | 10 | -- today | 2018-07-08 | 12 | | 2018-07-09 | 15 | | 2018-07-10 | 18 | -- today | 2018-07-10 | 19 | -- today +------------+---------+ SELECT cardname , cardtext , imagefile FROM tarot_history JOIN tarot_card USING (card_id) WHERE date = CURDATE(); +----------+----------------------------------------------------------+-------------+ | cardname | cardtext | imagefile | +----------+----------------------------------------------------------+-------------+ | card_10 | Suspendisse dapibus lorem pellentesque magna. | card_10.jpg | | card_18 | Aliquam at eros. Etiam at ligula et tellus ullamcorper. | card_18.jpg | | card_19 | Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus | card_19.jpg | +----------+----------------------------------------------------------+-------------+ Quote Link to comment https://forums.phpfreaks.com/topic/307474-need-random-and-unique-but-its-not/#findComment-1559505 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.